改了 ConfigMap,容器里多久能看到?环境变量会跟着变吗?更新是原子的吗?把 ConfigMap 删了会怎样?这篇在真集群里改三次、测三次延迟,读符号链接,重启容器,逐个回答。
初始:环境变量 LEVEL='v1';文件 /etc/cfg/level='v1' 连续改 3 次 ConfigMap(v2 → v3 → v4),从 apply 到容器里读到新内容的延迟(秒):[60.0, 66.7, 76.0] 此时环境变量 LEVEL='v1'(进程启动时就固定了,之后不会再变);文件 /etc/cfg/level='v4'
Pod 里同时用 env.valueFrom.configMapKeyRef 和挂载。连续改 3 次 ConfigMap,挂载的文件分别在 60.0、66.7、76.0 秒后才在容器里读到新值(另一次测到 86 秒)——kubelet 靠周期同步,不是 watch 到变化马上写。环境变量始终是 v1:它在容器启动时一次性注入,之后无论怎么改 ConfigMap 都不会变。
更新前:
..data -> ..2026_10_10_14_43_46.3905505594
level -> ..data/level
..2026_10_10_14_43_46.3905505594
更新后(86 秒):
..data -> ..2026_10_10_14_45_14.1016284082
level -> ..data/level
..2026_10_10_14_45_14.1016284082
旧的时间戳目录是否还在:False挂载目录里每个键是 level -> ..data/level 的符号链接,..data 再指向一个带时间戳的目录。更新时 kubelet 先把完整的新目录写好,再把 ..data 一次性改指向新目录,最后删掉旧目录:读文件的进程不会读到“一半新一半旧”。这也是 subPath 挂载不更新的根源(下一篇)。
现在 ConfigMap 里 level='v5',容器环境变量 LEVEL='v1' 用 crictl 停掉容器、kubelet 重启它(restartCount=1,Pod uid 没变:True)后:LEVEL='v5'(重启时重新读 ConfigMap)
ConfigMap 已经是 v5,环境变量还是 v1。用 crictl 停掉容器,kubelet 重启它(restartCount=1,Pod uid 没变),新容器里 LEVEL 就是 v5。所以改 ConfigMap 想让环境变量生效,重启容器就够,不一定要重建 Pod;常见做法是 kubectl rollout restart。
删除 ConfigMap 后 5 秒:Pod phase=Running;文件 /etc/cfg/level='v5'
100 秒后:Pod phase=Running;文件 /etc/cfg/level='v5'(kubelet 同步失败只是产生 FailedMount 事件,不会清掉文件)
事件里的 FailedMount:['FailedMount: MountVolume.SetUp failed for volume "cfg" : configmap "cfg" not found']删除 ConfigMap 之后,运行中的 Pod 仍是 Running,/etc/cfg/level 5 秒后和 100 秒后都还是 v5:kubelet 同步失败只产生一条 FailedMount: … configmap "cfg" not found 事件,不会把已有文件清掉。但此时新建的 Pod 没法挂载它,会卡在 ContainerCreating。