LabHub
学习 学习路径 课程

CCA — Cilium 认证助理

数据包在哪里被抓住,又被弹到哪里

在 LabHub 中继续学习

一句话总结

Cilium 会把 Kubernetes 的语义(服务、标签、策略)直接下发到内核中的数据结构。因此,即使服务增加,查找成本也不会增长,但这并不意味着一切都会变快。

概念图: 并不意味着一切都会变快。 · 重写整张表。 · 以 map entry 为单位的增量更新 · XDP 位于分配内存之前的阶段

为什么需要了解这一点

在 kube-proxy 的 iptables 模式中,一次服务请求会遍历 KUBE-SERVICES 链,在 KUBE-SVC-* 中经过概率分支,再于 KUBE-SEP-* 中执行 DNAT。规则数量与服务数和后端数成正比,内核对每个数据包都会近似遍历这份列表。

更棘手的是更新成本。iptables 即使只修改一条规则,实际上也会重写整张表。 在频繁部署的集群中,这会表现为 CPU 峰值和规则生效延迟。在拥有数千个服务的环境里,“Pod 已经启动,但流量还没到”的数秒空档就源于此处。

eBPF 会把这两个维度都变为常数时间。查找通过 hash map 完成,与服务数量无关;更新则是以 map entry 为单位的增量更新,不会触碰其他 entry。

工作原理

以下是从外部通过 NodePort 进入的数据包所经历的路径。

NIC 수신
  -> [XDP 훅]            드라이버 수준. sk_buff 할당 전이라 가장 빠름
  -> [tc ingress 훅]     서비스 변환(lb4_services -> lb4_backends), conntrack,
                         ipcache 룩업으로 목적지 아이덴티티 확인
  -> bpf_redirect_peer   호스트 veth 에서 파드 네임스페이스 안 피어로 직행
  -> [파드 lxc 인터페이스] 정책 평가: (소스 아이덴티티, 포트, 프로토콜, 방향)
  -> 애플리케이션 소켓

通过 NodePort 进入的数据包依次经过 eBPF hook:NIC 接收、XDP hook、tc ingress hook、bpf_redirect_peer、Pod 的 lxc interface、application socket。服务转换、conntrack 与策略评估发生在 tc hook;只有应用了 L7 策略的流量会离开内核,经过 userspace Envoy 并增加延迟

需要抓住三点。第一,XDP 位于分配内存之前的阶段,因此可用于 DDoS 过滤和 NodePort 加速,但需要受支持的 NIC driver。第二,数据路径的主体是 tc hook,服务转换、conntrack 和策略评估都在这里发生。第三,bpf_redirect_peer 会跳过数据通过 veth pair 时产生的一轮 softIRQ 重新调度,一次跨越 namespace 边界。

策略不是按 IP,而是按身份评估。每组 Pod 标签对应一个数字,这个数字会成为内核 map 的 key。考试会直接涉及下面这些保留身份,最好记住。

编号 名称 含义
0 unknown 未知来源
1 host 本地节点自身
2 world 集群外部的全部对象
3 unmanaged 不受 Cilium 管理的 endpoint
4 health 健康检查 endpoint
5 init 正在初始化的 endpoint
6 remote-node 其他节点
7 kube-apiserver API server
8 ingress ingress

职责分工也要梳理清楚。Cilium Agent 以 DaemonSet 形式运行在每个节点上,负责加载 eBPF 程序、管理 endpoint、应用策略和处理 conntrack。Cilium Operator 在每个集群运行一份,负责集群范围的 IPAM、CRD garbage collection 和节点发现。Agent 要直接操作节点数据路径,所以必须是 DaemonSet;Operator 处理集群全局状态,因此一份即可。

最后也要坦诚说明代价。换成 eBPF 后一切都会变快,这种说法并不正确。

了解“启用什么功能会付出什么代价”,是运维的核心。

实际工作中的表现

作者在一个由 7 个节点组成的 home lab(cp-1/2/3 + gpu-a/b/c/d)上运行 Kubernetes v1.34.10、containerd 1.7.27、kernel 6.14 和 Cilium 1.20.1。这个集群使用 kubeadm init --skip-phases=addon/kube-proxy,从一开始就没有安装 kube-proxy。这与安装后再删除不同。只要 kube-proxy 曾经运行过一次,就会在节点上刻下 KUBE-SERVICES / KUBE-SVC-* / KUBE-SEP-* 链;即使删除 DaemonSet,这些规则仍会保留,并与 eBPF 数据路径冲突。

以下结果来自测量,而不是主张。

kube-proxy 파드 수: 0
노드의 iptables KUBE- 체인 개수: 0

服务则以如下形式位于内核 map 中。

SERVICE ADDRESS             BACKEND ADDRESS (REVNAT_ID) (SLOT)
10.96.0.10:53/TCP (1)       10.244.0.150:53/TCP (4) (1)
10.96.0.1:443/TCP (1)       10.0.0.120:6443/TCP (1) (1)

cilium status 报告了 KubeProxyReplacement: TrueModules Health: OK 92 / Degraded 0;包括节点状态、控制平面、CNI、CoreDNS、调度和服务 DNS 在内的 14 项基本验证也全部 14/14 通过。这些数字之所以重要,理由很简单:证明 eBPF 数据路径正在工作的,不是文档,而是链数量和 map dump。

下个测验将检查什么

本模块只讲概念。下一模块会介绍身份模型和 kube-proxy 替代方案,让你把上面看到的值直接写入 Helm values 文件,并创建验证其状态的脚本。