首页/云/Kubernetes 速查/egress 策略下的 DNS 放行
网络与服务55 条

egress 策略下的 DNS 放行

出向默认拒绝后必须显式放行到 kube-dns/CoreDNS 的 53 端口(UDP/TCP),否则域名解析失败会被误判成「网络全挂」。

Kubernetes 速查云更新于 2026-10-13

为什么必须放行 DNS

NetworkPolicy 的出向策略是白名单:Pod 一旦被带 Egress 的策略选中,除显式放行的目标外,向任何地址发起的连接都会被丢弃,其中也包括发往集群 DNS 服务的 53 端口查询。这个疏漏的后果极具迷惑性——应用报的是「数据库连不上」「外部接口超时」,而根因是域名根本没解析出来。因此启用出向限制时,放行 DNS 必须与主策略同时上线。

基本信息

放行目标kube-system 中的 DNS 服务(标签 k8s-app: kube-dns)
协议端口UDP 53 与 TCP 53 都要放行
选择方式namespaceSelector 配 podSelector,避免写死地址
验证手段容器内解析集群服务名与外部域名各一次
常见误判把解析失败当成网络不通或中间件故障

放行 DNS 的标准写法

放行 DNS 的标准写法
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: prod
spec:
  podSelector: {}
  policyTypes: ['Egress']
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system   # 命名空间标签,集群自带的稳定标识
          podSelector:
            matchLabels:
              k8s-app: kube-dns                         # 指向 DNS 服务的工作负载
      ports:
        - {protocol: UDP, port: 53}
        - {protocol: TCP, port: 53}

典型使用场景

  • 上线出向限制:在默认拒绝之前先准备好 DNS 放行,避免业务同时失去解析能力
  • 排查应用报错:应用说连接超时,先确认解析是否成功,再谈连接层
  • 多命名空间治理:为每个命名空间准备统一的 DNS 放行策略模板,减少逐环境重写
  • DNS 组件迁移:从 kube-dns 换到 CoreDNS 或更换标签时,同步更新选择器
  • 性能优化:放行后仍解析缓慢,属于解析行为层面的调优,与策略无关

验证解析是否真的通了

验证解析是否真的通了
kubectl exec -it web-x -n prod -- nslookup kubernetes.default        # 集群内服务名
kubectl exec -it web-x -n prod -- nslookup api.example.com           # 外部域名
kubectl exec -it web-x -n prod -- cat /etc/resolv.conf               # 确认解析器地址与 search 域
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=30 | grep -i -E 'deny|refused|blocked'
kubectl get networkpolicy -n prod                                    # 复核命名空间内全部策略

现象与判定

现象可能原因判定方法
集群内服务名解析失败未放行 DNS 出向换用 Pod IP 直连是否可达,可达即解析问题
外部域名解析失败但内网正常上游 DNS 转发被拦解析器地址与 DNS 组件的上游配置
偶发解析失败只放行 UDP 53,大响应被截断后 TCP 重试被拒补放 TCP 53 后观察是否消失
Pod 启动后一律解析失败DNS 服务本身未就绪查看 DNS 组件副本与日志
kube-system 命名空间自带 kubernetes.io/metadata.name 标签,可直接用命名空间选择器定位,比写死 ClusterIP 稳——DNS 服务重建后地址会变,写死的选择器会立刻失效。
UDP 53 是常规查询通道,响应超过单包限制时解析器会改用 TCP 53 重试。只放 UDP 的策略在正常情况下看不出问题,遇到大响应或 DNSSEC 类查询就会偶发失败,属于难以复现的隐性故障。

易错点

  • 启用出向默认拒绝却漏放 DNS:整个命名空间的域名解析同时失效,表象是各种下游超时,排查方向容易被带偏
  • 只放行 UDP 53 不放 TCP 53:大响应走 TCP 重试时被拒,出现偶发且难复现的解析失败
  • 用 ClusterIP 写死放行目标:DNS 服务重建换地址后策略失效,应用再次解析失败
  • 把解析失败当成中间件故障:先去应用侧翻配置,实际根因在策略层,浪费大量排查时间

数据来源与参考

  • Kubernetes 官方文档 · NetworkPolicy / DNS 说明(DNS for Services and Pods)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌