目录
Please enable Javascript to view the contents

K8s网络-排障思路与常用命令

 ·  ☕ 5 分钟

系列导航

本系列从 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 表是否有下一跳 MACip neigh show dev eth0
bridge fdbVXLAN/VTEP 模式检查 FDB 表bridge fdb show dev flannel.1
iptables -t nat -L -n -v检查 kube-proxy Service DNAT 规则留意计数器(pkts/bytes)是否增长
ipvsadm -LnIPVS 模式检查 Service 后端ipvsadm -Ln --stats
conntrack -L检查连接跟踪表conntrack -L -s <Pod IP>
ss -tunap检查连接状态和进程ss -tunap | grep <port>
ip netns操作/查看 network namespaceip 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排障命令
Flannelkubectl logs -n kube-system <flannel-pod>bridge fdb show dev flannel.1ip route | grep flannel
Calicocalicoctl node statuscalicoctl get ippoolsbirdcl show protocolsip route | grep cali
Ciliumcilium statuscilium monitor --type dropcilium bpf tunnel listcilium service list
通用ip route get <IP>tcpdump -i any -nniptables -t nat -L -n -v

参考链接

分享

Hex
作者
Hex
CloudNative Developer