系列导航
本系列从 Pod 网络连通入手,逐步展开到 K8s 网络全景。
① 概念 → ② Flannel → ③ Calico → ④ 流量路径 → ⑤ Cilium → ⑥ 对比 → ⑦ 排障 ‖ ⑧ 开发 → ⑨ 多网卡 → ⑩ AI 演进
| 顺序 | 文章 | 定位 |
|---|
| ① | 概念与入门 | 基础——主机网络、Docker 网络、CNI 标准、方案分类树 |
| ② | Flannel 详解 | CNI 实现——Overlay 封装(UDP/VXLAN/HostGW)与抓包 |
| ③ | Calico 详解 | CNI 实现——三层路由(BGP/IPIP)+ NetworkPolicy |
| ④ | 流量路径全解析 | 全貌——Pod/Service/Ingress/Egress,揭示 CNI 的边界 |
| ⑤ | Cilium 详解 | 超越 CNI——eBPF 统一 Pod + Service + L7 + Hubble |
| ⑥ | 插件对比与选型 | 选型——5 插件横向对比 + 决策树 |
| ⑦ | 本篇 - 排障思路与常用命令 | 运维——工具链 + 场景排查 + 性能 |
| — | 核心路径 ↑ | 扩展展望 ↓ |
| ⑧ | CNI 插件开发指南 | 扩展——基于 CNI 规范开发自定义插件 |
| ⑨ | 多网卡方案详解 | 进阶——Multus + SR-IOV/ipvlan 多网口实战 |
| ⑩ | AI 时代网络演进 | 展望——GPU 网络、eBPF 加速、未来方向 |
网络问题排障的核心思路:从三层往上下验证——先确定 IP 通不通,再查策略拦没拦,最后看封装对不对。
1. 基础诊断工具链
| 工具 | 用途 | 关键示例 |
|---|
ip route | 检查路由表是否包含目标 Pod 子网的路由 | ip route get <目标Pod IP> |
ip neigh / arp -n | 检查 ARP 表是否有下一跳 MAC | ip neigh show dev eth0 |
bridge fdb | VXLAN/VTEP 模式检查 FDB 表 | bridge fdb show dev flannel.1 |
iptables -t nat -L -n -v | 检查 kube-proxy Service DNAT 规则 | 留意计数器(pkts/bytes)是否增长 |
ipvsadm -Ln | IPVS 模式检查 Service 后端 | ipvsadm -Ln --stats |
conntrack -L | 检查连接跟踪表 | conntrack -L -s <Pod IP> |
ss -tunap | 检查连接状态和进程 | ss -tunap | grep <port> |
ip netns | 操作/查看 network namespace | ip netns exec <ns> ip a |
2. 按现象排查
2.1 Pod 启动后无网络(IP 未分配)
1
2
3
4
5
6
7
8
9
| # 1. 检查 Pod 事件(CNI 插件是否报错)
kubectl describe pod <pod-name> | grep -A5 Events
# 2. 检查 kubelet 日志(CNI 调用链路)
journalctl -u kubelet -f | grep -i cni
# 3. 手动执行 CNI 插件验证配置
cat /etc/cni/net.d/*.conf
ls /opt/cni/bin/
|
常见原因: CNI 配置文件格式错误、IPAM 池耗尽(host-local 无可用 IP)、插件二进制缺失。
2.2 同节点 Pod 无法通信
1
2
3
4
5
6
7
8
9
10
11
| # 1. 检查 Pod 内的路由表和默认网关
kubectl exec <pod-a> -- ip route
# 预期:default via <cni0/docker0 IP> dev eth0
# 2. 检查 Pod 的 ARP 缓存
kubectl exec <pod-a> -- arp -n
# 预期:目标 Pod IP → MAC
# 3. 宿主机上检查网桥 CAM 表
brctl showmacs cni0
# 预期:目标 Pod MAC → veth 端口
|
Flannel 特定: flanneld 未运行或 etcd 不可达时,Pod 能启动但 IP 分配卡住。
Calico 特定: Felix 未将 /32 路由写入宿主机路由表——ip route | grep cali 确认。
Cilium 特定: eBPF 程序加载失败——cilium status --verbose 查看 Controller Status 是否有 failing。
2.3 跨节点 Pod 无法通信
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # 1. 确认两个 Pod 的宿主机路由表包含对方子网
ip route get <target-pod-ip>
# 预期输出:<target pod ip> via <target node ip> dev <iface>
# 2. Flannel VXLAN:检查 VTEP 设备 + FDB
ip -d link show flannel.1
bridge fdb show dev flannel.1 | grep <target node ip>
# 3. Calico BGP:检查 BGP Peer 状态
calicoctl node status
# 预期:BGP 邻居 Established
birdcl show protocols
# 预期:所有 BGP Peer 状态 up
# 4. Cilium:检查隧道端点
cilium bpf tunnel list
# 预期:目标 Pod IP → 目标节点 IP
# 5. 抓包确认封装是否正确
tcpdump -i eth0 -nn udp port 8472 # VXLAN
tcpdump -i eth0 -nn udp port 8285 # Flannel UDP
tcpdump -i eth0 -nn proto 4 # IPIP (IP proto 4)
|
Flannel VXLAN 特定: VNI 不匹配——源宿主机 VNI=1、目标宿主机 VNI≠1 时封装无法到达。
Calico IPIP 特定: tunl0 设备未创建——modprobe ipip && ip link set tunl0 up。
2.4 Service 不通
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 1. 确认 Service 有 Endpoint
kubectl get ep <svc-name>
# 如果没有后端 Pod,检查 Pod 的 readinessProbe 和 label selector
# 2. 确认 kube-proxy 规则
# iptables 模式
iptables -t nat -L KUBE-SERVICES -n | grep <svc-ip>
# IPVS 模式
ipvsadm -Ln | grep <svc-ip>
# 3. 从 Pod 内测试 Service DNS
kubectl exec <pod> -- nslookup <svc-name>.<namespace>.svc.cluster.local
# 预期:返回 Service ClusterIP
# 4. 抓包看 DNAT 是否生效
kubectl exec <pod> -- curl -v http://<svc-name>:<port>
# 同时在宿主机抓包:tcpdump -i any -nn host <svc-ip>
|
Cilium 特定(无 kube-proxy):
1
2
3
4
5
6
| # 检查 Service 的 eBPF Map 条目
cilium service list
# 预期:Service ClusterIP → 后端 Pod IP 映射存在
# 捕获 eBPF 数据路径事件
cilium monitor --type drop --type trace
|
常见原因: kube-proxy 未运行、conntrack 表满(dmesg | grep 'nf_conntrack: table full')、Service 的 externalTrafficPolicy: Local 导致流量发到没有后端 Pod 的节点。
2.5 DNS 解析失败
1
2
3
4
5
6
7
8
9
10
11
12
| # 1. 确认 CoreDNS Pod 运行正常
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 2. 从 Pod 内直接向 CoreDNS 发查询
kubectl exec <pod> -- nslookup kubernetes.default 10.96.0.10
# 3. 检查 Pod 的 /etc/resolv.conf
kubectl exec <pod> -- cat /etc/resolv.conf
# 预期:nameserver 指向 CoreDNS ClusterIP
# 4. 宿主机抓包确认 DNS 请求是否发出
tcpdump -i cni0 -nn port 53
|
3. 性能问题排查
3.1 Service 延迟尖峰
1
2
3
4
5
6
7
| # 检查 iptables 规则数量
iptables -t nat -L -n | wc -l
# > 5000 条时考虑迁移到 IPVS 或 Cilium eBPF
# IPVS 模式检查后端分布
ipvsadm -Ln --stats --rate
# 检查每个后端的连接数是否均匀
|
3.2 Overlay 带宽不足
1
2
3
4
5
6
7
8
9
10
11
| # 1. 确认 MTU 是否正确
kubectl exec <pod> -- ip link show eth0 | grep mtu
# VXLAN Overlay 下 Pod MTU 应为 1450(1500 - 50B 封装头)
# 2. 从 Pod 内做带宽测试
kubectl exec <pod-a> -- iperf3 -c <pod-b-ip>
# 对比宿主机直接 iperf3 的带宽,评估封装开销
# 3. 宿主机抓包看是否有分片
tcpdump -i eth0 -nn 'ip[6:2] & 0x1fff != 0'
# 出现大量分片说明 MTU 不匹配
|
3.3 conntrack 表满
1
2
3
4
5
6
7
8
9
10
| # 检查当前 conntrack 使用量
conntrack -C
# 检查上限
sysctl net.netfilter.nf_conntrack_max
# 临时扩容
sysctl -w net.netfilter.nf_conntrack_max=524288
# Cilium 场景不依赖内核 conntrack,检查 eBPF conntrack
cilium bpf ct list global | wc -l
|
4. 各 CNI 常用排障命令速查
| CNI | 排障命令 |
|---|
| Flannel | kubectl logs -n kube-system <flannel-pod>、bridge fdb show dev flannel.1、ip route | grep flannel |
| Calico | calicoctl node status、calicoctl get ippools、birdcl show protocols、ip route | grep cali |
| Cilium | cilium status、cilium monitor --type drop、cilium bpf tunnel list、cilium service list |
| 通用 | ip route get <IP>、tcpdump -i any -nn、iptables -t nat -L -n -v |
参考链接