Kubernetes-通过ConfigMap更新配置
本文学习官方文档:https://kubernetes.io/docs/tutorials/configuration/updating-configuration-via-a-configmap/,展示如何使用 ConfigMap 更新运行中的 Pod 配置。
完成本教程后,你将了解如何更改运行中应用程序的配置。
示例中使用 alpine 和 nginx 镜像。
实验环境直接用下面这个,免搭建
https://killercoda.com/playgrounds/scenario/kubernetes
学习目标
- 通过以 Volume 方式挂载的 ConfigMap 更新配置
- 通过 ConfigMap 更新 Pod 的环境变量
- 在多容器 Pod 中通过 ConfigMap 更新配置
- 在带有 Sidecar 容器的 Pod 中通过 ConfigMap 更新配置
- (额外)使用不可变(immutable)ConfigMap 的场景
1. 以 Volume 方式挂载 ConfigMap 更新配置
创建 ConfigMap
kubectl create configmap sport --from-literal=sport=football
创建 Deployment 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
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-volume.yaml
查看 Pod
kubectl get pods --selector=app.kubernetes.io/name=configmap-volume
查看初始日志
kubectl logs deployment/configmap-volume
输出示例:My preferred sport is football
修改 ConfigMap
kubectl edit configmap sport
将 sport: football 改为 sport: cricket,保存。
观察日志变化(自动更新)
kubectl logs deployment/configmap-volume --follow
几秒后日志自动变为 cricket。
结论:ConfigMap 以 volume 挂载时,更新会投影到容器内文件,kubelet 周期同步(通常几秒生效)。应用需支持重新读取文件(轮询、watch 等)。
2. 通过 ConfigMap 更新环境变量
创建 ConfigMap
kubectl create configmap fruits --from-literal=fruits=apples
创建 Deployment 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:
name: fruits
key: fruits
command:
- /bin/sh
- -c
- while true; do echo "$(date) The basket is full of $FRUITS"; sleep 10; done;
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-as-envvar.yaml
查看初始日志
显示 apples
修改 ConfigMap
kubectl edit configmap fruits # 改为 mangoes
观察 → 无变化
环境变量在 Pod 创建时注入,不会自动刷新。
触发滚动更新
kubectl rollout restart deployment/configmap-env-var
kubectl rollout status deployment/configmap-env-var --watch
新 Pod 日志显示 mangoes。
结论:环境变量需通过 Deployment 滚动更新才能生效。
3. 多容器 Pod 中通过 ConfigMap 更新配置
此例中两个容器共享 emptyDir 卷:一个 helper(alpine)根据 ConfigMap 写 HTML,nginx 提供服务。
创建 ConfigMap
kubectl create configmap color --from-literal=color=red
创建 Deployment 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;
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-two-containers.yaml
暴露服务并测试
kubectl expose deployment configmap-two-containers --name=configmap-service --port=8080 --target-port=80
kubectl port-forward service/configmap-service 8080:8080 &
curl http://localhost:8080 # 显示 red
修改 ConfigMap → blue
kubectl edit configmap color
持续观察
while true; do curl --connect-timeout 7.5 http://localhost:8080; sleep 10; done
几秒后自动变为 blue(因为 helper 容器周期写入,nginx 直接读文件)。
4. 带有 Sidecar 容器的 Pod 通过 ConfigMap 更新配置
Sidecar 作为 helper 容器(使用 restartPolicy: Always 模拟 sidecar 行为)。
YAML 与上面类似,但 alpine 移到 initContainers 并设为循环运行(官方示例使用此方式模拟 sidecar)。
# ... 与上面类似,主要区别:
containers:
- name: nginx
...
initContainers:
- name: alpine
image: alpine:3
restartPolicy: Always # 关键:让它像 sidecar 一样持续运行
...
kubectl apply -f https://k8s.io/examples/deployments/deployment-with-configmap-and-sidecar-container.yaml
暴露端口 8081,修改 ConfigMap 后观察变化(同上,自动生效)。
结论:多容器 / sidecar 场景中,只要 ConfigMap 以 volume 挂载且有容器主动重新生成内容,主容器就能感知更新。
5. 使用不可变(Immutable)ConfigMap
不可变 ConfigMap 禁止更新,适合稳定配置。
创建不可变 ConfigMap
apiVersion: v1
kind: ConfigMap
immutable: true
metadata:
name: company-name-20150801
data:
company_name: "ACME, Inc."
kubectl apply -f https://k8s.io/examples/configmap/immutable-configmap.yaml
使用它创建 Deployment
类似第一个 volume 示例,挂载后日志显示公司名。
尝试 kubectl edit configmap company-name-20150801 → 会报错(Forbidden: cannot update immutable ConfigMap)。
优点:防止意外修改,kubelet 优化同步(不检查更新)。
清理
kubectl delete all -l app.kubernetes.io/name=configmap-volume
kubectl delete all -l app.kubernetes.io/name=configmap-env-var
kubectl delete all -l app.kubernetes.io/name=configmap-two-containers
kubectl delete all -l app.kubernetes.io/name=configmap-sidecar-container
kubectl delete all -l app.kubernetes.io/name=immutable-configmap-volume
kubectl delete configmap sport fruits color company-name-20150801
kubectl delete svc configmap-service configmap-sidecar-service
总结与关键点
- Volume 挂载 → ConfigMap 更新 → 容器文件自动同步(需应用支持重读)
- 环境变量 → 只在 Pod 创建/重启时注入 → 需 rollout 更新
- 多容器 / Sidecar → 可实现更灵活的动态配置注入(如配置生成器 + 主应用)
- Immutable ConfigMap → 1.21+ 特性,适合不变配置,优化性能
更多推荐



所有评论(0)