Kubernetes网络与CNI生产排障完整指南
Kubernetes网络故障经常表现为“Pod能启动但访问超时”“同节点正常、跨节点不通”“Service偶发失败”或“域名解析很慢”。这些现象可能来自应用监听、容器网络命名空间、CNI数据面、节点路由、隧道、NetworkPolicy、kube-proxy、CoreDNS、负载均衡器或底层网络。直接重启Pod或重装CNI,往往只会暂时改变故障位置。
本文建立一条从应用到物理网络的排查路径,并分别说明Calico、Cilium、Flannel及常见Service、DNS、MTU和conntrack问题。命令与字段可能随版本和部署方式变化,生产操作前应核对当前Kubernetes与CNI官方文档。
一、先画清楚数据包路径
排障前先确认访问类型,因为不同流量经过的组件不同。
| 场景 | 典型路径 | 重点检查 |
|---|---|---|
| Pod访问同节点Pod | veth、网桥或eBPF数据面 | 容器路由、CNI端点、策略 |
| Pod访问跨节点Pod | veth、节点路由、隧道或BGP | MTU、路由、封装、防火墙 |
| Pod访问ClusterIP | Service规则或eBPF负载均衡 | EndpointSlice、kube-proxy/Cilium |
| 外部访问NodePort | 节点入口、Service转发、Pod | externalTrafficPolicy、SNAT |
| 外部访问LoadBalancer | 云LB/硬件LB、节点、Service | 健康检查、源地址、路由 |
| Pod解析Service域名 | resolv.conf、CoreDNS Service、CoreDNS Pod | ndots、上游DNS、EndpointSlice |
| Pod访问公网 | Pod路由、节点SNAT、出口防火墙 | 默认路由、NAT、DNS、代理 |
先记录源Pod、目标名称、目标IP、端口、协议、源节点、目标节点和故障时间。没有这些信息,“网络不通”无法形成可验证的假设。
二、建立分层排障顺序
推荐按以下顺序推进:
- 应用是否监听正确地址与端口;
- Pod网络命名空间内的地址、路由、DNS是否正确;
- 目标Pod IP能否访问;
- 同节点与跨节点结果是否不同;
- Service是否有正确EndpointSlice;
- NetworkPolicy和安全策略是否放行;
- CNI端点、路由、隧道或eBPF状态是否健康;
- 节点内核转发、conntrack和防火墙是否异常;
- 交换网络、VLAN、路由、ACL和MTU是否匹配。
每一步都保留证据,不要同时修改多个组件。恢复后还要解释“为什么恢复”,否则同类故障会再次出现。
三、第一步:确认应用而不是网络
进入目标Pod检查监听:
kubectl -n payments get pod -o wide
kubectl -n payments exec api-0 -- ss -lntup
kubectl -n payments exec api-0 -- curl -sv http://127.0.0.1:8080/health
kubectl -n payments logs api-0 --since=15m
常见问题包括:
- 应用只监听
127.0.0.1,其他Pod无法通过Pod IP访问; - Service的
targetPort与实际监听端口不一致; - HTTPS服务被当作HTTP探测;
- 应用线程池、连接池耗尽,被误判为网络超时;
- readiness失败导致端点被移出,但应用日志没有明显错误;
- Pod使用hostNetwork,排障路径与普通Pod不同。
如果容器镜像没有诊断工具,可启动临时调试容器:
kubectl debug -n payments pod/api-0 -it \
--image=nicolaka/netshoot --target=api
调试镜像必须经过安全审查并限制权限,不要长期留在生产环境。
四、检查Pod地址、路由和网络命名空间
kubectl -n payments exec api-0 -- ip addr
kubectl -n payments exec api-0 -- ip route
kubectl -n payments exec api-0 -- cat /etc/resolv.conf
kubectl -n payments exec api-0 -- ip neigh
需要确认:
- Pod IP属于预期Pod CIDR;
- 默认路由指向正确的容器网关;
- veth对端存在且处于UP;
- 没有重复IP或错误静态路由;
/etc/resolv.conf中的nameserver和search域符合集群配置;- 节点上的PodCIDR与控制面分配一致。
节点侧可用ip link、ip route、ip rule和nsenter检查。不要随意删除veth、路由或网络命名空间,这会直接中断业务Pod。
五、用对照实验快速缩小范围
选择同一目标,分别测试:
- 源Pod访问自己;
- 同节点Pod访问目标Pod IP;
- 跨节点Pod访问目标Pod IP;
- 访问Service ClusterIP;
- 访问Service DNS名称;
- 节点访问目标Pod IP;
- 外部客户端访问入口。
kubectl -n payments run netcheck --rm -it \
--image=nicolaka/netshoot -- /bin/bash
curl -m 3 -sv http://10.244.3.21:8080/health
curl -m 3 -sv http://10.96.14.8:8080/health
dig +time=2 +tries=1 api.payments.svc.cluster.local
如果同节点正常而跨节点失败,优先检查节点间路由、隧道、BGP、UDP封装端口和MTU。如果Pod IP正常而ClusterIP失败,重点转向Service数据面。如果ClusterIP正常而域名失败,则重点检查CoreDNS和Pod DNS配置。
六、Service与EndpointSlice排障
kubectl -n payments get svc api -o yaml
kubectl -n payments get endpointslice \
-l kubernetes.io/service-name=api -o wide
kubectl -n payments get pod -l app=api --show-labels
kubectl -n payments describe pod api-0
核对:
- selector是否匹配目标Pod;
- EndpointSlice地址和端口是否正确;
- ready、serving、terminating条件是否符合预期;
- Service的
port、targetPort、协议和名称是否匹配; - 目标Pod是否因readiness失败而未进入端点;
- 双栈集群中的addressType是否正确;
- 无selector Service是否由外部系统正确维护端点。
端点正确但ClusterIP失败时,继续检查kube-proxy模式或CNI的Service实现。
七、kube-proxy与Service数据面
传统集群可能使用iptables、IPVS或nftables模式;部分Cilium部署会替代kube-proxy。先确认实际模式,不要用错误工具排查。
kubectl -n kube-system get ds kube-proxy -o yaml
kubectl -n kube-system logs ds/kube-proxy --since=20m
# iptables模式示例
iptables-save | grep KUBE-SVC
# IPVS模式示例
ipvsadm -Ln
关注:
- kube-proxy是否在全部节点运行;
- 规则同步是否报错;
- 节点是否混用不同后端;
- IPVS虚拟服务是否存在真实服务器;
- firewalld、第三方安全软件是否重写规则;
- CNI替代kube-proxy时,eBPF Service表是否同步。
不要把“iptables里没看到规则”直接当作故障,先确认集群是否使用nftables、IPVS或eBPF。
八、NetworkPolicy必须按双向理解
一旦某方向被策略选中,未显式允许的流量可能被拒绝。排障时同时看源端egress和目标端ingress。
kubectl get networkpolicy -A
kubectl -n payments describe networkpolicy
kubectl -n payments get pod --show-labels
常见误区:
- namespaceSelector匹配的是命名空间标签,不是名称;
- podSelector为空表示命名空间内全部Pod;
- 放行TCP业务端口但忘记DNS的UDP/TCP 53;
- 只放行ClusterIP,实际策略看到的是Pod IP;
- 节点、本地DNS缓存或hostNetwork流量的处理方式因CNI而异;
- 策略资源创建成功不代表所用CNI实现了对应能力。
建议为关键策略建立自动化连通性测试,覆盖允许路径和拒绝路径,并在发布前验证。
九、Calico排障要点
Calico常见数据面包括BGP路由、IP-in-IP、VXLAN和eBPF。先确认IPPool与封装方式。
calicoctl node status
calicoctl get ippool -o wide
calicoctl get workloadendpoint -A
calicoctl get bgpconfiguration -o yaml
kubectl -n calico-system logs ds/calico-node --since=20m
重点检查:
- BGP邻居是否Established;
- 节点PodCIDR路由是否发布和接收;
- IPPool的CIDR、NAT、封装和节点选择器;
- Felix是否能编程路由与策略;
- VXLAN或IPIP封装是否被中间防火墙阻断;
- route reflector配置是否造成部分节点缺路由;
- 主机端点策略是否意外影响节点流量。
BGP会话正常不等于业务路由一定正确,还要比对具体目标Pod IP的路由下一跳。
十、Cilium排障要点
Cilium使用eBPF实现网络、安全策略及可选的Service负载均衡。常用检查:
cilium status --wait
cilium connectivity test
kubectl -n kube-system exec ds/cilium -- cilium-dbg status
kubectl -n kube-system exec ds/cilium -- cilium-dbg endpoint list
kubectl -n kube-system exec ds/cilium -- cilium-dbg service list
kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf lb list
Hubble可观察丢弃点:
hubble observe --from-pod payments/client \
--to-pod payments/api --verdict DROPPED
hubble observe --namespace payments --since 10m
重点检查agent、operator与cilium-envoy状态、endpoint身份、policy verdict、Service后端、tunnel/native routing、kube-proxy replacement与内核能力。Hubble Relay不可用可能只是观测面故障,不能直接等同于数据面故障。
十一、Flannel排障要点
Flannel常见后端包括VXLAN和host-gw。检查:
kubectl -n kube-flannel get pod -o wide
kubectl -n kube-flannel logs ds/kube-flannel-ds --since=20m
ip link show flannel.1
ip route | grep 10.244
cat /run/flannel/subnet.env
VXLAN模式关注VTEP、FDB、UDP 8472和MTU;host-gw要求节点在可直接路由的二层或三层网络中。Flannel主要负责基础连通性,NetworkPolicy能力通常需要其他组件实现。
十二、MTU问题为什么最隐蔽
小包正常、大包失败,TLS握手或文件传输卡住,是典型MTU线索。封装会减少可用MTU,底层1500字节时,VXLAN、IP-in-IP、WireGuard等都要预留头部空间。
ip link show
tracepath 10.244.3.21
ping -M do -s 1400 10.244.3.21
ping -M do -s 1372 10.244.3.21
排查时比对物理网卡、bond、VLAN、隧道、CNI、Pod veth和云网络的MTU,并确认ICMP Fragmentation Needed未被过滤。修改MTU通常需要重建Pod或滚动节点,应先在测试节点验证。
十三、conntrack、端口耗尽与丢包
高并发Service访问可能触发conntrack表满、NAT端口耗尽或TIME_WAIT堆积。
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
conntrack -S
ss -s
netstat -s
dmesg -T | grep -i conntrack
应结合连接创建率、持续时间、客户端复用、SNAT规模和节点容量判断。直接扩大表上限会增加内存消耗,必须同时修正连接池、超时和流量分布。
十四、CoreDNS与域名解析排障
kubectl -n kube-system get svc kube-dns
kubectl -n kube-system get endpointslice \
-l kubernetes.io/service-name=kube-dns
kubectl -n kube-system logs -l k8s-app=kube-dns --since=20m
kubectl -n payments exec netcheck -- cat /etc/resolv.conf
kubectl -n payments exec netcheck -- \
dig +stats api.payments.svc.cluster.local
重点检查CoreDNS副本分布、Service端点、Corefile、上游DNS、缓存、Pod的ndots、NodeLocal DNSCache、UDP分片和TCP 53。短名称查询慢时,用完整域名对照测试。
十五、抓包应在正确位置进行
同一流量可在Pod、veth、CNI网桥、隧道和物理网卡上抓包:
tcpdump -ni any host 10.244.3.21 and port 8080
tcpdump -ni eth0 udp port 4789
tcpdump -ni flannel.1
使用五元组、TCP序列号和时间戳关联各位置。源Pod发出但节点物理口没有,重点看节点数据面;源节点发出但目标节点没收到,重点看底层网络;目标节点收到但Pod没收到,重点看目标CNI;请求与响应都存在,则检查回程、SNAT或客户端。
抓包可能包含账号、Token、Cookie或业务数据,应限制范围、及时删除并按敏感日志管理。
十六、双栈与IPv6特别检查
双栈集群需确认Pod、Service和节点CIDR族一致,EndpointSlice addressType正确,CNI同时编程IPv4与IPv6路由及策略,节点IPv6转发和邻居发现正常,应用监听正确地址,外部负载均衡器真正支持双栈。分别指定地址族测试,不要用IPv4正常证明IPv6正常。
十七、生产变更与恢复策略
网络组件属于集群基础设施,变更前准备配置与CRD备份、单节点灰度、Pod驱逐预算、保底访问路径、回滚镜像与参数、连通性探针及停止条件。升级CNI前核对Kubernetes、内核、iptables/nftables、eBPF和封装兼容矩阵,不要在同一窗口同时升级内核、CNI和kube-proxy。
十八、监控与告警
建议覆盖:
- CNI agent/operator可用性与endpoint未就绪数;
- policy drop、BGP邻居和路由数量;
- 隧道丢包、错误和重传;
- CoreDNS请求率、延迟、SERVFAIL和缓存命中;
- conntrack使用率;
- 节点网络错误、丢包和队列丢弃;
- Service无端点;
- 跨节点、跨可用区和DNS合成探测。
单纯监控“Pod Running”无法发现数据面黑洞,合成探测必须覆盖真实路径。
十九、常见误区
重启Pod后恢复,所以是应用问题
重建Pod可能改变节点、IP、路由、策略身份和conntrack状态,不能据此判断根因。
ping不通就是网络故障
ICMP可能被策略禁止,而TCP业务正常。测试应使用真实协议和端口。
Service有ClusterIP就一定有后端
必须检查EndpointSlice和ready条件。
临时关闭防火墙最省事
这会扩大暴露面并破坏证据,应定位具体链、规则、端口和方向。
二十、故障Runbook模板
- 记录告警、业务影响、起始时间和变更;
- 固定源、目标、协议和复现命令;
- 验证应用监听与Pod本地访问;
- 对照同节点、跨节点、Pod IP、Service和DNS;
- 检查EndpointSlice和NetworkPolicy;
- 检查CNI端点、路由、隧道或eBPF状态;
- 检查MTU、conntrack、节点防火墙和底层网络;
- 抓包证明丢包位置;
- 选择最小风险恢复动作;
- 补充监控、自动化测试和复盘。
二十一、生产验收清单
- [ ] Pod CIDR、Service CIDR、节点网段不存在重叠;
- [ ] CNI模式、封装、路由和MTU有基线记录;
- [ ] 同节点、跨节点、Service、DNS和出口探测正常;
- [ ] NetworkPolicy同时覆盖业务和DNS依赖;
- [ ] CoreDNS副本分散且有延迟、错误率监控;
- [ ] conntrack容量和节点网络指标有告警;
- [ ] CNI组件具备版本兼容、备份和回滚方案;
- [ ] 双栈环境分别验证IPv4与IPv6;
- [ ] 关键链路有抓包和故障Runbook;
- [ ] 调试权限和敏感数据处理符合安全要求。
二十二、官方参考
- Kubernetes集群网络
- Kubernetes调试Service
- Kubernetes调试DNS解析
- Kubernetes NetworkPolicy
- Calico Documentation
- Cilium Troubleshooting
- Flannel Documentation
高质量网络排障不是背命令,而是能把数据包路径拆成可验证的阶段。只要每一步都有对照实验和证据,即使底层使用不同CNI,也能稳定定位故障边界。