现场是这样的。K8s 里跑 CentOS 基础镜像,Dockerfile 里 COPY 了 /etc/localtime,运行时又挂 -v /etc/localtime:/etc/localtime:ro,容器内 date 还是 UTC,日志时间差八小时。
真正麻烦的地方在于,几个原因的现象几乎一样。镜像里没有 /usr/share/zoneinfo,COPY 进来的是软链,指不到目标文件;宿主机 /etc/localtime 本身是符号链接,挂进容器后被解析成空文件;应用只读 TZ 环境变量,根本不看 /etc/localtime。
先看容器内的时间与时区文件
kubectl exec -it app-0 -- date; kubectl exec -it app-0 -- ls -l /etc/localtime
然后挂真实文件而不是软链
volumeMounts 里挂 /usr/share/zoneinfo/Asia/Shanghai 到 /etc/localtime
同时注入 TZ 变量
env: [{name: TZ, value: Asia/Shanghai}]
等前面都确认过,再确认容器内时区缩写
kubectl exec -it app-0 -- date +%Z
排查用的命令都是临时敲的,没有写成脚本,事后才整理。
手上没有现成的复现脚本,就照着线上请求手工拼了一个。
恢复的判定其实很直接。容器内 date 输出 CST 且带 +0800,应用日志时间与宿主机 date 一致,Pod 重建后依然生效(配置写在 Deployment 里)。
容易忽略的是,挂软链是容器时区最常见的坑,要挂 zoneinfo 下的实体文件;只改运行时挂载不改镜像,换环境时还会再犯一次。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
