记录一下那天晚上的排查过程。K8s 1.24 上一套 nginx 的配置放在 ConfigMap 里用 volume 挂进 Pod,kubectl edit 改完 upstream 地址,进容器 cat 还是旧值,重启容器后才生效。

刚开始盯着「应用只在启动时读一次配置文件,文件变了也不 reload」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。subPath 挂载不会跟随 ConfigMap 更新,这是 kubelet 的已知行为。还有一种是kubelet 的同步周期默认一分钟,改完立刻看往往还没刷到。

还有一种情况,改了 ConfigMap 但改的是另一个命名空间里的同名对象。

第一件事是确认挂载方式里有没有 subPath

kubectl get pod web-0 -o jsonpath='{.spec.volumes[*].configMap.name}'

随后看容器内文件的时间戳是否刷新

kubectl exec web-0 -- ls -l --time-style=full-iso /etc/nginx/conf.d/

接着用 symlink 方式挂目录后触发应用重载

kubectl exec web-0 -- nginx -s reload

等前面都确认过,再确认 ConfigMap 的 resourceVersion 已变

kubectl get cm nginx-conf -o jsonpath='{.metadata.resourceVersion}'

别只看报错消失,验证要多做一步。容器内配置文件的 mtime 与 ConfigMap 更新时刻一致,nginx -s reload 后 upstream 指向新地址,访问日志落到新后端。

容易忽略的是,要热更新就别用 subPath,它把文件绑死在一个 inode 上;改完记得让应用 reload,nginx 不会自己读新配置。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189