目录
configMap 描述信息
Ⅰ、使用目录创建
Ⅱ、使用文件创建
Ⅲ、使用字面值创建
Pod 中使用 ConfigMap
Ⅰ、使用 ConfigMap 来替代环境变量
Ⅱ、用 ConfigMap 设置命令行参数
Ⅲ、通过数据卷插件使用ConfigMap
Ⅳ、ConfigMap 的热更新
configmap是专门存储我们配置文件的存储方案
ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制等对象。
[root@master1 configmap]# vim dir/game.properties
[root@master1 configmap]# vim dir/ui.properties
[root@master1 configmap]#
[root@master1 configmap]#
[root@master1 configmap]# kubectl create configmap game-config --from-file=./dir/
configmap/game-config created
[root@master1 configmap]#
[root@master1 configmap]# kubectl get cm
NAME DATA AGE
game-config 2 16s
[root@master1 configmap]# cat dir/game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
[root@master1 configmap]#
[root@master1 configmap]# cat dir/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
[root@master1 configmap]#
—from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容。
只要指定为一个文件就可以从单个文件中创建 ConfigMap,跟上面的区别就是目录和文件的使用
[root@master1 configmap]# kubectl create configmap game-config-2 --from-file=./dir/game.properties
configmap/game-config-2 created
[root@master1 configmap]# kubectl get cm
NAME DATA AGE
game-config 2 3m12s
game-config-2 1 3s
—from-file 这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的。
使用文字值创建,利用 —from-literal 参数传递配置信息,该参数可以使用多次,格式如下:
[root@master1 configmap]# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
configmap/special-config created
[root@master1 configmap]#
[root@master1 configmap]# kubectl get cm
NAME DATA AGE
game-config 2 9m22s
game-config-2 1 6m13s
special-config 2 5s
[root@master1 configmap]# kubectl describe cm special-config
Name: special-config
Namespace: default
Labels:
Annotations:
Data
====
special.how:
----
very
special.type:
----
charm
Events:
[root@master1 configmap]#
分析:special-config表示指定的名字;后面的--from-literal表示指定的键名=值。
既然上面已经分析了三种创建方式,下面的就是一些使用案例
测试的cm是一个special-config,这之前创建好了,一个env-config
special-config这个cm是之前创建好的,这里补充它的对于的yaml文件如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: charm
下面创建env.yaml
[root@master1 env]# cat env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
[root@master1 env]#
[root@master1 env]# kubectl create -f env.yaml
configmap/env-config created
[root@master1 env]#
[root@master1 env]# kubectl get cm
NAME DATA AGE
env-config 1 5s
game-config 2 16m
game-config-2 1 12m
special-config 2 6m50s
上面的两个是我们创建的拥有不同的键值对的ConfigMap,给我们下面创建的pod进行匹配
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: hub.atguigu.com/library/myapp:v1
command: [ "/bin/sh", "-c", "env" ] #打印出我们的坏境变量env
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
[root@master1 configmap]# kubectl create -f pod.yaml
pod/dapi-test-pod created
[root@master1 configmap]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "env" ] #打印出我们的坏境变量env
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how #导入的是special-config里面的special.how的值(very),即此时把这个值赋给SPECIAL_LEVEL_KEY
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.type
envFrom: #这个就表示我们上面创建的env-config就被导入了
- configMapRef:
name: env-config #匹配上哪个ConfigMap根据这个
restartPolicy: Never
会有三个不同的环境变量,第一个是env-config,它的键值对是log_level: INFO
第二个它的键名是SPECIAL_LEVEL_KEY,键值是very
第三个它的键名是SPECIAL_TYPE_KEY,键值是charm
总结:上面的就是两种不同的方式,一种通过env字段,一种通过envFrom,把我们的环境变量注入到我们的pod内部。
总结:上面的就是通过我们的ConifigMap把我们的一个坏境变量注入到我们的pod内部。
其实这个跟上面的测试大同小异,上面是打印出整个pod 的env环境信息,这里我们只是打印自己想要的那个环境信息
测试的cm是我们的special-config
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: charm
测试的pod的yaml文件如下
[root@master1 configmap]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox
command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] #运行的命令是打印出这两个值
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.type
restartPolicy: Never
[root@master1 configmap]#
[root@master1 configmap]# kubectl create -f pod1.yaml
pod/dapi-test-pod created
[root@master1 configmap]#
[root@master1 configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 58s
[root@master1 configmap]# kubectl logs dapi-test-pod
very charm
[root@master1 configmap]#
cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: charm
在数据卷里面使用这个 ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容。。。
[root@master1 configmap]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: busybox:alpine
command: [ "/bin/sh", "-c", "sleep 600s" ]
volumeMounts: #在当前容器内进行数据卷为config-volume的挂载
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap: #这个config-volume从名字为special-config的导入来的
name: special-config
restartPolicy: Never
[root@master1 configmap]#
[root@master1 configmap]# kubectl create -f pod2.yaml
pod/dapi-test-pod created
[root@master1 configmap]#
[root@master1 configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
dapi-test-pod 1/1 Running 0 3s
[root@master1 configmap]# kubectl exec -it dapi-test-pod sh
/ # cd /etc/config
/etc/config # ls
special.how special.type
/etc/config # cat special.how
very/etc/config #
/etc/config # cat special.type
charm/etc/config #
[root@master1 configmap]# cat pod3.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: log-config
namespace: default
data:
log_level: INFO
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: log-config
[root@master1 configmap]#
[root@master1 configmap]# kubectl create -f pod3.yaml
configmap/log-config created
deployment.extensions/my-nginx created
[root@master1 configmap]#
[root@master1 configmap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-6c59667984-b7htz 1/1 Running 0 36s
分析:上面是创建一个Deployment去调用ConfigMap,调用的方式是以volumes的方式挂载进来的挂载的是log-config,挂载的目录是/etc/config 的目录中。。也就意味我们去my-nginx容器中,在/etc/config的目录下会有一个log_level的文件名,它的内容应该是INFO。
[root@master1 configmap]# kubectl exec `kubectl get pods -l run=my-nginx -o=name|cut -d "/" -f2` cat /etc/config/log_level
INFO[root@master1 configmap]#
修改 ConfigMap
kubectl edit configmap log-config
修改 log_level 的值为 DEBUG 等待大概 10 秒钟时间,再次查看环境变量的值,发现已经更改至DEBUG了,如果对于我们nginx的应用十分友好,可以达到这样热更新状态。
[root@master1 configmap]# kubectl edit configmaps log-config
configmap/log-config edited
[root@master1 configmap]#
[root@master1 configmap]# kubectl exec `kubectl get pods -l run=my-nginx -o=name|cut -d "/" -f2` cat /etc/config/log_level
INFO[root@master1 configmap]#
[root@master1 configmap]# kubectl exec `kubectl get pods -l run=my-nginx -o=name|cut -d "/" -f2` cat /etc/config/log_level
DEBUG[root@master1 configmap]#
注意:configmap如果以env的方式挂载至容器,修改configmap不会实现热更新。
ConfigMap 更新后滚动更新 Pod
更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,即我们的pod不会更新,也就是pod不会死亡并启动,即pod的名字不会变,我们可以通过修改 pod annotations 的方式强制触发滚动更新。
kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations":{"version/config": "20190411" }}}}}'
!!! 更新 ConfigMap 后: 使用该 ConfigMap 挂载的 Env 不会同步更新 使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新
总结:上面的所有就是如何通过ConfigMap去保存我们的一些配置文件以及一些数据。那这些数据可以通过我们被导入pod内部成为环境变量或者是所谓的文件,从而达到我们的这种热更新的目的。但是这些文件是以明文的方式去保存的,如果有一些密码文件,通过ConfigMap就不适合了。