K8s 集群里一个 CentOS 基础镜像的 Pod 解析内网域名失败,进容器 vi /etc/resolv.conf 提示 Read-only file system,退出后配置也没变化。

一开始怀疑是「镜像里 resolv.conf 是符号链接,指向另一个被挂载覆盖的路径」,查了一圈,方向不对。

原因不止一个,得分开看。kubelet 用 bind mount 把文件挂进容器,挂载点是只读的,容器内无法改写。另一种情况是DNS 配置由 Pod 的 dnsPolicy 决定,改容器内文件重启即被覆盖。

少数情况下是容器以 readOnlyRootFilesystem 运行,整层文件系统都不可写。

上来先看这个文件的挂载来源

findmnt -T /etc/resolv.conf -o TARGET,SOURCE,OPTIONS

从 Pod 侧确认 DNS 策略

kubectl get pod app-0 -o jsonpath='{.spec.dnsPolicy}{"\n"}'

接着改用 dnsConfig 追加内网域名服务器

kubectl patch deploy app --type merge -p '{"spec":{"template":{"spec":{"dnsConfig":{"nameservers":["10.0.0.2"]}}}}}'

末了在容器内验证解析结果

cat /etc/resolv.conf && getent hosts db.internal

报错是间歇性的,我蹲守了半小时才抓到一次完整现场。

恢复的判定其实很直接。kubectl exec 进容器后 /etc/resolv.conf 里出现指定的 nameserver,getent hosts 能解析出内网地址,应用日志不再报解析超时。

提醒一点。不要为了改一个文件去删 readOnlyRootFilesystem,这层保护挡过不少入侵;DNS 这类注入项一律从工作负载声明改。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189