被 cilium BPF 劫走的 WireGuard 流量

Sep 1, 2026 00:00 · 4556 words · 10 minute read Troubleshooting Network Linux Kubernetes

现象

一句话描述问题现象:在公有云上走 WireGuard 访问 foo 集群内的服务不通。

网络架构图如上,有两条链路,一条通一条不通:

  1. 阿里云 instance1 走 service vip1 wireguard 到 foo 的 harbor 节点(harbor 不在 Kubernetes 集群中)✅ 比下面的链路多一跳,先路由至 171,再走 Kubernetes 的跨节点 overlay 到 gpu-118 业务节点
  2. 阿里云 instance2 走 service vip2 wireguard 到 foo 的 foo-i-master03 节点 ❌

排查

kubectl get svc -n ns-t-te-c637fngp2sne3h2q | grep if-dc6igsfwaodgnkof-service
if-dc6igsfwaodgnkof-service               LoadBalancer   172.28.3.29      10.197.92.5    80/TCP,9998/TCP                      53d
if-dc6igsfwaodgnkof-service-2             LoadBalancer   172.28.220.200   10.197.88.1    80/TCP,9998/TCP                      2d16h

kubectl exec -it -n kube-system cilium-5759s -- cilium-dbg service list | grep "10.197.92.5"
208    10.197.92.5:80/TCP         LoadBalancer   1 => 172.27.5.34:80/TCP (active)
209    10.197.92.5:9998/TCP       LoadBalancer   1 => 172.27.5.34:9998/TCP (active)

kubectl exec -it -n kube-system cilium-5759s -- cilium-dbg service list | grep "10.197.88.1"
2013   10.197.88.1:80/TCP         LoadBalancer   1 => 172.27.5.34:80/TCP (active)
2014   10.197.88.1:9998/TCP       LoadBalancer   1 => 172.27.5.34:9998/TCP (active)

两个 Service 都是 LoadBalancer 类型,由 metalLB 实现。

  • vip 10.197.92.5 -> Pod IP 172.27.5.34
  • vip 10.197.88.1 -> Pod IP 172.27.5.34

两条链路的后端实际上是同一个推理服务 Pod,服务本身没问题。

在集群内的 foo-i-master03 节点上测试:

上通过 VIP 访问 通过 Cluster IP 访问
10.197.92.5 ✅ 172.28.3.29 ✅
10.197.88.1 ❌ 172.28.220.200 ✅

通过 Cluster IP 访问均没有问题说明 cilium 的 DNAT 和集群的 overlay 网络都正常。

找出丢包点

查看 foo-i-master03 节点上 cilium 的丢包:

kubectl exec -it -n kube-system cilium-5759s -- cilium monitor --type drop
xx drop (Policy denied) flow 0x460d64c7 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:33440 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0x14179f0a to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:36978 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0xee6e27df to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:39480 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0x1416cdb0 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:35890 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0x72e502ed to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:57910 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x588595ed to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:59668 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0xd9d9842f to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:48364 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x9fc2f57c to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:49276 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0x9fd8487b to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:60786 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x4941af40 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:53956 -> 60.205.177.172:80 tcp SYN
xx drop (Is a ClusterIP) flow 0x0 to endpoint 0, ifindex 183, file bpf_host.c:962, , identity 16777219->unknown: 10.2.10.1:57556 -> 172.28.0.1:443 tcp SYN
xx drop (Policy denied) flow 0x3d3e26ff to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:46462 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0x30e5dc91 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:48212 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x9d029f69 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:36978 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x5726f3b5 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:49668 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0xa03be84 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:57910 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x93f69c16 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:49054 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0x72b625b4 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:46476 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0xac64620f to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:60786 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x20396268 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:53956 -> 60.205.177.172:80 tcp SYN
xx drop (Is a ClusterIP) flow 0x0 to endpoint 0, ifindex 183, file bpf_host.c:962, , identity 16777219->unknown: 10.2.10.1:57556 -> 172.28.0.1:443 tcp SYN
xx drop (Policy denied) flow 0x47503867 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:54914 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0x6ebd1d52 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:39480 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0xa99d01bc to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:49054 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0x53ad1da3 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:46476 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0xa0c25956 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:52098 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x58ba5785 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:48226 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0xa93632af to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:44328 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0xf76ddc10 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:39766 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0xcd7c44f6 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:36978 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0x35c1fe11 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:49660 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0x85567bcf to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:48946 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0x3bece1bc to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:57910 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0xff0799ab to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:55254 -> 39.102.60.242:80 tcp SYN
xx drop (Policy denied) flow 0x846450d9 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:34638 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0xc5544dd5 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:60786 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0xd75c3a16 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:53956 -> 60.205.177.172:80 tcp SYN
xx drop (Policy denied) flow 0xb81879b1 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:59152 -> 39.102.60.242:80 tcp SYN
xx drop (Is a ClusterIP) flow 0x0 to endpoint 0, ifindex 183, file bpf_host.c:962, , identity 16777219->unknown: 10.2.10.1:57556 -> 172.28.0.1:443 tcp SYN
xx drop (Policy denied) flow 0x52f2ceb6 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:49292 -> 39.105.217.223:80 tcp SYN
xx drop (Policy denied) flow 0x520b65e5 to endpoint 0, ifindex 69, file bpf_lxc.c:1651, , identity 50131->world: 172.27.2.127:48226 -> 60.205.177.172:80 tcp SYN

没看到 10.197.88.1 和 172.27.5.34 相关记录,表示 foo-i-master03 节点的 cilium 并未发生相关丢包。

在 foo-i-master03 节点上对所有网卡抓包(172.27.5.17 是后端 Pod IP):

tcpdump -nne -i any 'tcp port 80 and host 172.27.5.17'
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
10:25:56.081452 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.42750 > 172.27.5.17.80: Flags [S], seq 2869817211, win 64860, options [mss 1380,sackOK,TS val 2524038291 ecr 0,nop,wscale 7], length 0
10:26:02.063660 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.38576 > 172.27.5.17.80: Flags [S], seq 1366030254, win 64860, options [mss 1380,sackOK,TS val 2524044273 ecr 0,nop,wscale 7], length 0
10:26:03.085393 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.38576 > 172.27.5.17.80: Flags [S], seq 1366030254, win 64860, options [mss 1380,sackOK,TS val 2524045295 ecr 0,nop,wscale 7], length 0
10:26:05.101382 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.38576 > 172.27.5.17.80: Flags [S], seq 1366030254, win 64860, options [mss 1380,sackOK,TS val 2524047311 ecr 0,nop,wscale 7], length 0
10:26:11.071336 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.56192 > 172.27.5.17.80: Flags [S], seq 2167750376, win 64860, options [mss 1380,sackOK,TS val 2524053280 ecr 0,nop,wscale 7], length 0
10:26:12.077480 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.56192 > 172.27.5.17.80: Flags [S], seq 2167750376, win 64860, options [mss 1380,sackOK,TS val 2524054287 ecr 0,nop,wscale 7], length 0
10:26:14.093427 cilium_vxlan Out ifindex 9 00:00:00:00:00:00 ethertype IPv4 (0x0800), length 80: 172.27.2.240.56192 > 172.27.5.17.80: Flags [S], seq 2167750376, win 64860, options [mss 1380,sackOK,TS val 2524056303 ecr 0,nop,wscale 7], length 0

数据包进入节点后,cilium 把 VIP 直接 DNAT 成推理服务后端 Pod IP 172.27.5.17。

这里抓包记录实际上有一个关键信息,我在排查的时候同时也 prompt AI 一起排查,但 AI 没能够及时看出这里的问题。该关键信息是可以直接缩短排查路径的。

cilium 的操作:

  1. 将 vip 10.197.88.1 DNAT 成 172.27.5.17(Pod IP)
  2. 将源 IP SNAT 成 172.27.2.240(foo-i-master03 节点的 cilium_host 设备的 IP)
  3. 将数据包送入 cilium_vxlan VTEP 设备,二次封包,走 VXLAN 隧道去 gpu-119 节点

SNAT 会导致在推理服务 Pod 中无法看出流量真正的来源,因为另一条链路没问题,推理服务正在 serving,无法判断出是否有数据包来自 instance2。

所以部署一个 nginx 服务来帮助测试与排查:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeName: gpu-119 # 将 Pod 固定到 gpu-119 节点上
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - name: http
              containerPort: 80
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              cpu: 200m
              memory: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-2
  annotations:
    metallb.universe.tf/ip-allocated-from-pool: mizar-ip-pool2
  labels:
    mizar.k8s.io/user-job_kind: infini2
spec:
  allocateLoadBalancerNodePorts: false
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  loadBalancerClass: metallb
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: http
      protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-1
  annotations:
    metallb.universe.tf/ip-allocated-from-pool: mizar-ip-pool
  labels:
    mizar.k8s.io/user-job_kind: infini
spec:
  allocateLoadBalancerNodePorts: false
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  loadBalancerClass: metallb
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 80
      targetPort: http
      protocol: TCP
kubectl get po -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
nginx-588c9b685f-b7544   1/1     Running   0          19h   172.27.5.17   gpu-119   <none>           <none>

kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP      172.28.0.1      <none>        443/TCP   60d
nginx-1      LoadBalancer   172.28.55.234   10.197.92.7   80/TCP    79m
nginx-2      LoadBalancer   172.28.40.210   10.197.88.2   80/TCP    79m

和推理服务保持一致,两个 Service 两个 VIP 两条链路:

  • vip 10.197.92.7 -> Pod IP 172.27.5.17 ✅
  • vip 10.197.88.2 -> Pod IP 172.27.5.17 ❌

nginx Pod

只在 instance2 发包,在 nginx Pod 网络命名空间内抓包:

tcpdump -nne -i eth0 tcp and port 80
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes

没有任何数据包,说明 TCP 包根本没到 Pod

gpu-119 cilium

查看 gpu-119 节点上的 cilium 丢包:

kubectl exec -it -n kube-system cilium-5759s -- cilium-dbg monitor -vv --type drop --type trace --type policy-verdict | grep 172.27.5.17

也没看到任何与 Pod IP 172.27.5.17 相关的记录,说明 cilium BPF 中并未发生丢包。

foo-i-master03 bond0

在 foo-i-master03 节点的 bond0 上抓包,过滤 VXLAN 内封包 IP 为 172.27.5.17

tcpdump -nne -i bond0 \
  'src host 192.168.71.192 and dst host 192.168.71.119 and udp dst port 8472 and udp[46:4] = 0xac1b0511'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:27:38.038003 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.59598 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.59330 > 172.27.5.17.80: Flags [S], seq 1310639769, win 64860, options [mss 1380,sackOK,TS val 2473740246 ecr 0,nop,wscale 7], length 0
20:27:39.054431 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.59598 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.59330 > 172.27.5.17.80: Flags [S], seq 1310639769, win 64860, options [mss 1380,sackOK,TS val 2473741263 ecr 0,nop,wscale 7], length 0
20:27:41.070507 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.59598 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.59330 > 172.27.5.17.80: Flags [S], seq 1310639769, win 64860, options [mss 1380,sackOK,TS val 2473743279 ecr 0,nop,wscale 7], length 0
20:27:47.045591 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.56675 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.51256 > 172.27.5.17.80: Flags [S], seq 4244890411, win 64860, options [mss 1380,sackOK,TS val 2473749254 ecr 0,nop,wscale 7], length 0
20:27:48.046385 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.56675 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.51256 > 172.27.5.17.80: Flags [S], seq 4244890411, win 64860, options [mss 1380,sackOK,TS val 2473750255 ecr 0,nop,wscale 7], length 0

说明包走 VXLAN 成功出 foo-i-master03 机器了。

这里的抓包中关键信息又出现了一次,但 AI 还是没能够看出来。

gpu-119 bond0

在 gpu-119 bond0 上抓入包,过滤 VXLAN 内封包 IP 为 172.27.5.17

tcpdump -nne -s 0 -Q in -i bond0   'src host 192.168.71.192 and dst host 192.168.71.119 and udp dst port 8472 and udp[46:4] = 0xac1b0511'
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:33:59.402199 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.49067 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.36008 > 172.27.5.17.80: Flags [S], seq 483517714, win 64860, options [mss 1380,sackOK,TS val 2474121615 ecr 0,nop,wscale 7], length 0
20:34:05.376029 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.53348 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.53118 > 172.27.5.17.80: Flags [S], seq 2775139000, win 64860, options [mss 1380,sackOK,TS val 2474127588 ecr 0,nop,wscale 7], length 0
20:34:06.378182 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.53348 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.53118 > 172.27.5.17.80: Flags [S], seq 2775139000, win 64860, options [mss 1380,sackOK,TS val 2474128591 ecr 0,nop,wscale 7], length 0
20:34:08.394097 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.53348 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.53118 > 172.27.5.17.80: Flags [S], seq 2775139000, win 64860, options [mss 1380,sackOK,TS val 2474130607 ecr 0,nop,wscale 7], length 0

有入包,说明 VXLAN 包成功达到 gpu-119 节点。

gpu-119 cilium

查看 cilium BPF 侧的丢包:

kubectl exec -it -n kube-system cilium-wbv4d -- cilium-dbg monitor -vv --type drop --type trace --type policy-verdict | grep "172.27.5.17 "

没有任何输出,说明包不在这丢的。

通过 cilium 全家桶的 pwru 工具分析丢包点:

root@gpu-119:~# pwru \
  --filter-track-skb \
  --output-tuple \
  --output-tcp-flags \
  --output-caller \
  --timestamp=relative \
  'tcp and dst host 172.27.5.17 and dst port 80'
2026/08/17 22:47:59 INFO Attaching kprobes via=kprobe
1475 / 1475 [--------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 370 p/s
2026/08/17 22:48:03 INFO Attached ignored=3
2026/08/17 22:48:03 INFO Listening for events..
2026/08/17 22:48:03 WARN Failed to retrieve all ifaces from all network namespaces. Some iface names might be not shown. error="open /proc/2069721/ns/net: no such file or directory"
SKB                CPU PROCESS          TIMESTAMP        NETNS      MARK/x        IFACE       PROTO  MTU   LEN   TUPLE FUNC CALLER
0xff391ae9e95e7200 183 <empty>:0        0                4026531840 0            bond0:6      0x0800 0     74    192.168.71.192:42582->192.168.71.119:8472(udp) eth_type_trans vxlan_set_mac[vxlan]
0xff391ae9e95e7200 183 <empty>:0        1754             4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_release_head_state kfree_skb_reason
0xff391ae9e95e7200 183 <empty>:0        2163             4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_free_head          skb_release_data
0xff391ae9e95e7200 183 ~bin/pwru:118611 1007368312       4026531840 0            bond0:6      0x0800 0     74    192.168.71.192:42582->192.168.71.119:8472(udp) eth_type_trans         vxlan_set_mac[vxlan]
0xff391ae9e95e7200 183 ~bin/pwru:118611 1736             4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:42582->192.168.71.119:8472(udp) kfree_skb_reason(SKB_DROP_REASON_NOT_SPECIFIED) vxlan_rcv[vxlan]
0xff391ae9e95e7200 183 ~bin/pwru:118611 1315             4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_release_head_state                          kfree_skb_reason
0xff391ae9e95e7200 183 ~bin/pwru:118611 1827             4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_free_head                                   skb_release_data
0xff391ae9e95e7e00 183 <empty>:0        0                4026531840 0            bond0:6      0x0800 0     74    192.168.71.192:42582->192.168.71.119:8472(udp) eth_type_trans                                  vxlan_set_mac[vxlan]
0xff391ae9e95e7e00 183 <empty>:0        977              4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:42582->192.168.71.119:8472(udp) kfree_skb_reason(SKB_DROP_REASON_NOT_SPECIFIED) vxlan_rcv[vxlan]
0xff391ae9e95e7e00 183 <empty>:0        508              4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_release_head_state                          kfree_skb_reason
0xff391ae9e95e7e00 183 <empty>:0        714              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_release_data                                kfree_skb_reason
0xff391ae9e95e7e00 183 <empty>:0        471              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:42582->192.168.71.119:8472(udp) skb_free_head                                   skb_release_data
0xff391ae9e95e7e00 183 <empty>:0        520              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:42582->192.168.71.119:8472(udp) kfree_skbmem                                    kfree_skb_reason
0xff391b063809e800 149 <empty>:0        0                4026531840 0            bond0:6      0x0800 0     74    192.168.71.192:37207->192.168.71.119:8472(udp) eth_type_trans                                  vxlan_set_mac[vxlan]
0xff391b063809e800 149 <empty>:0        1206             4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:37207->192.168.71.119:8472(udp) kfree_skb_reason(SKB_DROP_REASON_NOT_SPECIFIED) vxlan_rcv[vxlan]
0xff391b063809e800 149 <empty>:0        775              4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_release_head_state                          kfree_skb_reason
0xff391b063809e800 149 <empty>:0        635              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_release_data                                kfree_skb_reason
0xff391b063809e800 149 <empty>:0        638              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_free_head                                   skb_release_data
0xff391b063809e800 149 <empty>:0        893              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) kfree_skbmem                                    kfree_skb_reason
0xff391b063809fd00 149 <empty>:0        0                4026531840 0            bond0:6      0x0800 0     74    192.168.71.192:37207->192.168.71.119:8472(udp) eth_type_trans                                  vxlan_set_mac[vxlan]
0xff391b063809fd00 149 <empty>:0        894              4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:37207->192.168.71.119:8472(udp) kfree_skb_reason(SKB_DROP_REASON_NOT_SPECIFIED) vxlan_rcv[vxlan]
0xff391b063809fd00 149 <empty>:0        603              4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_release_head_state                          kfree_skb_reason
0xff391b063809fd00 149 <empty>:0        640              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_release_data                                kfree_skb_reason
0xff391b063809fd00 149 <empty>:0        565              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_free_head                                   skb_release_data
0xff391b063809fd00 149 <empty>:0        718              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) kfree_skbmem                                    kfree_skb_reason
0xff391b063809fb00 149 <empty>:0        0                4026531840 0            bond0:6      0x0800 0     74    192.168.71.192:37207->192.168.71.119:8472(udp) eth_type_trans                                  vxlan_set_mac[vxlan]
0xff391b063809fb00 149 <empty>:0        1036             4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:37207->192.168.71.119:8472(udp) kfree_skb_reason(SKB_DROP_REASON_NOT_SPECIFIED) vxlan_rcv[vxlan]
0xff391b063809fb00 149 <empty>:0        594              4026531840 0        cilium_vxlan:20  0x0800 0     60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_release_head_state                          kfree_skb_reason
0xff391b063809fb00 149 <empty>:0        612              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_release_data                                kfree_skb_reason
0xff391b063809fb00 149 <empty>:0        475              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) skb_free_head                                   skb_release_data
0xff391b063809fb00 149 <empty>:0        558              4026531840 0        cilium_vxlan:20  0x0800 1500  60    192.168.71.192:37207->192.168.71.119:8472(udp) kfree_skbmem                                    kfree_skb_reason
^C2026/08/17 22:48:14 INFO Received signal, exiting program..
2026/08/17 22:48:14 INFO Detaching kprobes...
1472 / 1472 [---------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 26 p/s

丢包点在 kfree_skb_reason(SKB_DROP_REASON_NOT_SPECIFIED) vxlan_rcv[vxlan],源 IP 也能对上(来自 foo-i-master03),确实在解 VXLAN 封包时丢了,NOT_SPECIFIED 是因为当前的内核版本没有为 VXLAN 分支提供更细粒度的 reason。

此时 AI 给出的可能性为 VXLAN 内封包内的源 MAC 恰好等于本机 cilium_vxlan VTEP 设备的 MAC 地址,导致丢包,这种可能性微乎其微。

实际上,通过在 gpu-119 bond0 抓取另一条链路正常的 VXLAN 包对比:

  • 正常的包

    tcpdump -nne -s 0 -Q in -i bond0   'src host 192.168.71.192 and dst host 192.168.71.119 and udp dst port 8472 and udp[46:4] = 0xac1b0511'
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on bond0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    23:46:11.060589 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.49046 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 6
    06:62:b2:21:c5:be > 06:62:b2:21:c5:be, ethertype IPv4 (0x0800), length 74: 172.27.2.240.43570 > 172.27.5.17.80: Flags [S], seq 99631676, win 65170, options [mss 1330,sackOK,TS val 2921688077 ecr 0,nop,wscale 7], length 0
    23:46:11.060986 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 116: 192.168.71.192.49046 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 6
    06:62:b2:21:c5:be > 06:62:b2:21:c5:be, ethertype IPv4 (0x0800), length 66: 172.27.2.240.43570 > 172.27.5.17.80: Flags [.], ack 238303052, win 510, options [nop,nop,TS val 2921688078 ecr 2925319524], length 0
    23:46:11.061210 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 191: 192.168.71.192.49046 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 6
    06:62:b2:21:c5:be > 06:62:b2:21:c5:be, ethertype IPv4 (0x0800), length 141: 172.27.2.240.43570 > 172.27.5.17.80: Flags [P.], seq 0:75, ack 1, win 510, options [nop,nop,TS val 2921688078 ecr 2925319524], length 75: HTTP: GET / HTTP/1.1
    
  • 不正常的包

    tcpdump -nne -s 0 -Q in -i bond0   'src host 192.168.71.192 and dst host 192.168.71.119 and udp dst port 8472 and udp[46:4] = 0xac1b0511'
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on bond0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    23:49:00.327167 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.58592 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
    00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.46396 > 172.27.5.17.80: Flags [S], seq 1721381836, win 64860, options [mss 1380,sackOK,TS val 2485822538 ecr 0,nop,wscale 7], length 0
    23:49:01.360099 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.58592 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
    00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.46396 > 172.27.5.17.80: Flags [S], seq 1721381836, win 64860, options [mss 1380,sackOK,TS val 2485823571 ecr 0,nop,wscale 7], length 0
    23:49:03.372006 c6:a8:07:0b:92:49 > 46:35:36:03:de:61, ethertype IPv4 (0x0800), length 124: 192.168.71.192.58592 > 192.168.71.119.8472: OTV, flags [I] (0x08), overlay 0, instance 2
    00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 172.27.2.240.46396 > 172.27.5.17.80: Flags [S], seq 1721381836, win 64860, options [mss 1380,sackOK,TS val 2485825583 ecr 0,nop,wscale 7], length 0
    

正常的链路中,VXLAN 的内封包的 mac 地址有效;但有问题的链路中,VXLAN 的内封包的 mac 地址全为 0,这是导致丢包的原因。实际上在之前抓包时就已经携带了该关键信息。

原因

因为 foo-i-master03 节点上问题数据包的入口是 wg-maas-prod2 WireGuard 的虚拟网卡(来自阿里云),这是个 L3/ARPHRD_NONE 设备,没有正常的 mac 地址,节点上的 cilium 为其 attach 了 BPF(bond0 也有),导致包被其劫走,harbor 节点不在 k8s 集群中,上面没有 cilium

tc filter show dev wg-maas-prod2 ingress
filter protocol all pref 1 bpf chain 0
filter protocol all pref 1 bpf chain 0 handle 0x1 cil_from_netdev-wg-maas-prod2 direct-action not_in_hw id 17781 tag e064410d5c957a28 jited

ip -d link show wg-maas-prod2
183: wg-maas-prod2: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/none  promiscuity 0 minmtu 0 maxmtu 2147483552
    wireguard addrgenmode none numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

cat /sys/class/net/wg-maas-prod2/type
65534
# type 65534 表示 ARPHRD_NONE,不会有标准的以太网头。

有问题的链路:aliyun client -> wg-maas-prod2(foo-i-master03) -> cilium DNAT & SNAT(foo-i-master03) -> 送入 cilium_vxlan VTEP 设备时添加全零 mac 地址(foo-i-master03)

而没有问题的链路:aliyun client -> wg-maas-prod1(harbor) -> 命中路由直接转发往 foo-i-master01 节点 -> bond0 入站(foo-i-master01)

harbor 节点路由表:

ip r
10.197.92.0/22 via 192.168.71.171 dev bond0 proto static

流量在执行 Linux 路由查找(在内核中完成)前,就已经被 wg-maas-prod2 网卡上 attach 的 cilium BPF NAT 了,所以 wg-maas-prod2 节点上转发至 gpu-172 的静态路由失效。

ip r
10.197.88.0/22 via 192.168.71.172 dev bond0

解决方案

  1. 临时

    卸掉 foo-i-master03 节点上 wg-maas-prod2 虚拟网卡上的 cilium BPF

    tc filter show dev wg-maas-prod2 ingress
    filter protocol all pref 1 bpf chain 0
    filter protocol all pref 1 bpf chain 0 handle 0x1 cil_from_netdev-wg-maas-prod2 direct-action not_in_hw id 17781 tag e064410d5c957a28 jited
    
    
    tc filter del dev wg-maas-prod2 ingress protocol all pref 1 handle 0x1 bpf
    
    tc filter show dev wg-maas-prod2 ingress
    

    卸完后 wg-maas-prod2 链路直接通了,流量顺利被路由至 gpu172 节点,再经过 VXLAN 隧道到达 gpu-119 节点。但以上修复在 cilium node plugin 重启后会还原。

  2. 持久化

    修改 cilium 的配置文件,排除 wg-maas-prod2 设备;重启 foo-i-master03 节点上的 cilium node plugin。

    为 foo-i-master03 创建专属的 CiliumNodeConfig 对象:

    apiVersion: cilium.io/v2
    kind: CiliumNodeConfig
    metadata:
      name: master03-devices
      namespace: kube-system
    spec:
      nodeSelector:
        matchLabels:
          kubernetes.io/hostname: foo-i-master03
      defaults:
        devices: "bond0"
        direct-routing-device: "bond0"
    

    应用后只需重启该节点的 cilium。