ASP.NET Core on K8S深入学习(9)Secret & Configmap

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 本文探索了在K8S中如何进行配置管理,如果需要密文配置,可以使用Secret,如果是一般应用配置,可以使用ConfigMap。虽然Secret和ConfigMap都定义了好几种定义方式,但是我们一般采用YAML配置创建和Volume方式读取,因为Volume方式可以支持动态更新。

一、Secret

1.1 关于Secret

  在应用启动过程中需要一些敏感信息,比如数据库用户名、密码,如果直接明文存储在容器镜像中是不安全的,K8S提供的方案是Secret

  Secret 会以密文的方式存储数据,避免了直接在配置文件中保存敏感信息。

  Secret 会以 Volume 的形式被 mount 到 Pod,容器可通过文件的方式使用 Secret 中的敏感数据,也可以使用环境变量的方式使用。

1.2 创建与查看Secret

  这里假设我们要创建一个包含以下信息的Secret:

  (1)用户名:Edison

  (2)密码:EDC123456*

  有4种方法来创建Secret:

  (1)通过 --from-literal:

kubectl create secret generic mysecret --from-literal=username=Edison --from-literal=password=EDC123456*

PS:每个 --from-literal 对应一个信息条目

  (2)通过 --from-file:

echo -n Edison > ./username
echo -n EDC123456* > ./password
kubectl create secret generic mysecret --from-file=./username --from-file=./password

PS:每个文件内容对应一个信息条目

  (3)通过 --from-env-file:

cat << EOF > env.txt
username=Edison
password=EDC123456*
EOF
kubectl create secret generic mysecret --from-env-file=env.txt

  PS:文件 env.txt 中每行 Key=Value 对应一个信息条目

  (4)通过YAML配置文件创建:(推荐方式

  由于配置文件中的敏感数据必须是通过base64编码后的结果,因此需要获取base64编码后的值:

  下面就是这个YAML文件的内容:

apiVersion: v1
kind: Secret
metadata:
  name: edc-secret
data:
  username: RWRpc29u
  password: RURDMTIzNDU2Kg==

  通过kubectl apply来创建Secret:

   创建成功后,验证一下,查看一下这个Secret:

kubectl get secret edc-secret      // 查看存在的secret
kubectl describe secret edc-secret  // 查看条目的Key
kubectl edit secret edc-secret     // 查看条目的Value

   将Value进行base64反编码,如下所示,与预期一致:

1.3 在Pod中使用Secret

  K8S中Pod中使用Secret有两种方式,一是Volume方式,二是环境变量的方式。

  (1)Volume方式

  这里我们以一个示例演示一下如何通过Volume方式使用Secret,首先定义一个Pod:

apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
  - name: secret-demo-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: edc-secret

  该Pod中会使用到刚刚定义的secret(edc-secret),然后volumeMounts定义了将foo mount到容器中的路径为/etc/foo的目录下,并且指定了读写权限为只读。

  通过kubectl apply创建之后,我们试着在容器中读取secret来验证一下,如下图所示:

  可以看到,K8S为每条敏感数据创建了一个文件,而且其Value是以明文存放的。

  当然,你也可以自定义存放数据的目录,如下配置所示:

apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
  - name: secret-demo-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: edc-secret
      items:
      - key: username
        path: /edc-group/username
      - key: password
        path: /edc-group/password

  这时,该secret就会存放于/etc/foo/edc-group/username 和 /etc/foo/edc-group/password 两个目录下了。

  (2)动态更新

  以Volume方式使用Secret,其中一个优点就是支持动态更新。例如,我们将Secret更新一下,重新应用到K8S中:

apiVersion: v1
kind: Secret
metadata:
  name: edc-secret
data:
  username: RWRpc29u
  password: YWJjZGVmZyo=    // 换为了 abcdefg*

  通过kubectl apply重新应用之后,等待一段时间后,再次进入容器中验证:

   已经改为了 abcdefg*,符合预期。

  (2)环境变量方式

  通过Volume使用Secret看起来稍微麻烦了一点,容器必须通过文件读取数据。K8S提供了另外一种方式,那就是环境变量方式。

  下面仍以上面的例子为例,修改配置文件:

apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
  - name: secret-demo-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    env:
      - name: EDC_SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: edc-secret
            key: username
      - name: EDC_SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: edc-secret
            key: password

  通过kubectl apply应用之后,进入容器验证一下:

   可以看到,可以方便地通过环境变量获取到Value。

_PS:_需要注意的也是,虽然通过环境变量读取Secret比较方便,但是无法支持Secret动态更新!

二、Configmap

2.1 关于Configmap

  上面提到的Secret可以为Pod提供机密数据的存储,而对于一些非机密敏感的数据,像一些应用的配置信息啊神马的,则可以使用Configmap。

  Configmap的创建与使用方式与Secret非常类似,不同点只在于数据以明文形式存放(不过,我觉得Secret的密文形式也并不密文,只能算得上是简单编码)。

2.2 创建Configmap

  和Secret一样,可以通过 --from-literal,--from-file 和 --from-env-file来创建,这里我们跳过,直接说下我们最常用的yaml配置文件的方式。

apiVersion: v1
kind: ConfigMap
metadata:
  name: service-configmap
data:
  LogLevel: Error
  LogFile: service-timestamp.log
  AllowedHosts: edc.com

2.3 使用Configmap

  和Secret一样,也可以通过Volume 或 环境变量两种方式来使用Configmap。

  (1)Volume方式

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo
spec:
  containers:
  - name: configmap-demo-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    configMap:
      name: service-configmap

  (2)环境变量方式

apiVersion: v1
kind: Pod
metadata:
  name: secret-demo
spec:
  containers:
  - name: secret-demo-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    env:
      - name: SERVICE_LOG_LEVEL
        valueFrom:
          configMapKeyRef:
            name: service-configmap
            key: LogLevel
      - name: SERVICE_LOG_FILE
        valueFrom:
          configMapKeyRef:
            name: service-configmap
            key: LogFile
      - name: SERVICE_ALLOWED_HOSTS
        valueFrom:
          configMapKeyRef:
            name: service-configmap
            key: AllowedHosts

2.4 最佳实践

  大多数情况下,大家建议的最佳实践是:

  (1)创建ConfigMap采用YAML配置方式 => 便于复用和版本管理

  (2)读取ConfigMap采用Volume方式 => 便于配置动态更新

  下面我们创建一个Configmap,其YAML内容如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: service-configmap
data:
  appsettings.json: |
    LogHandler: NLogHandler
    LogLevel: Error
    LogFile: %hostname-%timestamp.log

  这里注意别忘了:后面的 | 符号,然后创建&查看Configmap:

   如果想要在Pod中使用此Configmap,可以在YAML配置如下:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo
spec:
  containers:
  - name: configmap-demo-pod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    volumeMounts:
    - name: configmap
      mountPath: "/etc/configmap"
  volumes:
  - name: configmap
    configMap:
      name: service-configmap
      items:
        - key: appsettings.json
          path: appsettings.json

  这里将Volume mount到了容器的 /etc/configmap 目录中,下面我们验证一下:

  这时我们将configmap更新一下,如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: service-configmap
data:
  appsettings.json: |
    Logging:
      LogLevel:
        Default: "Error"
    AllowedHosts: "*"

  通过kubectl apply更新一下configmap,然后再到pod中验证是否动态更新:

   可以看出,已经动态更新,符合预期!

2.5 ASP.NET Core appSettings

  我们在ASP.NET Core中的配置都是写在appSettings.json文件中,如何将appSettings.json转换为ConfigMap呢?圣杰已经总结归纳为了《.NET Core使用K8S Configmap的正确姿势》一文,有兴趣的读者可以参考此文。

三、小结

  本文探索了在K8S中如何进行配置管理,如果需要密文配置,可以使用Secret,如果是一般应用配置,可以使用ConfigMap。虽然Secret和ConfigMap都定义了好几种定义方式,但是我们一般采用YAML配置创建和Volume方式读取,因为Volume方式可以支持动态更新。最后,通过分享圣杰的一篇文章,介绍了如何在ASP.NET Core下使用Configmap的方式,希望对你有帮助!

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
4天前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
4天前
|
Kubernetes 监控 测试技术
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
|
4天前
|
Kubernetes API 调度
k8s学习--pod的所有状态详解(图例展示)
k8s学习--pod的所有状态详解(图例展示)
|
2天前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
4天前
|
Kubernetes 固态存储 调度
k8s学习--如何控制pod调度的位置
k8s学习--如何控制pod调度的位置
|
4天前
|
存储 Kubernetes 调度
k8s学习--k8s群集部署zookeeper应用及详细解释
k8s学习--k8s群集部署zookeeper应用及详细解释
|
存储 Kubernetes Shell
Kubernetes里的secret最基本的用法
Kubernetes里的secret最基本的用法
224 0
Kubernetes里的secret最基本的用法
|
存储 Kubernetes 数据安全/隐私保护
|
5天前
|
Kubernetes Cloud Native 云计算
云原生之旅:Kubernetes 集群的搭建与实践
【8月更文挑战第67天】在云原生技术日益成为IT行业焦点的今天,掌握Kubernetes已成为每个软件工程师必备的技能。本文将通过浅显易懂的语言和实际代码示例,引导你从零开始搭建一个Kubernetes集群,并探索其核心概念。无论你是初学者还是希望巩固知识的开发者,这篇文章都将为你打开一扇通往云原生世界的大门。
55 17
|
2天前
|
Kubernetes Cloud Native 微服务
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
15 1