ConfigMap/Secret:配置、定制我的应用

439 阅读3分钟

ConfigMap/Secret:配置、定制我的应用

Kubernetes里专门用来管理配置信息有两种对象:ConfigMap和Secret

ConfigMap/Secret

配置信息从数据安全角度,可以分为两类:

  1. 明文配置,不保密,可以任意查询修改,如服务端口、运行参数、文件路径等
  2. 机密配置,涉及敏感信息需要保密,不能随便查看,如密码、密钥、证书等。

ConfigMap用来保存明文配置,Secret用来保存机密配置。

ConfigMap

创建ConfigMap的YAML模板

export out="--dry-run=client -o yaml"        # 定义Shell变量
kubectl create cm info $out

得到的样本文件是这样的:

apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: info

可以发现没有spec字段,这是因为ConfigMap 存储的是配置数据,是静态的字符串,并不是容器,所以它们就不需要用“spec”字段来说明运行时的“规格”。

生成带有data字段的YAML模板

kubectl create cm info --from-literal=k=v $out

注意,因为在 ConfigMap 里的数据都是 Key-Value 结构,所以 --from-literal 参数需要使用 k=v 的形式

将YAML模板文件修改一下,多添加一些key-value:

apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: null
  name: info
data:
  count: '10'
  debug: 'on'
  path: '/etc/systemd'
  greeting: |
    say hello to kubernetes.

创建ConfigMap并查看

创建cm

kubectl apply -f cm.yml

查看cm

kubectl get cm
kubectl describe cm info

image.png

ConfigMap中的Key-Value信息被存入etcd数据库,后续可以被其他api对象使用。

Secret

Secret对象和ConfigMap的结构和用法很类似,Kubernetes中Secret对象细分很多类,比如:

  • 访问私有镜像仓库的认证信息
  • 身份识别的凭证信息
  • HTTPS 通信的证书和私钥
  • 一般的机密信息(格式由用户自行解释)

这里介绍最后一种

创建一般Secret的YAML模板

kubectl create secret generic user --from-literal=name=root $out

得到的Secret对象:

apiVersion: v1
data:
  name: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: null
  name: user

这里的name看起来像是乱码,其实只是做了base64编码,算不上真正的加密。

base64编码

echo -n "123456" | base64
MTIzNDU2

这条命令里的 echo ,必须要加参数 -n 去掉字符串里隐含的换行符,否则 Base64 编码出来的字符串就是错误

编辑secret.yml

apiVersion: v1
kind: Secret
metadata:
  name: user

data:
  name: cm9vdA==  # root
  pwd: MTIzNDU2   # 123456
  db: bXlzcWw=    # mysql

创建Secret并查看

kubectl apply  -f secret.yml
kubectl get secret
kubectl describe secret user

image.png

可以发现,Secret对象是无法直接看到内容的,只能看到数据的大小。

如何使用ConfigMap和Secret对象

两种方式将ConfigMap和Secret注入到Pod:环境变量和加载文件

环境变量方式使用ConfigMap/Secret

描述容器的环境变量,可以使用containers中的env字段,env中可以使用value来指定值,也可以使用valueFrom来从ConfigMap 或者 Secret 对象里获取值。

这样就实现了把配置信息以环境变量的形式注入进 Pod,也就是配置与应用的解耦。

查看valueFrom的定义

kubectl explain pod.spec.containers.env.valueFrom

image.png

示例

apiVersion: v1
kind: Pod
metadata:
  name: env-pod

spec:
  containers:
  - env:
      - name: COUNT
        valueFrom:
          configMapKeyRef:
            name: info
            key: count
      - name: GREETING
        valueFrom:
          configMapKeyRef:
            name: info
            key: greeting
      - name: USERNAME
        valueFrom:
          secretKeyRef:
            name: user
            key: name
      - name: PASSWORD
        valueFrom:
          secretKeyRef:
            name: user
            key: pwd

    image: busybox
    name: busy
    imagePullPolicy: IfNotPresent
    command: ["/bin/sleep", "300"]

解释:

Pod的名字是env-pod,镜像是busybox,执行的命令是睡眠300s。这段时间 可以使用kubectl exec进入Pod观察环境变量。

在Pod中的组合关系

image.png

创建并查看

kubectl apply -f env-pod.yml
kubectl exec -it env-pod -- sh

echo $COUNT
echo $GREETING
echo $USERNAME $PASSWORD

image.png

以Volume方式使用ConfigMap/Secret

Kubernetes 为 Pod 定义了一个“Volume”的概念,可以翻译成是“存储卷”。如果把 Pod 理解成是一个虚拟机,那么 Volume 就相当于是虚拟机里的磁盘.

Pod可以挂载(mount)多个Volume,挂载Volume很简单,只需要在spec里增加一个volumes字段,然后再定义卷的名字和引用即可。

定义volume

spec:
  volumes:
  - name: cm-vol
    configMap:
      name: info
  - name: sec-vol
    secret:
      secretName: user

挂载volume

在containers下挂载之前定义的volume

containers:
- volumeMounts:
  - mountPath: /tmp/cm-items
    name: cm-vol
  - mountPath: /tmp/sec-items
    name: sec-vol

在Pod中的组合关系

完整的示例

apiVersion: v1
kind: Pod
metadata:
  name: vol-pod

spec:
  volumes:
  - name: cm-vol
    configMap:
      name: info
  - name: sec-vol
    secret:
      secretName: user

  containers:
  - volumeMounts:
    - mountPath: /tmp/cm-items
      name: cm-vol
    - mountPath: /tmp/sec-items
      name: sec-vol

    image: busybox
    name: busy
    imagePullPolicy: IfNotPresent
    command: ["/bin/sleep", "300"]

创建并查看

kubectl apply -f vol-pod.yml
kubectl get pod
kubectl exec -it vol-pod -- sh

采用Volume方式挂载,ConfigMap和Secret都变成了目录,而具体的key-value则变成了一个个的文件,文件名就是key。

总结

  1. ConfigMap 记录了一些 Key-Value 格式的字符串数据,描述字段是“data”,不是“spec”。
  2. Secret 与 ConfigMap 很类似,也使用“data”保存字符串数据,但它要求数据必须是 Base64 编码,起到一定的保密效果。
  3. 在 Pod 的“env.valueFrom”字段中可以引用 ConfigMap 和 Secret,把它们变成应用可以访问的环境变量。
  4. 在 Pod 的“spec.volumes”字段中可以引用 ConfigMap 和 Secret,把它们变成存储卷,然后在“spec.containers.volumeMounts”字段中加载成文件的形式。
  5. ConfigMap 和 Secret 对存储数据的大小没有限制,但小数据用环境变量比较适合,大数据应该用存储卷,可根据具体场景灵活应用。

思考

当修改ConfigMap的YAML,并使用kubectl apply更新对象,本文中env-pod和vol-pod,是否会自动更新配置?

答:经过试验后发现,env-pod采用环境变量方式,初始化容器时是一次性拷贝的,不会更新配置;vol-pod采用Volume方式,会自动更新配置。

《极客时间-Kubernetes入门实战课》学习笔记 Day14 极客课程分享