导读:本期聚焦于长沙SEO公司创作的《Kubernetes 集群 DNS 传播延迟导致创建失败怎么办?排查与处理方案详解》,敬请观看详情。Pod 创建后一直处于 ContainerCreating 状态,日志里反复出现 no such host 或者 server misbehaving,大概率是集群 DNS 传播延迟在作怪。本文围绕 Kubernetes 环境下 CoreDNS 的解析机制,分析 DNS 缓存、ndots 配置、NodeLocal DNSCache 等因素如何引发服务发现失败,并给出完整的排查路径:从 resolv.conf 检查、CoreDNS 日志分析到缓存参数调优。同时介绍常见规避手段,包括调整 DNS ConfigMap、启用 NodeLocal DNSCache、优化重试策略以及规范 headless Service 使用方式,帮助你在集群扩容或滚动更新时避免因 DNS 未及时生效而导致的创建失败问题。

在 Kubernetes 集群里,一个让人头疼的问题是:Pod 明明调度成功了,却长时间卡在 ContainerCreating 状态,describe 出来的事件里赫然写着 no such host。更多的时候,问题出在应用容器启动阶段去解析某个 Service 域名,而此时这条 DNS 记录还没有在集群内传播完成,解析失败后容器直接退出或初始化失败。这种 DNS 传播延迟看似随机、难以复现,其实背后有明确的机制可以分析。本文从 DNS 解析链路入手,梳理延迟产生的根因,并给出一套可落地的排查与处理方案。

Kubernetes 集群 DNS 传播延迟导致创建失败怎么办?排查与处理方案详解

先弄清楚集群 DNS 的解析链路

Kubernetes 默认通过 CoreDNS 提供服务发现能力。当一个容器发起域名解析时,请求会按照容器内 /etc/resolv.conf 的配置逐级进行:先查容器的 search 域,再查集群域 cluster.local,最后才查外部域名。kubelet 会为每个 Pod 注入类似下面的配置:

nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

这里的 ndots:5 是关键。它意味着只要域名中的点数少于 5 个,解析器都会先把 search 域依次拼接后再尝试,最后才走绝对查询。举例来说,容器里访问一个外部地址 api.ipipp.com,实际上会产生四次查询:api.ipipp.com.default.svc.cluster.localapi.ipipp.com.svc.cluster.localapi.ipipp.com.cluster.local,以及最终真正的 api.ipipp.com。每一次查询都是一次网络往返,任何一环超时,整体解析就会变慢甚至失败。

再看传播这一侧。Service 和 Endpoint 的变化由 kube-apiserver 写入 etcd,CoreDNS 通过 Watch 机制感知变化并更新内存中的缓存记录。正常情况下这个延迟在毫秒级别,但当 apiserver 负载高、网络抖动或者 CoreDNS Pod 本身资源不足时,Watch 事件的处理就会出现明显滞后。此外,客户端 libc 解析器自身没有缓存(Go 应用则依赖内部的 nss 解析逻辑),每一次失败都会真实地打到 CoreDNS 上,形成放大效应。

常见故障场景与排查路径

遇到创建失败时,不要急着重启,先按固定顺序收集证据。第一步用 kubectl describe pod 查看事件,确认失败发生在镜像拉取、卷挂载还是容器启动阶段。如果是应用日志中出现 Lookup XXX: no such host,基本可以锁定 DNS 问题。第二步进入一个同命名空间的调试 Pod 验证解析:

# 安装了 dnsutils 的调试容器
kubectl run -it --rm debug --image=registry.k8s.io/e2e-test-images/jessie-dnsutils -- sh

# 在容器内执行
nslookup my-svc.default.svc.cluster.local
cat /etc/resolv.conf

如果调试 Pod 能解析而业务 Pod 不能,多半是时序问题——业务 Pod 启动时 DNS 记录尚未生效,属于典型的传播延迟。反过来如果调试 Pod 也解析失败,就要看 CoreDNS 自身状态了:检查 CoreDNS Pod 是否 Running、是否发生 OOMKilled、kubectl logs -n kube-system -l k8s-app=kube-dns 中是否有 SERVFAIL 或循环代理报错。

还有一个容易被忽视的场景:headless Service 配合 StatefulSet 使用时,Pod 的 DNS 记录依赖 Pod 就绪。滚动更新过程中,旧 Pod 记录被删除、新 Pod 记录尚未写入,客户端拿到的可能是过期答案。另外,如果 CoreDNS 的 forward 插件把 cluster.local 也转发到了上游,会造成查询环,日志中会出现 loop 检测并直接退出的现象,这类问题在自建上游 DNS 的环境里特别常见。

从根源上缓解传播延迟

缓解方案分几个层次。最直接的是启用 NodeLocal DNSCache,它以 DaemonSet 形式在每个节点跑一个缓存实例,把 ClusterIP 的 DNS 查询改为本机 169.254.20.10 的 UDP 查询,减少 iptables NAT 和 conntrack 竞争,同时本地缓存能显著降低 CoreDNS 的压力:

# 官方提供的部署清单
kubectl apply -f nodelocaldns.yaml

# 验证节点上的监听
ss -lunp | grep 169.254.20.10

第二个层次是调优 CoreDNS 本身。给 CoreDNS 的 Pod 设置合理的 CPU 请求与限制(DNS 是 CPU 密集型服务,限流会直接推高查询延迟),并将副本数与节点规模匹配。Corefile 中可以开启日志与监控插件,配合 Prometheus 指标 coredns_dns_request_duration_seconds 观察延迟分布,判断瓶颈在集群内传播还是上游转发。

第三个层次在应用侧。对短域名的外部访问,显式写成 FQDN 并补上结尾的点,例如 api.ipipp.com.,可以跳过 search 域拼接,一次查询直达。也可以通过 Pod 的 dnsConfig 自定义 ndots 值:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: app
      image: my-app:latest
  dnsConfig:
    options:
      - name: ndots
        value: "2"

让应用对 DNS 延迟更有韧性

即便基础设施已经优化,传播延迟也不可能降到绝对的零,应用侧必须具备重试能力。以 Go 为例,默认的解析失败不会重试,建议在初始化逻辑里加入带退避的重试,或者直接使用 grpc 的内置重试与 backoff 机制。Java 应用要留意 JDK 8 及以下的 DNS 缓存默认值是 10 秒且失败不缓存,可以通过 networkaddress.cache.ttl 与安全属性调整。

对于依赖 headless Service 的场景,客户端应避免在启动瞬间依赖具体的 Pod 域名,改用 Service 域名加健康检查的方式,等解析稳定后再执行业务初始化。InitContainer 中做一次带重试的等待也是常见做法:

initContainers:
  - name: wait-for-dependency
    image: busybox:1.36
    command:
      - sh
      - -c
      - |
        until nslookup my-db.default.svc.cluster.local; do
          echo "waiting for dns record..."
          sleep 2
        done

最后一点经验之谈:变更窗口内的失败往往被误判为应用 Bug。在做大规模扩容、节点排水或 CoreDNS 升级时,提前确认 PDB(PodDisruptionBudget)配置,保证 CoreDNS 始终有可用副本;同时避免应用把启动时的首次解析失败视为致命错误。把 DNS 当作一个可能抖动的依赖来设计,才是对付传播延迟最稳妥的姿态。

Kubernetes DNSCoreDNSDNS传播延迟修改时间:2026-09-07 21:07:09

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260907/52446.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。