ConfigMap/Secret:配置、定制我的应用
Kubernetes里专门用来管理配置信息有两种对象:ConfigMap和Secret
ConfigMap/Secret
配置信息从数据安全角度,可以分为两类:
- 明文配置,不保密,可以任意查询修改,如服务端口、运行参数、文件路径等
- 机密配置,涉及敏感信息需要保密,不能随便查看,如密码、密钥、证书等。
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
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
可以发现,Secret对象是无法直接看到内容的,只能看到数据的大小。
如何使用ConfigMap和Secret对象
两种方式将ConfigMap和Secret注入到Pod:环境变量和加载文件
环境变量方式使用ConfigMap/Secret
描述容器的环境变量,可以使用containers中的env字段,env中可以使用value来指定值,也可以使用valueFrom来从ConfigMap 或者 Secret 对象里获取值。
这样就实现了把配置信息以环境变量的形式注入进 Pod,也就是配置与应用的解耦。
查看valueFrom的定义
kubectl explain pod.spec.containers.env.valueFrom
示例
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中的组合关系
创建并查看
kubectl apply -f env-pod.yml
kubectl exec -it env-pod -- sh
echo $COUNT
echo $GREETING
echo $USERNAME $PASSWORD
以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。
总结
- ConfigMap 记录了一些 Key-Value 格式的字符串数据,描述字段是“data”,不是“spec”。
- Secret 与 ConfigMap 很类似,也使用“data”保存字符串数据,但它要求数据必须是 Base64 编码,起到一定的保密效果。
- 在 Pod 的“env.valueFrom”字段中可以引用 ConfigMap 和 Secret,把它们变成应用可以访问的环境变量。
- 在 Pod 的“spec.volumes”字段中可以引用 ConfigMap 和 Secret,把它们变成存储卷,然后在“spec.containers.volumeMounts”字段中加载成文件的形式。
- ConfigMap 和 Secret 对存储数据的大小没有限制,但小数据用环境变量比较适合,大数据应该用存储卷,可根据具体场景灵活应用。
思考
当修改ConfigMap的YAML,并使用kubectl apply更新对象,本文中env-pod和vol-pod,是否会自动更新配置?
答:经过试验后发现,env-pod采用环境变量方式,初始化容器时是一次性拷贝的,不会更新配置;vol-pod采用Volume方式,会自动更新配置。
《极客时间-Kubernetes入门实战课》学习笔记 Day14