自建 K8s 1.25 集群,CentOS 7.9 节点,业务 Pod 访问 Service 名偶尔超时,kubectl logs coredns 报 plugin/forward: no upstreams available,节点 resolv.conf 里的上游是内网 10.20.0.2,在宿主机 dig 这个地址是通的。
真正麻烦的地方在于,几个原因的现象几乎一样。CoreDNS 的 forward 插件指向了一个不通的 upstream 地址;节点 resolv.conf 被 NetworkManager 改过,CoreDNS 读到的是旧值;上游 DNS 只允许特定网段递归,Pod 网段不在白名单里;CoreDNS 副本太少,请求排队超时后被当成上游不可用。
第一件事是看 CoreDNS 实际加载的转发配置
kubectl -n kube-system get cm coredns -o yaml | grep -A5 forward
从 Pod 侧验证域名解析链路
kubectl run dnstest --rm -it --image=busybox --restart=Never -- nslookup kubernetes.default
修正 Corefile 里的 forward 地址
kubectl -n kube-system edit cm coredns
滚动重启 CoreDNS 让配置生效
kubectl -n kube-system rollout restart deploy coredns
中途换过一次思路,把范围缩到最小的那一层,反而快了。
中间停过一次,把已经改的东西回滚干净,再重新来一遍。
同样的操作我在测试机上先走了一遍,线上只做验证过的部分。
别只看报错消失,验证要多做一步。Pod 内 nslookup kubernetes.default 和外部域名都能解析,CoreDNS 日志不再出现 no upstreams,解析 P99 回到 10ms 以内。
提醒一点。CoreDNS 读的是节点 resolv.conf 的副本,改完宿主机 DNS 要重启 CoreDNS,否则配置不会自动跟着更新。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
