深色模式
K8s 网络不通排查
摘要:集群内访问不通时,先分清是"名字解析不到"、"Endpoint 为空"还是"转发不到 Pod"。本文按 Service → EndpointSlice → CoreDNS → kube-proxy → NetworkPolicy → CNI 的顺序逐层排查,每层都有明确判定命令。
适用环境
bash
kubectl version --short 2>/dev/null || kubectl version
kubectl get svc,pod -n <ns>
kubectl -n kube-system get pod -l k8s-app=kube-dns1
2
3
2
3
排障步骤
第 1 步:确认 Service 与后端选择器是否匹配
bash
kubectl get svc <svc> -n <ns> -o yaml
kubectl get pod -n <ns> -l <key>=<value> -o wide1
2
2
Service 的 selector 必须命中 Pod 标签,一个字符之差就会没有后端。
第 2 步:看 EndpointSlice 是否有后端
bash
kubectl get endpointslices -n <ns> -l kubernetes.io/service-name=<svc>
kubectl describe endpointslices -n <ns> -l kubernetes.io/service-name=<svc>1
2
2
Endpoint 为空说明没匹配到 Pod 或 Pod 未 Ready;有地址但访问不通则跳到第 5 步。
第 3 步:从 Pod 内部验证 DNS
bash
kubectl run -it --rm dns-test --image=busybox:1.36 --restart=Never -n <ns> -- \
nslookup <svc>.<ns>.svc.cluster.local
kubectl exec -it <pod> -n <ns> -- cat /etc/resolv.conf1
2
3
2
3
ClusterIP 不能 ping
ClusterIP 是 iptables/IPVS 里的虚拟地址,没有真实网卡,ping 必然失败。必须用端口探测验证。
第 4 步:检查 CoreDNS
bash
kubectl -n kube-system get pod -l k8s-app=kube-dns -o wide
kubectl -n kube-system logs -l k8s-app=kube-dns --tail=50
kubectl get cm coredns -n kube-system -o yaml1
2
3
2
3
第 5 步:检查 kube-proxy 转发规则
bash
kubectl -n kube-system get pod -l k8s-app=kube-proxy
iptables -t nat -S | grep -i <svc-cluster-ip> # iptables 模式
ipvsadm -Ln 2>/dev/null | grep -A 3 <svc-cluster-ip> # ipvs 模式1
2
3
2
3
第 6 步:检查 NetworkPolicy
bash
kubectl get networkpolicy -n <ns>
kubectl describe networkpolicy -n <ns>1
2
2
存在 NetworkPolicy 时默认拒绝
一旦命名空间内出现匹配某 Pod 的 NetworkPolicy,未显式放行的流量会被丢弃。新增策略后"突然不通"多源于此。
第 7 步:CNI 层面
bash
kubectl -n kube-system get pod -l k8s-app=calico-node -o wide 2>/dev/null
ip route show
ip link show | grep -iE 'cali|flannel|veth'1
2
3
2
3
跨节点不通时重点看 CNI 组件日志与节点间底层网络(179/BGP、4789/VXLAN 等端口)。
验证
bash
kubectl exec -it <pod> -n <ns> -- wget -qO- -T 3 http://<svc>:<port>/health
kubectl exec -it <pod> -n <ns> -- nslookup <svc>.<ns>.svc.cluster.local
kubectl get endpointslices -n <ns> -l kubernetes.io/service-name=<svc> -o yaml1
2
3
2
3
常见坑
Headless Service 没有 ClusterIP
clusterIP: None 时 DNS 直接返回 Pod IP 列表,行为与有 ClusterIP 完全不同。
容器内 ndots 拖慢解析
默认 ndots:5 会让集群内短域名先拼 search 域重试多次,表现为首次访问延迟高。
只测 Pod IP 通就以为 Service 通
Pod IP 直连绕过了 kube-proxy,两者故障域不同,必须分别验证。
清空 iptables 规则验证
iptables -F 会一次性移除 kube-proxy 写入的全部转发规则,导致整个集群网络瘫痪且需重启 kube-proxy 恢复。绝不可在生产执行。