本文学习官方文档: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+ 特性,适合不变配置,优化性能
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐