K8s Pod 网络问题诊断流程从 DNS 解析失败到跨节点通信异常的排障实录一、Pod 网络问题为什么这么难排查K8s 网络问题的排查难度在所有运维问题中排前三原因只有一个——网络链路太长故障点太多。一个简单的 Pod 间通信数据包要经过Pod 网络命名空间 → veth pair → cni0 网桥 → iptables/nftables 规则 → 节点路由 → 物理网卡 → 交换机 → 对端节点 → 反向路径。任何一个环节出问题表现都是网络不通。更让人头疼的是K8s 网络问题往往不是稳定复现的。DNS 解析偶尔超时、跨节点通信间歇性丢包、Service 访问时断时续——这些间歇性问题比完全不通更难定位因为你排查时它可能已经恢复了。我在生产环境踩过的网络坑包括CoreDNS 的 ndots 导致域名解析走了错误路径、iptables 规则冲突导致流量被意外 DROP、CNI 插件升级后节点路由表没更新、kube-proxy 的 IPVS 模式在特定内核版本下有 bug。每一个都是几小时的排查最后发现原因往往很简单。这篇文章的目标是给出一套系统化的 K8s Pod 网络诊断流程让你遇到网络问题时不再靠猜。二、Pod 网络问题分类与诊断流程flowchart TD A[Pod 网络异常] -- B{能否访问 ClusterIP?} B --|否| C{能否访问 Pod IP?} B --|是| D{DNS 解析正常?} C --|否| E{同节点 Pod 间通信?} C --|是| F[Service/kube-proxy 问题] E --|否| G[CNI/节点网络问题] E --|是| H[跨节点路由问题] D --|否| I[CoreDNS 问题] D --|是| J{能否访问外部网络?} J --|否| K[出站 NAT/网关问题] J --|是| L[应用层问题] G -- G1[检查 CNI 插件状态] G -- G2[检查 veth pair] G -- G3[检查节点路由表] H -- H1[检查节点间路由] H -- H2[检查网络策略] H -- H3[检查防火墙规则] I -- I1[检查 CoreDNS Pod 状态] I -- I2[检查 resolv.conf] I -- I3[检查 ndots 配置] F -- F1[检查 kube-proxy] F -- F2[检查 iptables/IPVS 规则] F -- F3[检查 endpoints]这个流程图的核心逻辑是从内到外逐层排查。先确认 Pod 本身的网络栈是否正常再检查 Service 层然后是 DNS最后是外部网络。每一层都有对应的诊断命令和常见原因。三、逐层诊断的实战命令3.1 第一层Pod 内部网络栈#!/bin/bash # pod-network-debug.sh - Pod 网络诊断脚本 # 用法: ./pod-network-debug.sh namespace pod-name NS$1 POD$2 echo 1. Pod 基本网络信息 kubectl exec -n $NS $POD -- ip addr show kubectl exec -n $NS $POD -- ip route show echo echo 2. Pod DNS 配置 kubectl exec -n $NS $POD -- cat /etc/resolv.conf echo echo 3. 本地回环测试 kubectl exec -n $NS $POD -- ping -c 2 127.0.0.1 echo echo 4. 同节点 Pod 通信测试 # 获取同节点其他 Pod IP NODE$(kubectl get pod -n $NS $POD -o jsonpath{.spec.nodeName}) echo 当前 Pod 所在节点: $NODE # 获取同节点其他 Pod PODS_ON_NODE$(kubectl get pods -n $NS -o wide --no-headers | \ awk -v node$NODE $7 node {print $1, $6}) echo 同节点 Pod 列表: echo $PODS_ON_NODE # 测试同节点 Pod 间通信 while read -r pod_name pod_ip; do if [ $pod_name ! $POD ]; then echo 测试与 $pod_name ($pod_ip) 的连通性: kubectl exec -n $NS $POD -- ping -c 2 -W 3 $pod_ip fi done $PODS_ON_NODE echo echo 5. 跨节点 Pod 通信测试 # 获取不同节点的 Pod CROSS_PODS$(kubectl get pods -n $NS -o wide --no-headers | \ awk -v node$NODE $7 ! node {print $1, $6} | head -3) while read -r pod_name pod_ip; do echo 测试与 $pod_name ($pod_ip) 的跨节点连通性: kubectl exec -n $NS $POD -- ping -c 2 -W 3 $pod_ip done $CROSS_PODS echo echo 6. Service 连通性测试 # 测试 ClusterIP SVC_IP$(kubectl get svc -n $NS -o jsonpath{.items[0].spec.clusterIP}) echo 测试 ClusterIP: $SVC_IP kubectl exec -n $NS $POD -- curl -sS -m 5 http://$SVC_IP || echo ClusterIP 不可达 echo echo 7. DNS 解析测试 kubectl exec -n $NS $POD -- nslookup kubernetes.default.svc.cluster.local || \ echo DNS 解析失败 echo echo 8. 外部网络测试 kubectl exec -n $NS $POD -- curl -sS -m 5 https://httpbin.org/ip || \ echo 外部网络不可达3.2 第二层DNS 问题深度排查DNS 问题是 K8s 网络故障中最常见的类型占我处理过的网络问题的 40% 以上。# DNS 问题排查清单 # 1. 检查 CoreDNS Pod 状态 kubectl get pods -n kube-system -l k8s-appkube-dns -o wide # 2. 查看 CoreDNS 日志 kubectl logs -n kube-system -l k8s-appkube-dns --tail50 # 3. 检查 CoreDNS 配置 kubectl get configmap coredns -n kube-system -o yaml # 4. 从问题 Pod 测试 DNS 解析带详细输出 kubectl exec -n $NS $POD -- nslookup -debug kubernetes.default.svc.cluster.local # 5. 检查 ndots 问题最常见的 DNS 性能问题 # ndots5 意味着少于 5 个点的域名会先尝试追加集群域名后缀 # 例如: mysql 会依次尝试: # mysql.default.svc.cluster.local # mysql.svc.cluster.local # mysql.cluster.local # mysql.search domain # mysql # 每次尝试都是一次 DNS 查询5 次查询才找到结果 # 6. 修复 ndots 问题在 Pod spec 中覆盖 dnsConfig# 修复 ndots 问题的 Pod 配置 apiVersion: v1 kind: Pod metadata: name: app-with-dns-fix spec: containers: - name: app image: app:latest dnsConfig: options: - name: ndots value: 1 # 只有点数 1 的域名才追加后缀 - name: timeout value: 2 # DNS 查询超时 2 秒 - name: attempts value: 2 # 最多重试 2 次 dnsPolicy: ClusterFirst3.3 第三层Service 和 kube-proxy 问题# Service/kube-proxy 问题排查 # 1. 检查 Service Endpoints kubectl get endpoints -n $NS # 如果 Endpoints 为空说明没有 Pod 匹配 Service 的 selector # 2. 检查 kube-proxy 模式和状态 kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode # 3. 检查 iptables 规则iptables 模式 # 在节点上执行 sudo iptables -t nat -L KUBE-SERVICES -n --line-numbers sudo iptables -t nat -L KUBE-SVC-hash -n --line-numbers # 4. 检查 IPVS 规则IPVS 模式 sudo ipvsadm -Ln | grep ClusterIP # 5. 检查 kube-proxy 日志 kubectl logs -n kube-system -l k8s-appkube-proxy --tail50 # 6. Conntrack 表溢出高频问题 sudo cat /proc/sys/net/netfilter/nf_conntrack_count sudo cat /proc/sys/net/netfilter/nf_conntrack_max # 如果 count 接近 max需要调大 max 值 # 7. 修复 conntrack 溢出 sudo sysctl -w net.netfilter.nf_conntrack_max131072 # 持久化 echo net.netfilter.nf_conntrack_max131072 | \ sudo tee -a /etc/sysctl.d/99-k8s-network.conf3.4 第四层CNI 和节点网络问题# CNI 问题排查 # 1. 检查 CNI 插件状态 ls /etc/cni/net.d/ ls /opt/cni/bin/ # 2. 检查节点路由表 ip route show | grep -E 10\.(244|32)\. # 3. 检查 veth pair # 在节点上找到 Pod 对应的 veth POD_IFINDEX$(kubectl exec -n $NS $POD -- cat /sys/class/net/eth0/ifindex) VETH$(ip link | grep -B1 master cni0 | grep -oP ^\d: \K[^]) echo Pod eth0 ifindex: $POD_IFINDEX echo Host veth: $VETH # 4. 检查网络策略 kubectl get networkpolicy -n $NS # 5. 抓包定位 # 在节点上抓 Pod 的流量 NODE_IP$(kubectl get node $NODE -o jsonpath{.status.addresses[0].address}) POD_IP$(kubectl get pod -n $NS $POD -o jsonpath{.status.podIP}) sudo tcpdump -i any -nn host $POD_IP and port 80 -c 100 # 6. 检查节点防火墙 sudo iptables -L FORWARD -n -v sudo nft list ruleset 2/dev/null四、常见网络问题的根因与修复4.1 DNS 解析间歇性超时根因CoreDNS 的 Pod 数量不足或资源限制过低高并发时 DNS 查询排队。修复增加 CoreDNS 副本数调大 CoreDNS 的 CPU/内存限制开启 CoreDNS 的 autopath 插件减少 DNS 查询次数在业务 Pod 中配置 ndots1。4.2 跨节点 Pod 通信丢包根因节点路由表不完整或 CNI 配置不一致。常见于节点扩容后 CNI 插件没有正确初始化新节点的路由。修复重启 CNI Pod如 Calico 的 calico-node手动添加缺失的路由检查节点的 IP 转发是否开启sysctl net.ipv4.ip_forward。4.3 Service 访问时断时续根因kube-proxy 的 iptables 规则冲突或 conntrack 表溢出。在大量 Service 的集群中iptables 模式的性能会显著下降。修复切换到 IPVS 模式性能更好调大 conntrack 表上限检查是否有重复的 iptables 规则。4.4 Pod 无法访问外部网络根因出站 NAT 规则缺失或节点网关配置错误。部分 CNI 插件需要手动配置 NAT 规则。修复检查节点的 iptables NAT 规则POSTROUTING 链确认节点的默认网关正确检查云厂商的安全组是否放行了出站流量。五、总结K8s Pod 网络问题的排查核心方法论就四个字逐层定位。从 Pod 内部网络栈开始到 DNS、Service、CNI、节点网络每一层都有对应的诊断命令和常见根因。实战中最重要的一点先确认故障范围再深入排查。是单个 Pod 的问题还是整个节点的问题是 DNS 问题还是网络连通性问题是入站问题还是出站问题范围缩小了排查效率才能提上来。建议把诊断脚本做成 K8s Job 或 DaemonSet集群里随时可以跑。网络问题不会给你时间慢慢敲命令提前准备好工具出问题时才能快速定位。最后网络问题的最佳解决方案不是排查而是预防。做好 CNI 插件的版本管理、CoreDNS 的资源规划、网络策略的测试覆盖大部分网络问题可以在上线前被发现。