為啥有的ConfigMap要重啟Pod才生效
在一般應(yīng)用部署中,都是將程序和配置信息分離,這樣可以保證程序可以被各個(gè)環(huán)境復(fù)用。
在容器場(chǎng)景中,將應(yīng)用打包成鏡像后,可以通過(guò)環(huán)境變量或者文件掛載的方式,在創(chuàng)建容器時(shí)把配置注入進(jìn)去。
在Kubernetes場(chǎng)景中,則使用configMap實(shí)現(xiàn)應(yīng)用與配置分離。使用configMap的方式有多種,有的方式修改了configMap的配置,無(wú)需重啟Pod即可生效,有的方式需要重啟Pod才生效??纯茨阌玫氖悄囊环N吧。
一、使用方式
使用configMap做程序和配置分離,那么首先就要定義configMap,然后部署configMap。
1.定義configMap
apiVersion: v1
kind: ConfigMap
metadata:
name: democm
namespace: demo
data:
db_name: demodb
db_host: 172.19.132.23
configMap有3種使用方式:env方式 、envFrom方式 、volumes方式。
2.env方式
這種方式是將configMap的key-value注入到容器的環(huán)境變量里,程序里使用時(shí),使用env里定義的name即可獲取到對(duì)應(yīng)的值。使用方式如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-cm-1
namespace: demo
labels:
app: pod-cm-1
spec:
containers:
- name: pod-cm-1
image: busybox
imagePullPolicy: IfNotPresent
tty: true
# 會(huì)出現(xiàn)在容器的環(huán)境變量里,程序里要使用env#name可以獲取到對(duì)應(yīng)的值
env:
- name: db_name_app
valueFrom:
configMapKeyRef:
name: democm
key: db_name
- name: db_host_app
valueFrom:
configMapKeyRef:
name: democm
key: db_host
3.envFrom方式
這種方式也是將configMap的key-value注入到容器的環(huán)境變量里,使用方法與env方式類(lèi)似,只不過(guò)在程序使用時(shí),是直接使用configMap定義的key,即可獲取到對(duì)應(yīng)的值。使用方式如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-cm-2
namespace: demo
labels:
app: pod-cm-2
spec:
containers:
- name: pod-cm-2
image: busybox
imagePullPolicy: IfNotPresent
tty: true
# 程序里使用configmap的key
envFrom:
- configMapRef:
name: democm
4.volumes方式
這種方式是以卷掛載的方式,將configMap的key-value寫(xiě)入到文件里,key是文件名,value是文件內(nèi)容。
使用方式如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-cm-3
namespace: demo
labels:
app: pod-cm-3
spec:
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
觀(guān)察volume卷下面的內(nèi)容:
進(jìn)入到容器的/usr/share/nginx/html目錄下,可以看到configMap定義的key-value會(huì)出現(xiàn)此目錄下,并且會(huì)有一個(gè)類(lèi)似時(shí)間的文件。進(jìn)入到文件夾里,可以看到對(duì)應(yīng)的db_host和db_name文件。
如果configMap變化之后,對(duì)應(yīng)的會(huì)生成新的文件:
二、實(shí)踐
1.編排部署configMap
編排部署configMap,查看部署后的configMap信息:
[root@k8s-master configmap]# kubectl apply -f configmap.yaml
configmap/democm created
[root@k8s-master configmap]# kubectl get cm -n demo
NAME DATA AGE
democm 2 11s
[root@k8s-master configmap]# kubectl describe cm democm -n demo
Name: democm
Namespace: demo
Labels: <none>
Annotations: <none>
Data
====
db_host:
----
172.19.132.23
db_name:
----
demodb
Events: <none>
2.env方式
從這里可以看到env方式定義的yaml里的env已經(jīng)被放入到容器的環(huán)境變量里的,只不過(guò)env里的值是從configMap里取的。
[root@k8s-master configmap]# kubectl exec -it pod-cm-1 -n demo -- /bin/sh
/ #
/ # evn
/bin/sh: evn: not found
/ # env
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=pod-cm-1
SHLVL=1
HOME=/root
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
db_host_app=172.19.132.23
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
db_name_app=demodb
3.envFrom方式
從這里可以看到envFrom方式是直接把configMap的key-value放入到容器的環(huán)境變量里的。
[root@k8s-master configmap]# kubectl apply -f pod_configmap_2.yaml
pod/pod-cm-2 created
[root@k8s-master configmap]# kubectl exec -it pod-cm-2 -n demo -- /bin/sh
/ #
/ # env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=pod-cm-2
SHLVL=1
HOME=/root
db_name=demodb
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
db_host=172.19.132.23
4.volumes方式
這種方式可以看到,volumes方式并沒(méi)有把configMap的值放入到環(huán)境變量。
[root@k8s-master configmap]# kubectl apply -f pod_configmap_3.yaml
pod/pod-cm-3 created
[root@k8s-master configmap]# kubectl exec -it pod-cm-3 -n demo -- /bin/sh
# env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=pod-cm-3
HOME=/root
PKG_RELEASE=1~bookworm
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
NGINX_VERSION=1.25.2
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=0.8.0
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
但是可以看到configMap的key-value被寫(xiě)入到了文件里。
# cd /usr/share/nginx/html
# ls
db_host db_name
# cat db_host
172.19.132.23
# cat db_name
demodb
5.修改configMap值
修改configMap值,然后重新部署configMap,繼續(xù)觀(guān)察這3種方式。
用命令kubectl exec -it pod-cm-xxxxxx -n demo -- /bin/sh進(jìn)入到容器后,可以觀(guān)察到:
- env方式和envFrom方式方式對(duì)應(yīng)的值沒(méi)有變化,需要重啟Pod后才生效。
- volumes方式的值會(huì)自動(dòng)變化。
三、總結(jié)
本文總結(jié)了configMap使用的3種方式:env方式、envFrom方式、volumes方式。
env方式和envFrom方式方式說(shuō)白了是往容器里注入了環(huán)境變量,在容器啟動(dòng)的時(shí)候,就已經(jīng)注入了,無(wú)法修改。每次修改configMap的key-value,需要重啟Pod才能生效。
volumes方式的方式,實(shí)際上把configMap的key-value寫(xiě)入到了容器對(duì)應(yīng)的volume卷下,而且每次configMap變更,都會(huì)把最新值寫(xiě)入到volume卷下,這樣容器每次都能取到最新值。