手把手教你用 eBPF 排查 K8s 网络问题
手把手教你用 eBPF 排查 K8s 网络问题
前言:为什么需要 eBPF?
生产环境告警响起——数据库连接数瞬间飙高,可 kubectl get pods 一片绿色。过去我们靠 tcpdump + iptables -L 盲排,既费时又破坏线上流量。
eBPF(Extended Berkeley Packet Filter)技术让我们第一次能在不停业务的前提下,精准追踪每一条跨 Pod 流量,实现内核级可观测。本文基于 Cilium 1.17 和最新内核实践,提供可直接落地的排查方法论。
一、环境准备:生产级前置检查
1.1 内核版本要求
eBPF 功能对内核版本敏感,生产环境建议:
# 检查内核版本(推荐 ≥ 5.10,最低 ≥ 4.19.57)
uname -r
# 检查 BPF 特性支持
bpftool feature probe | grep -E "program_type|map_type"
# 关键检查项:BTF 支持(CO-RE 必需)
ls /sys/kernel/btf/vmlinux
生产提示:标准化内核版本 across 所有节点,避免 CO-RE(Compile Once - Run Everywhere)兼容性问题 。
1.2 快速部署排查工具
# 安装 kubectl-trace(无需在节点预装组件)
kubectl krew install trace
# 安装 bpftool(节点级调试)
yum install -y bpftool || apt-get install -y bpftool
# Cilium 集群确认 eBPF 模式
cilium status | grep "KubeProxyReplacement"
# 预期输出:KubeProxyReplacement: Strict
二、网络问题排查
场景 1:Pod 无法访问 ClusterIP,但 PodIP 正常
现象:curl <service-ip>:port 超时,直接访问后端 Pod IP 正常。
排查流程:
# Step 1: 确认 Cilium 代理模式
kubectl -n kube-system exec ds/cilium -- cilium status | grep "KubeProxyReplacement"
# Step 2: 检查 eBPF 程序加载状态
kubectl -n kube-system exec ds/cilium -- bpftool prog show | grep cilium
# Step 3: 查看 Service 映射表(替代 iptables -t nat -L)
kubectl -n kube-system exec ds/cilium -- cilium service list
# 预期看到:ClusterIP -> Backend Pod IPs 的映射
# Step 4: 追踪数据包路径
kubectl trace run <node-name> -e 'kprobe:tcp_v4_connect { printf("PID %d connecting to %s\n", pid, ntop(AF_INET, arg2)); }'
根因定位:若 cilium service list 无对应条目,确认 kubeProxyReplacement=strict 已生效且 Service CIDR 正确写入 CT LB Map 。
场景 2:NetworkPolicy 误拦截导致连接超时
现象:应用间通信随机超时,无明确错误日志。
排查流程:
# 启用 Hubble 实时观测(Cilium 内置)
hubble observe --verdict DROPPED -f
# 典型输出:
# default/client-xxx:35044 (ID:4605) <> default/server-xxx:80 (ID:22656) Policy denied DROPPED (TCP Flags: SYN)
# default/client-xxx:35044 (ID:4605) <> default/server-xxx:80 (ID:22656) policy-verdict:none INGRESS DENIED (TCP Flags: SYN)
# 查看具体策略命中
kubectl -n kube-system exec ds/cilium -- cilium endpoint list | grep <pod-id>
修复建议:使用 CiliumNetworkPolicy 替代原生 NetworkPolicy,支持基于 Identity 的细粒度控制,避免标签选择器交叉导致的"假阳性"拦截 。
场景 3:跨节点 Pod 丢包(VXLAN/Direct Routing 模式)
现象:同节点 Pod 通信正常,跨节点丢包。
排查流程:
# 检查隧道映射(VXLAN 模式)
kubectl -n kube-system exec ds/cilium -- cilium bpf tunnel list
# 检查路由和邻居表(Direct Routing 模式)
kubectl -n kube-system exec ds/cilium -- cilium bpf neigh list
# 使用 bpftrace 追踪跨节点流量
kubectl trace run <node-name> -e 'tracepoint:skb:kfree_skb { printf("Drop reason: %s\n", args->location); }'
# 检查底层网络
ip route show table all | grep <remote-node-cidr>
arp -n | grep <remote-node-ip>
生产经验:若采用 Direct-Routing,检查 ToR(Top-of-Rack)交换机的 ARP Proxy / ECMP 配置;必要时切换为 VXLAN 模式确保稳定性 。
场景 4:DNS 解析间歇性失败
现象:应用日志显示 NXDOMAIN 或超时,CoreDNS Pod 状态正常。
排查流程:
# 使用 eBPF 追踪 DNS 查询路径
kubectl trace run <node-name> -e 'kprobe:udp_sendmsg /comm == "coredns"/ { printf("DNS query from %d\n", pid); }'
# 检查 Cilium DNS 策略(若启用 L7 策略)
kubectl -n kube-system exec ds/cilium -- cilium policy get | grep -A5 "dns"
# 查看 Hubble DNS 指标
hubble observe --protocol DNS --namespace kube-system
根因:常见为 Cilium L7 DNS 策略的 FQDN 缓存过期或通配符规则配置不当,导致合法查询被拦截。
场景 5:高并发场景下连接追踪表溢出
现象:大流量压测时新建连接失败,conntrack -L 显示表满。
排查流程:
# 检查 conntrack 状态(传统 iptables 模式)
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
# Cilium eBPF 模式下检查 CT Map
kubectl -n kube-system exec ds/cilium -- cilium bpf ct list global | wc -l
kubectl -n kube-system exec ds/cilium -- cilium bpf metrics list | grep conntrack
# 动态调整 Map 大小(生产环境)
helm upgrade cilium cilium/cilium -n kube-system \
--set bpf.ctTcpMax=524288 \
--set bpf.ctAnyMax=262144 \
--set bpf.mapDynamicSizeRatio=0.0025
性能对比:eBPF Map 相比传统 conntrack,查询复杂度为 O(1),且支持动态扩容,在高并发场景下 CPU 开销降低 40%-60% 。
三、生产环境最佳实践
3.1 可观测性体系建设
# Cilium Hubble 指标配置(Prometheus 集成)
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
enable-hubble: "true"
hubble-metrics-server: ":9965"
hubble-metrics: |
dns:query;ignoreAAAA
drop:sourceContext=identity;destinationContext=identity
tcp:sourceContext=identity;destinationContext=identity
flow:sourceContext=identity;destinationContext=identity
icmp:sourceContext=identity;destinationContext=identity
http:sourceContext=identity;destinationContext=identity
3.2 安全加固要点
- 权限控制:限制
CAP_BPF和CAP_SYS_ADMIN能力,仅允许预编译签名的 eBPF 程序加载 - 资源隔离:使用 cgroup 控制 eBPF 程序的资源消耗,避免"吵闹邻居"影响
- 审计日志:建立 eBPF 程序加载、Map 访问的完整审计链路
3.3 性能调优清单
| 优化项 | 配置建议 | 效果 |
|---|---|---|
| XDP 加速 | loadBalancer.acceleration=native | 降低延迟 30% |
| CPU 绑定 | resources.limits.cpu=2000m | 避免调度抖动 |
| Ring Buffer | 使用 per-CPU Map | 减少并发竞争 |
| 动态采样 | 高负载时降低追踪频率 | 控制 overhead < 1% |
四、工具链速查表
| 工具 | 适用场景 | 命令示例 |
|---|---|---|
| kubectl-trace | 集群级动态追踪 | kubectl trace run node-1 -e 'kprobe:tcp_drop' |
| bpftrace | 快速原型开发 | bpftrace -e 'kprobe:ip_vs_* { @[probe] = count(); }' |
| bpftool | 程序/Map inspection | bpftool prog show / bpftool map dump id <id> |
| cilium-cli | Cilium 专属诊断 | cilium connectivity test / cilium sysdump |
| Hubble CLI | 流量可视化 | hubble observe --verdict DROPPED --follow |
| BCC tools | 深度系统分析 | tcplife / tcpdrop / execsnoop |
五、总结
eBPF 技术正在重塑 Kubernetes 网络运维范式:
- 从黑盒到白盒:Hubble 提供 L3-L7 全链路秒级追踪,定位网络抖动不再靠抓包
- 从被动到主动:基于 Identity 的 NetworkPolicy 实现零信任东西向隔离
- 从低效到高性能:eBPF 替代 iptables,Service 数量 >1000 时性能优势显著
给 SRE 的临别赠言:生产环境不是儿戏,升级内核、拥抱 eBPF 需要做好运维门槛提升的准备。但当你的集群规模爆炸式增长时,eBPF 可能是救命的稻草。
本文基于 Cilium 1.17.5、Kernel 5.15+ 生产环境实践整理,建议定期关注内核版本与 eBPF 特性兼容性更新。
更多推荐
所有评论(0)