在一般应用部署中,都是将程序和配置信息分离,这样可以保证程序可以被各个环境复用。
在容器场景中,将应用打包成镜像后,可以通过环境变量或者文件挂载的方式,在创建容器时把配置注入进去。
在Kubernetes场景中,则使用configMap实现应用与配置分离。使用configMap的方式有多种,有的方式修改了configMap的配置,无需重启Pod即可生效,有的方式需要重启Pod才生效。看看你用的是哪一种吧。
使用configMap做程序和配置分离,那么首先就要定义configMap,然后部署configMap。
apiVersion: v1kind: ConfigMapmetadata: name: democm namespace: demodata: db_name: demodb db_host: 172.19.132.23
configMap有3种使用方式:env方式 、envFrom方式 、volumes方式。
这种方式是将configMap的key-value注入到容器的环境变量里,程序里使用时,使用env里定义的name即可获取到对应的值。使用方式如下:
apiVersion: v1kind: Podmetadata: name: pod-cm-1 namespace: demo labels: app: pod-cm-1spec: containers: - name: pod-cm-1 image: busybox imagePullPolicy: IfNotPresent tty: true # 会出现在容器的环境变量里,程序里要使用env#name可以获取到对应的值 env: - name: db_name_app valueFrom: configMapKeyRef: name: democm key: db_name - name: db_host_app valueFrom: configMapKeyRef: name: democm key: db_host
这种方式也是将configMap的key-value注入到容器的环境变量里,使用方法与env方式类似,只不过在程序使用时,是直接使用configMap定义的key,即可获取到对应的值。使用方式如下:
apiVersion: v1kind: Podmetadata: name: pod-cm-2 namespace: demo labels: app: pod-cm-2spec: containers: - name: pod-cm-2 image: busybox imagePullPolicy: IfNotPresent tty: true # 程序里使用configmap的key envFrom: - configMapRef: name: democm
这种方式是以卷挂载的方式,将configMap的key-value写入到文件里,key是文件名,value是文件内容。
使用方式如下:
apiVersion: v1kind: Podmetadata: name: pod-cm-3 namespace: demo labels: app: pod-cm-3spec: nodeName: k8s-worker-2 containers: - name: pod-cm-3 image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 hostPort: 8080 volumeMounts: - name: workdir mountPath: /usr/share/nginx/html volumes: - name: workdir configMap: name: democm optional: true
观察volume卷下面的内容:
进入到容器的/usr/share/nginx/html目录下,可以看到configMap定义的key-value会出现此目录下,并且会有一个类似时间的文件。进入到文件夹里,可以看到对应的db_host和db_name文件。
如果configMap变化之后,对应的会生成新的文件:
编排部署configMap,查看部署后的configMap信息:
[root@k8s-master configmap]# kubectl apply -f configmap.yamlconfigmap/democm created[root@k8s-master configmap]# kubectl get cm -n demoNAME DATA AGEdemocm 2 11s[root@k8s-master configmap]# kubectl describe cm democm -n demoName: democmNamespace: demoLabels: <none>Annotations: <none>Data====db_host:----172.19.132.23db_name:----demodbEvents: <none>
从这里可以看到env方式定义的yaml里的env已经被放入到容器的环境变量里的,只不过env里的值是从configMap里取的。
[root@k8s-master configmap]# kubectl exec -it pod-cm-1 -n demo -- /bin/sh/ #/ # evn/bin/sh: evn: not found/ # envKUBERNETES_PORT=tcp://10.96.0.1:443KUBERNETES_SERVICE_PORT=443HOSTNAME=pod-cm-1SHLVL=1HOME=/rootTERM=xtermKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binKUBERNETES_PORT_443_TCP_PORT=443KUBERNETES_PORT_443_TCP_PROTO=tcpdb_host_app=172.19.132.23KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443KUBERNETES_SERVICE_PORT_HTTPS=443KUBERNETES_SERVICE_HOST=10.96.0.1PWD=/db_name_app=demodb
从这里可以看到envFrom方式是直接把configMap的key-value放入到容器的环境变量里的。
[root@k8s-master configmap]# kubectl apply -f pod_configmap_2.yamlpod/pod-cm-2 created[root@k8s-master configmap]# kubectl exec -it pod-cm-2 -n demo -- /bin/sh/ #/ # envKUBERNETES_SERVICE_PORT=443KUBERNETES_PORT=tcp://10.96.0.1:443HOSTNAME=pod-cm-2SHLVL=1HOME=/rootdb_name=demodbTERM=xtermKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binKUBERNETES_PORT_443_TCP_PORT=443KUBERNETES_PORT_443_TCP_PROTO=tcpKUBERNETES_SERVICE_PORT_HTTPS=443KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443KUBERNETES_SERVICE_HOST=10.96.0.1PWD=/db_host=172.19.132.23
这种方式可以看到,volumes方式并没有把configMap的值放入到环境变量。
[root@k8s-master configmap]# kubectl apply -f pod_configmap_3.yamlpod/pod-cm-3 created[root@k8s-master configmap]# kubectl exec -it pod-cm-3 -n demo -- /bin/sh# envKUBERNETES_SERVICE_PORT=443KUBERNETES_PORT=tcp://10.96.0.1:443HOSTNAME=pod-cm-3HOME=/rootPKG_RELEASE=1~bookwormTERM=xtermKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1NGINX_VERSION=1.25.2PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binKUBERNETES_PORT_443_TCP_PORT=443NJS_VERSION=0.8.0KUBERNETES_PORT_443_TCP_PROTO=tcpKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443KUBERNETES_SERVICE_PORT_HTTPS=443KUBERNETES_SERVICE_HOST=10.96.0.1PWD=/
但是可以看到configMap的key-value被写入到了文件里。
# cd /usr/share/nginx/html# lsdb_host db_name# cat db_host172.19.132.23# cat db_namedemodb
修改configMap值,然后重新部署configMap,继续观察这3种方式。
用命令kubectl exec -it pod-cm-xxxxxx -n demo -- /bin/sh进入到容器后,可以观察到:
本文总结了configMap使用的3种方式:env方式、envFrom方式、volumes方式。
env方式和envFrom方式方式说白了是往容器里注入了环境变量,在容器启动的时候,就已经注入了,无法修改。每次修改configMap的key-value,需要重启Pod才能生效。
volumes方式的方式,实际上把configMap的key-value写入到了容器对应的volume卷下,而且每次configMap变更,都会把最新值写入到volume卷下,这样容器每次都能取到最新值。
本文链接:http://www.28at.com/showinfo-26-14301-0.html为啥有的ConfigMap要重启Pod才生效
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: JDK21 性能提升20倍