通过 ConfigMap 更新配置
本页面提供了一个通过 ConfigMap 更新 Pod 内配置的分步示例,该示例基于 “配置 Pod 以使用 ConfigMap” 任务构建。
在本教程结束时,你将了解如何更改正在运行的应用程序的配置。
本教程以 Alpine 和 Nginx 镜像为例进行讲解。
开始之前
你需要拥有一个 Kubernetes 集群,并且必须对 kubectl 命令行工具进行配置,使其能够与你的集群进行通信。建议在至少有两个非控制平面节点的集群上运行本教程。如果你还没有集群,可以使用 Minikube 创建一个,或者使用以下 Kubernetes 在线实验环境之一:
- Killercoda
- KodeKloud
- Play with Kubernetes
你需要具备 curl 命令行工具,以便从终端或命令提示符发起 HTTP 请求。如果你没有安装 curl,可以进行安装,请查阅你本地操作系统的相关文档。
目标
- 通过作为卷挂载的 ConfigMap 更新配置。
- 通过 ConfigMap 更新 Pod 的环境变量。
- 在多容器 Pod 中通过 ConfigMap 更新配置。
- 在拥有边车(Sidecar)容器的 Pod 中通过 ConfigMap 更新配置。
通过作为卷挂载的 ConfigMap 更新配置
使用 kubectl create configmap 命令从字面量值创建一个 ConfigMap:
kubectl create configmap sport --from-literal=sport=football此命令创建了一个名为 sport 的 ConfigMap,其中包含一个键值对 sport=football。
以下是一个 Deployment 清单示例,其中 sport ConfigMap 作为卷挂载到 Pod 唯一的容器中:
# deployments/deployment-with-configmap-as-volume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: configmap-volume
labels:
app.kubernetes.io/name: configmap-volume
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: configmap-volume
template:
metadata:
labels:
app.kubernetes.io/name: configmap-volume
spec:
containers:
- name: alpine
image: alpine:3
command:
- /bin/sh
- -c
- while true; do echo "$(date) My preferred sport is $(cat /etc/config/sport)";
sleep 10; done;
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: sport在这个 Deployment 中,定义了 3 个副本的 Pod。每个 Pod 中的 alpine 容器会不断循环,每隔 10 秒打印当前时间和配置文件中的 sport 值。config-volume 卷挂载了 sport ConfigMap 到容器的 /etc/config 路径。
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-volume.yaml检查这个 Deployment 的 Pod 是否准备就绪(通过选择器匹配):
kubectl get pods --selector=app.kubernetes.io/name=configmap-volume预期输出类似如下:
NAME READY STATUS RESTARTS AGE
configmap-volume-6b976dfdcf-qxvbm 1/1 Running 0 72s
configmap-volume-6b976dfdcf-skpvm 1/1 Running 0 72s
configmap-volume-6b976dfdcf-tbc6r 1/1 Running 0 72s这表明所有 Pod 都已成功启动并处于运行状态。
在每个运行这些 Pod 的节点上,kubelet 会获取 ConfigMap 的数据,并将其转换为本地卷中的文件,然后将该卷挂载到容器中。容器内运行的代码会从文件中加载信息并将报告打印到标准输出。可以通过查看 Deployment 中某个 Pod 的日志来查看这个报告:
# 选择一个属于该 Deployment 的 Pod 并查看其日志
kubectl logs deployments/configmap-volume预期输出类似如下:
Found 3 pods, using pod/configmap-volume-76d9c5678f-x5rgj
Thu Jan 4 14:06:46 UTC 2024 My preferred sport is football
Thu Jan 4 14:06:56 UTC 2024 My preferred sport is football
Thu Jan 4 14:07:06 UTC 2024 My preferred sport is football
Thu Jan 4 14:07:16 UTC 2024 My preferred sport is football
Thu Jan 4 14:07:26 UTC 2024 My preferred sport is football可以看到,当前打印的 sport 值为 football。
编辑 ConfigMap
编辑 ConfigMap:
kubectl edit configmap sport在弹出的编辑器中,将键 sport 的值从 football 更改为 cricket,然后保存更改。kubectl 工具会相应地更新 ConfigMap(如果看到错误,请重试)。
编辑后的 ConfigMap 清单示例如下:
apiVersion: v1
data:
sport: cricket
kind: ConfigMap
# 可以保留现有的元数据不变。
# 你看到的值不会与这些完全匹配。
metadata:
creationTimestamp: "2024-01-04T14:05:06Z"
name: sport
namespace: default
resourceVersion: "1743935"
uid: 024ee001-fe72-487e-872e-34d6464a8a23保存后会看到如下输出:
configmap/sport edited跟踪 Pod 日志
跟踪属于这个 Deployment 的某个 Pod 的日志(跟随最新条目):
kubectl logs deployments/configmap-volume --follow几秒钟后,应该会看到日志输出发生如下变化:
Thu Jan 4 14:11:36 UTC 2024 My preferred sport is football
Thu Jan 4 14:11:46 UTC 2024 My preferred sport is football
Thu Jan 4 14:11:56 UTC 2024 My preferred sport is football
Thu Jan 4 14:12:06 UTC 2024 My preferred sport is cricket
Thu Jan 4 14:12:16 UTC 2024 My preferred sport is cricket注意事项
当使用 configMap 卷或投影卷将 ConfigMap 映射到正在运行的 Pod 中,并且更新该 ConfigMap 时,正在运行的 Pod 几乎会立即看到更新。然而,应用程序只有在编写为轮询更改或监视文件更新时才会看到更改。在启动时一次性加载配置的应用程序不会注意到更改。
另外,从 ConfigMap 更新到新键投影到 Pod 的总延迟可能长达 kubelet 同步周期。同时,也可以查看 “挂载的 ConfigMap 会自动更新” 相关内容。
通过 ConfigMap 更新 Pod 的环境变量
使用 kubectl create configmap 命令从字面量值创建一个 ConfigMap:
kubectl create configmap fruits --from-literal=fruits=apples此命令创建了一个名为 fruits 的 ConfigMap,其中包含一个键值对 fruits=apples。
以下是一个 Deployment 清单示例,其中通过 fruits ConfigMap 配置了一个环境变量:
# deployments/deployment-with-configmap-as-envvar.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: configmap-env-var
labels:
app.kubernetes.io/name: configmap-env-var
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: configmap-env-var
template:
metadata:
labels:
app.kubernetes.io/name: configmap-env-var
spec:
containers:
- name: alpine
image: alpine:3
env:
- name: FRUITS
valueFrom:
configMapKeyRef:
key: fruits
name: fruits
command:
- /bin/sh
- -c
- while true; do echo "$(date) The basket is full of $FRUITS";
sleep 10; done;
ports:
- containerPort: 80在这个 Deployment 中,定义了 3 个副本的 Pod。每个 Pod 中的 alpine 容器设置了一个名为 FRUITS 的环境变量,其值从 fruits ConfigMap 的 fruits 键获取。容器会不断循环,每隔 10 秒打印当前时间和 FRUITS 环境变量的值。
创建这个 Deployment:
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-envvar.yaml检查 Pod 状态
检查这个 Deployment 的 Pod 是否准备就绪(通过选择器匹配):
kubectl get pods --selector=app.kubernetes.io/name=configmap-env-var预期输出类似如下:
NAME READY STATUS RESTARTS AGE
configmap-env-var-59cfc64f7d-74d7z 1/1 Running 0 46s
configmap-env-var-59cfc64f7d-c4wmj 1/1 Running 0 46s
configmap-env-var-59cfc64f7d-dpr98 1/1 Running 0 46s这表明所有 Pod 都已成功启动并处于运行状态。
查看 Pod 日志
fruits ConfigMap 中的键值对被配置为 Pod 容器中的环境变量。可以通过查看属于该 Deployment 的一个 Pod 的日志来检查:
kubectl logs deployment/configmap-env-var预期输出类似如下:
Found 3 pods, using pod/configmap-env-var-7c994f7769-l74nq
Thu Jan 4 16:07:06 UTC 2024 The basket is full of apples
Thu Jan 4 16:07:16 UTC 2024 The basket is full of apples
Thu Jan 4 16:07:26 UTC 2024 The basket is full of apples可以看到,当前打印的 FRUITS 环境变量值为 apples。
编辑 ConfigMap
编辑 ConfigMap:
kubectl edit configmap fruits在弹出的编辑器中,将键 fruits 的值从 apples 更改为 mangoes,然后保存更改。kubectl 工具会相应地更新 ConfigMap(如果看到错误,请重试)。
编辑后的 ConfigMap 清单示例如下:
apiVersion: v1
data:
fruits: mangoes
kind: ConfigMap
# 可以保留现有的元数据不变。
# 你看到的值不会与这些完全匹配。
metadata:
creationTimestamp: "2024-01-04T16:04:19Z"
name: fruits
namespace: default
resourceVersion: "1749472"保存后会看到如下输出:
configmap/fruits edited跟踪 Pod 日志
跟踪该 Deployment 的日志并观察几秒钟的输出:
kubectl logs deployments/configmap-env-var --follow会注意到,即使编辑了 ConfigMap,输出仍然没有改变:
Thu Jan 4 16:12:56 UTC 2024 The basket is full of apples
Thu Jan 4 16:13:06 UTC 2024 The basket is full of apples
Thu Jan 4 16:13:16 UTC 2024 The basket is full of apples
Thu Jan 4 16:13:26 UTC 2024 The basket is full of apples注意事项
尽管 ConfigMap 中键的值已更改,但 Pod 中的环境变量仍显示先前的值。这是因为当源数据更改时,Pod 内运行进程的环境变量不会更新;如果要强制更新,则需要让 Kubernetes 替换现有的 Pod。新的 Pod 将使用更新后的信息运行。
可以通过执行 Deployment 的滚动更新来触发替换,使用 kubectl rollout 命令:
# 触发滚动更新
kubectl rollout restart deployment configmap-env-var
# 等待滚动更新完成
kubectl rollout status deployment configmap-env-var --watch=true接下来,检查 Deployment:
kubectl get deployment configmap-env-var预期输出类似如下:
NAME READY UP-TO-DATE AVAILABLE AGE
configmap-env-var 3/3 3 3 12m检查 Pod:
kubectl get pods --selector=app.kubernetes.io/name=configmap-env-var滚动更新会使 Kubernetes 为 Deployment 创建一个新的 ReplicaSet,这意味着现有 Pod 最终会终止,并创建新的 Pod。几秒钟后,应该会看到类似如下的输出:
NAME READY STATUS RESTARTS AGE
configmap-env-var-6d94d89bf5-2ph2l 1/1 Running 0 13s
configmap-env-var-6d94d89bf5-74twx 1/1 Running 0 8s
configmap-env-var-6d94d89bf5-d5vx8 1/1 Running 0 11s查看更新后 Pod 日志
注意:在继续下一步之前,请等待较旧的 Pod 完全终止。
查看该 Deployment 中一个 Pod 的日志:
kubectl logs deployment/configmap-env-var预期输出类似如下:
Found 3 pods, using pod/configmap-env-var-6d9ff89fb6-bzcf6
Thu Jan 4 16:30:35 UTC 2024 The basket is full of mangoes
Thu Jan 4 16:30:45 UTC 2024 The basket is full of mangoes
Thu Jan 4 16:30:55 UTC 2024 The basket is full of mangoes这演示了通过 ConfigMap 更新 Pod 中环境变量的场景。对 ConfigMap 值的更改会在后续的滚动更新中应用到 Pod。如果由于其他原因(例如扩展 Deployment)创建了 Pod,那么新的 Pod 也会使用最新的配置值;如果不触发滚动更新,可能会发现应用程序运行时使用的环境变量值新旧混杂。
在多容器 Pod 中通过 ConfigMap 更新配置
创建 ConfigMap
使用 kubectl create configmap 命令从字面量值创建一个 ConfigMap:
kubectl create configmap color --from-literal=color=red此命令创建了一个名为 color 的 ConfigMap,其中包含一个键值对 color=red。
创建 Deployment
以下是一个 Deployment 的清单示例,它管理一组 Pod,每个 Pod 包含两个容器。这两个容器共享一个 emptyDir 卷用于相互通信。第一个容器运行一个 Web 服务器(Nginx),Web 服务器容器中共享卷的挂载路径是 /usr/share/nginx/html。第二个辅助容器基于 Alpine 镜像,对于这个容器,emptyDir 卷挂载在 /pod-data 路径下。辅助容器根据 ConfigMap 的内容编写一个 HTML 文件,Web 服务器容器通过 HTTP 提供这个 HTML 文件的服务。
# deployments/deployment-with-configmap-two-containers.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: configmap-two-containers
labels:
app.kubernetes.io/name: configmap-two-containers
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: configmap-two-containers
template:
metadata:
labels:
app.kubernetes.io/name: configmap-two-containers
spec:
volumes:
- name: shared-data
emptyDir: {}
- name: config-volume
configMap:
name: color
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: alpine
image: alpine:3
volumeMounts:
- name: shared-data
mountPath: /pod-data
- name: config-volume
mountPath: /etc/config
command:
- /bin/sh
- -c
- while true; do echo "$(date) My preferred color is $(cat /etc/config/color)" > /pod-data/index.html;
sleep 10; done;在这个 Deployment 中,定义了 3 个副本的 Pod。每个 Pod 有两个容器 nginx 和 alpine,它们共享 shared-data 卷,alpine 容器还挂载了 config-volume 卷(即 color ConfigMap)。alpine 容器会不断循环,每隔 10 秒将当前时间和 color ConfigMap 中 color 键的值写入到共享卷的 index.html 文件中,nginx 容器则提供该文件的 HTTP 服务。
创建这个 Deployment:
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-two-containers.yaml检查 Pod 状态
检查这个 Deployment 的 Pod 是否准备就绪(通过选择器匹配):
kubectl get pods --selector=app.kubernetes.io/name=configmap-two-containers预期输出类似如下:
NAME READY STATUS RESTARTS AGE
configmap-two-containers-565fb6d4f4-2xhxf 2/2 Running 0 20s
configmap-two-containers-565fb6d4f4-g5v4j 2/2 Running 0 20s
configmap-two-containers-565fb6d4f4-mzsmf 2/2 Running 0 20s这表明所有 Pod 都已成功启动并处于运行状态。
暴露 Deployment
暴露这个 Deployment(kubectl 工具会为你创建一个 Service):
kubectl expose deployment configmap-two-containers --name=configmap-service --port=8080 --target-port=80端口转发
使用 kubectl 进行端口转发:
# 此命令会在后台持续运行
kubectl port-forward service/configmap-service 8080:8080 &访问服务
访问该服务:
curl http://localhost:8080预期输出类似如下:
Fri Jan 5 08:08:22 UTC 2024 My preferred color is red
编辑 ConfigMap
编辑 ConfigMap:kubectl edit configmap color在弹出的编辑器中,将键 color 的值从 red 更改为 blue,然后保存更改。kubectl 工具会相应地更新 ConfigMap(如果看到错误,请重试)。
编辑后的 ConfigMap 清单示例如下:
apiVersion: v1
data:
color: blue
kind: ConfigMap
# 可以保留现有的元数据不变。
# 你看到的值不会与这些完全匹配。
metadata:
creationTimestamp: "2024-01-05T08:12:05Z"
name: color
namespace: configmap
resourceVersion: "1801272"
uid: 80d33e4a-cbb4-4bc9-ba8c-544c68e425d6循环访问服务 URL
持续循环访问服务 URL 几秒钟:
# 当你满意输出时可取消(按 Ctrl-C)
while true; do curl --connect-timeout 7.5 http://localhost:8080; sleep 10; done应该会看到输出如下变化:
Fri Jan 5 08:14:00 UTC 2024 My preferred color is red
Fri Jan 5 08:14:02 UTC 2024 My preferred color is red
Fri Jan 5 08:14:20 UTC 2024 My preferred color is red
Fri Jan 5 08:14:22 UTC 2024 My preferred color is red
Fri Jan 5 08:14:32 UTC 2024 My preferred color is blue
Fri Jan 5 08:14:43 UTC 2024 My preferred color is blue
Fri Jan 5 08:15:00 UTC 2024 My preferred color is blue这表明在多容器 Pod 中,通过更新 ConfigMap,能够成功更新应用程序的配置并反映在服务的输出中。
在拥有边车容器的 Pod 中通过 ConfigMap 更新配置
配置准备
若你是接着上一个场景继续操作,可复用名为 color 的 ConfigMap;若你要独立执行此场景,需使用 kubectl create configmap 命令从字面量值创建一个 ConfigMap:
kubectl create configmap color --from-literal=color=blue此命令创建了一个名为 color 的 ConfigMap,其中包含键值对 color=blue。
创建 Deployment
以下是一个 Deployment 的清单示例,它管理一组 Pod,每个 Pod 有一个主容器和一个边车容器。这两个容器共享一个 emptyDir 卷用于通信。主容器运行一个 Web 服务器(NGINX),Web 服务器容器中共享卷的挂载路径为 /usr/share/nginx/html。第二个容器是基于 Alpine Linux 的边车容器,作为辅助容器。对于这个容器,emptyDir 卷挂载在/pod-data 路径下。边车容器会根据 ConfigMap 的内容编写一个 HTML 文件,Web 服务器容器通过 HTTP 提供这个 HTML 文件的服务。
# deployments/deployment-with-configmap-and-sidecar-container.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: configmap-sidecar-container
labels:
app.kubernetes.io/name: configmap-sidecar-container
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: configmap-sidecar-container
template:
metadata:
labels:
app.kubernetes.io/name: configmap-sidecar-container
spec:
volumes:
- name: shared-data
emptyDir: {}
- name: config-volume
configMap:
name: color
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
initContainers:
- name: alpine
image: alpine:3
restartPolicy: Always
volumeMounts:
- name: shared-data
mountPath: /pod-data
- name: config-volume
mountPath: /etc/config
command:
- /bin/sh
- -c
- while true; do echo "$(date) My preferred color is $(cat /etc/config/color)" > /pod-data/index.html;
sleep 10; done;在这个 Deployment 中,定义了 3 个副本的 Pod。每个 Pod 里,nginx 容器作为主容器提供 HTTP 服务,alpine 容器作为边车容器(以 initContainers 形式存在)负责根据 ConfigMap 内容更新 HTML 文件。边车容器会每隔 10 秒将当前时间和 color ConfigMap 中 color 键的值写入到共享卷的 index.html 文件中。
创建这个 Deployment:
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-and-sidecar-container.yaml检查 Pod 状态
检查这个 Deployment 的 Pod 是否准备就绪(通过选择器匹配):
kubectl get pods --selector=app.kubernetes.io/name=configmap-sidecar-container预期输出类似如下:
NAME READY STATUS RESTARTS AGE
configmap-sidecar-container-5fb59f558b-87rp7 2/2 Running 0 94s
configmap-sidecar-container-5fb59f558b-ccs7s 2/2 Running 0 94s
configmap-sidecar-container-5fb59f558b-wnmgk 2/2 Running 0 94s这表明所有 Pod 都已成功启动并处于运行状态。
暴露 Deployment
暴露这个 Deployment(kubectl 工具会为你创建一个 Service):
kubectl expose deployment configmap-sidecar-container --name=configmap-sidecar-service --port=8081 --target-port=80端口转发
使用 kubectl 进行端口转发:
# 此命令会在后台持续运行
kubectl port-forward service/configmap-sidecar-service 8081:8081 &访问服务
访问该服务:
curl http://localhost:8081预期输出类似如下:
Sat Feb 17 13:09:05 UTC 2024 My preferred color is blue编辑 ConfigMap
编辑 ConfigMap:
kubectl edit configmap color在弹出的编辑器中,将键 color 的值从 blue 更改为 green,然后保存更改。kubectl 工具会相应地更新 ConfigMap(如果看到错误,请重试)。
编辑后的 ConfigMap 清单示例如下:
apiVersion: v1
data:
color: green
kind: ConfigMap
# 可以保留现有的元数据不变。
# 你看到的值不会与这些完全匹配。
metadata:
creationTimestamp: "2024-02-17T12:20:30Z"
name: color
namespace: default
resourceVersion: "1054"
uid: e40bb34c-58df-4280-8bea-6ed16edccfaa循环访问服务 URL
持续循环访问服务 URL 几秒钟:
# 当你满意输出时可取消(按 Ctrl-C)
while true; do curl --connect-timeout 7.5 http://localhost:8081; sleep 10; done应该会看到输出如下变化:
Sat Feb 17 13:12:35 UTC 2024 My preferred color is blue
Sat Feb 17 13:12:45 UTC 2024 My preferred color is blue
Sat Feb 17 13:12:55 UTC 2024 My preferred color is blue
Sat Feb 17 13:13:05 UTC 2024 My preferred color is blue
Sat Feb 17 13:13:15 UTC 2024 My preferred color is green
Sat Feb 17 13:13:25 UTC 2024 My preferred color is green
Sat Feb 17 13:13:35 UTC 2024 My preferred color is green这说明在拥有边车容器的 Pod 中,通过更新 ConfigMap 能够更新应用程序的配置,并且配置的更改会反映在服务的输出中。由于边车容器会定期根据 ConfigMap 内容更新 HTML 文件,所以当 ConfigMap 内容改变后,服务的输出也会随之更新。
通过作为卷挂载的不可变 ConfigMap 更新配置
注意事项
不可变的 ConfigMap 特别适用于那些固定不变、预期不会随时间变化的配置。将 ConfigMap 标记为不可变可以提升性能,因为此时 kubelet 无需监视其变化。
如果你确实需要进行更改,应该计划采取以下措施之一:
- 更改 ConfigMap 的名称,并切换到运行引用新名称的 Pod。
- 替换集群中所有之前运行过使用旧值 Pod 的节点。
- 在 kubelet 之前加载过旧 ConfigMap 的任何节点上重启 kubelet。
创建不可变 ConfigMap
以下是一个不可变 ConfigMap 的清单示例:
# configmap/immutable-configmap.yaml
apiVersion: v1
data:
company_name: "ACME, Inc." # 现有的虚构公司名称
kind: ConfigMap
immutable: true
metadata:
name: company-name-20150801创建这个不可变 ConfigMap:
kubectl apply -f https://k8s.io/examples/configmap/immutable-configmap.yaml创建 Deployment 以下是一个 Deployment 清单示例,其中将不可变 ConfigMap company-name-20150801 作为卷挂载到 Pod 的唯一容器中:
# deployments/deployment-with-immutable-configmap-as-volume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: immutable-configmap-volume
labels:
app.kubernetes.io/name: immutable-configmap-volume
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: immutable-configmap-volume
template:
metadata:
labels:
app.kubernetes.io/name: immutable-configmap-volume
spec:
containers:
- name: alpine
image: alpine:3
command:
- /bin/sh
- -c
- while true; do echo "$(date) The name of the company is $(cat /etc/config/company_name)";
sleep 10; done;
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: company-name-20150801创建这个 Deployment:
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-immutable-configmap-as-volume.yaml检查 Pod 状态
检查这个 Deployment 的 Pod 是否准备就绪(通过选择器匹配):
kubectl get pods --selector=app.kubernetes.io/name=immutable-configmap-volume预期输出类似如下:
NAME READY STATUS RESTARTS AGE
immutable-configmap-volume-78b6fbff95-5gsfh 1/1 Running 0 62s
immutable-configmap-volume-78b6fbff95-7vcj4 1/1 Running 0 62s
immutable-configmap-volume-78b6fbff95-vdslm 1/1 Running 0 62s查看 Pod 日志
Pod 的容器引用了 ConfigMap 中定义的数据,并将其用于打印报告到标准输出。可以通过查看该 Deployment 中一个 Pod 的日志来检查这个报告:
# 选择一个属于该 Deployment 的 Pod 并查看其日志
kubectl logs deployments/immutable-configmap-volume预期输出类似如下:
Found 3 pods, using pod/immutable-configmap-volume-78b6fbff95-5gsfh
Wed Mar 20 03:52:34 UTC 2024 The name of the company is ACME, Inc.
Wed Mar 20 03:52:44 UTC 2024 The name of the company is ACME, Inc.
Wed Mar 20 03:52:54 UTC 2024 The name of the company is ACME, Inc.注意事项
一旦 ConfigMap 被标记为不可变,就无法撤销此更改,也无法修改 data 或 binaryData 字段的内容。
为了修改使用此配置的 Pod 的行为,你需要创建一个新的不可变 ConfigMap,并编辑 Deployment 以定义一个略有不同的 Pod 模板,引用新的 ConfigMap。
创建新的不可变 ConfigMap
使用以下清单创建一个新的不可变 ConfigMap:
# configmap/new-immutable-configmap.yaml
apiVersion: v1
data:
company_name: "Fiktivesunternehmen GmbH" # 新的虚构公司名称
kind: ConfigMap
immutable: true
metadata:
name: company-name-20240312应用这个新的 ConfigMap:
kubectl apply -f https://k8s.io/examples/configmap/new-immutable-configmap.yaml预期输出类似如下:
configmap/company-name-20240312 created检查新创建的 ConfigMap
检查新创建的 ConfigMap:
kubectl get configmap预期输出会显示新旧两个 ConfigMap:
NAME DATA AGE
company-name-20150801 1 22m
company-name-20240312 1 24s修改 Deployment 以引用新的 ConfigMap
编辑 Deployment:
kubectl edit deployment immutable-configmap-volume在弹出的编辑器中,更新现有的卷定义以使用新的 ConfigMap:
volumes:
- configMap:
defaultMode: 420
name: company-name-20240312 # 更新此字段
name: config-volume保存后应该会看到如下输出:
deployment.apps/immutable-configmap-volume edited这将触发一次滚动更新。等待所有之前的 Pod 终止,新的 Pod 进入就绪状态。
监控 Pod 状态
监控 Pod 的状态:
kubectl get pods --selector=app.kubernetes.io/name=immutable-configmap-volume你会看到类似如下的输出,旧的 Pod 会终止,新的 Pod 会运行:
NAME READY STATUS RESTARTS AGE
immutable-configmap-volume-5fdb88fcc8-29v8n 1/1 Running 0 13s
immutable-configmap-volume-5fdb88fcc8-52ddd 1/1 Running 0 14s
immutable-configmap-volume-5fdb88fcc8-n5jx4 1/1 Running 0 15s
immutable-configmap-volume-78b6fbff95-5gsfh 1/1 Terminating 0 32m
immutable-configmap-volume-78b6fbff95-7vcj4 1/1 Terminating 0 32m
immutable-configmap-volume-78b6fbff95-vdslm 1/1 Terminating 0 32m最终你应该会看到类似如下的输出:
NAME READY STATUS RESTARTS AGE
immutable-configmap-volume-5fdb88fcc8-29v8n 1/1 Running 0 43s
immutable-configmap-volume-5fdb88fcc8-52ddd 1/1 Running 0 44s
immutable-configmap-volume-5fdb88fcc8-n5jx4 1/1 Running 0 45s查看更新后 Pod 的日志
查看该 Deployment 中一个 Pod 的日志:
# 选择一个属于该 Deployment 的 Pod 并查看其日志
kubectl logs deployment/immutable-configmap-volume预期输出类似如下:
Found 3 pods, using pod/immutable-configmap-volume-5fdb88fcc8-n5jx4
Wed Mar 20 04:24:17 UTC 2024 The name of the company is Fiktivesunternehmen GmbH
Wed Mar 20 04:24:27 UTC 2024 The name of the company is Fiktivesunternehmen GmbH
Wed Mar 20 04:24:37 UTC 2024 The name of the company is Fiktivesunternehmen GmbH删除旧的 ConfigMap
一旦所有的部署都迁移到使用新的不可变 ConfigMap,建议删除旧的 ConfigMap:
kubectl delete configmap company-name-20150801总结
对于挂载为 Pod 卷的 ConfigMap,在 kubelet 后续同步之后,其变更会无缝生效。这意味着只要 kubelet 完成同步,Pod 就可以立即使用更新后的 ConfigMap 数据,应用程序若持续读取卷中的配置文件,就能及时感知到变化。
对于为 Pod 配置环境变量的 ConfigMap,其变更在 Pod 后续的滚动更新后才会生效。由于环境变量在容器启动时就已设置,容器运行过程中不会自动更新,所以需要通过滚动更新替换 Pod 来使新的配置生效。
一旦 ConfigMap 被标记为不可变,就无法撤销这一更改(即无法将不可变的 ConfigMap 变回可变),也不能对其 data 或 binaryData 字段的内容进行任何修改。此时,你可以选择删除并重新创建该 ConfigMap,或者创建一个全新的 ConfigMap。当删除一个 ConfigMap 时,正在运行的容器及其 Pod 对任何引用该 ConfigMap 的卷的挂载点依然会保留 。
清理操作
如果 kubectl port-forward 命令仍在运行,请终止它们。
删除本教程中创建的资源:
kubectl delete deployment configmap-volume configmap-env-var configmap-two-containers configmap-sidecar-container immutable-configmap-volumekubectl delete service configmap-service configmap-sidecar-servicekubectl delete configmap sport fruits color company-name-20240312kubectl delete configmap company-name-20150801 # 如有需要上述第一条 kubectl delete deployment 命令用于删除多个 Deployment 资源,这些 Deployment 在教程中分别用于展示通过 ConfigMap 以不同方式(挂载为卷、配置环境变量、在多容器 Pod 中使用、在含边车容器的 Pod 中使用以及使用不可变 ConfigMap 等)配置 Pod 的功能。
第二条 kubectl delete service 命令删除在教程中为暴露 Deployment 而创建的 Service 资源。
第三条和第四条 kubectl delete configmap 命令用于删除在教程中创建的 ConfigMap 资源,包括不同场景下用于配置 Pod 的 ConfigMap,如 sport、fruits、color 以及不可变 ConfigMap company-name-20240312 和 company-name-20150801 (如果还存在的话)。通过这些删除操作,可以清理教程执行过程中在 Kubernetes 集群中创建的各类资源,避免占用集群资源和造成资源混乱。