使用 Cilium 在 Docker 主机上开启 eBPF kube-proxy 替换

解读

国内云原生面试中,**“Docker 主机”通常指裸金属或虚拟机节点,“Cilium”作为 CNCF 毕业级 CNI,默认依赖 Kubernetes。题目要求“脱离 K8s,仅用 Docker Engine”完成 kube-proxy 替换,本质是考察候选人能否把 Cilium 的 eBPF 数据面“降级”**到单机 Docker 环境,同时保留 ClusterIP、NodePort、LoadBalancer 等 Service 语义。
面试官想看到:

  1. 是否理解 kube-proxy 的 iptables/ipvs 模式痛点(规则爆炸、收敛慢、跟踪困难)。
  2. 能否在无 K8s API Server场景下,用 Cilium 的**“lib-only”**模式(cilium-agent --datapath-mode=lb-only)接管主机网络栈,实现南北向与东西向负载均衡。
  3. 对 eBPF 程序加载、map 管理、Docker 网络命名空间打通、XDP 驱动选型(veth/ipvlan/DPDK)是否具备落地经验。
  4. 是否掌握国内合规要求:等保 2.0 对容器网络审计、RBAC、流量镜像的强制条款,以及信创环境下内核版本 ≥ 5.10 的硬性门槛。

知识点

  1. eBPF 与 kube-proxy 替换原理

    • eBPF 程序在 tc ingress/egress 或 XDP 层提前做 NAT、会话保持,无需逐包遍历 iptables。
    • Cilium 的 “Kube-Proxy Replacement” 提供完全兼容的 Service 语义,但需内核开启 CONFIG_NET_CLS_BPF、CONFIG_XDP_SOCKETS。
  2. Cilium 运行模式

    • k8s 模式:依赖 kube-apiserver,自动监听 Endpoints/Service。
    • lb-only 模式:独立运行,通过 cilium-agent --config-file=lb-config.yaml 静态声明 Service/Backend,适用于裸金属 Docker 主机。
  3. Docker 网络模型限制

    • 默认 bridge 网络与主机网络隔离,需使用 --network hostipvlan/macvlan 驱动,确保容器与主机共用网络命名空间,否则 eBPF 程序无法 attach 到容器 veth 另一端。
  4. 国内内核与驱动痛点

    • 阿里云、腾讯云 CentOS 7.9 默认 3.10 内核,需手动升级至 5.4 LTS 或 5.10+ 并安装 kernel-devel-5.x
    • 华为鲲鹏 ARM 服务器需确认 arm64 eBPF JIT 已开启,避免程序加载失败。
  5. 等保合规

    • 必须开启 --enable-hubble--hubble-listen-address=:4244,配合 Hubble-Exporter 把 L3/L4/L7 元数据送到 Kafka→ELK,满足 6 个月流量审计要求。

答案

步骤 1:前置检查

uname -r  # 确认 ≥ 5.10
grep XDP /boot/config-$(uname -r)  # 确认 CONFIG_XDP_SOCKETS=y
lscpu | grep Virt  # 确认关闭虚拟化嵌套,避免 XDP 驱动回退

步骤 2:安装 Cilium CLI(国内镜像加速)

export CILIUM_CLI_VERSION=v0.15.7
curl -L https://mirrors.tuna.tsinghua.edu.cn/github-release/cilium/cilium-cli/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz | tar xz -C /usr/local/bin

步骤 3:准备 lb-only 配置
cat > /etc/cilium/cilium-lb.yaml <<EOF
datapath-mode: lb-only
enable-kube-proxy-replacement: true
devices: "eth0" # 主机上行口
bpf-lb-acceleration: native # 使用 XDP_DRV,如 ixgbe/mlx5
bpf-lb-mode: snat
node-port-range: "30000,32767"
enable-hubble: true
hubble-listen-address: :4244
EOF

步骤 4:启动 cilium-agent(systemd 托管)
cat > /etc/systemd/system/cilium-agent.service <<EOF
[Unit]
Description=Cilium eBPF LB
After=network-online.target

[Service]
ExecStart=/usr/bin/cilium-agent --config-dir=/etc/cilium
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable --now cilium-agent

步骤 5:声明 Service(无 K8s,静态写 YAML)
cat > /var/lib/cilium/static-service.yaml <<EOF
- name: nginx-lb
type: NodePort
cluster-ip: 10.96.0.100
external-ip: 10.0.0.10 # 主机公网 IP
ports:
- port: 80
targetPort: 8080
nodePort: 30080
backends:
- ip: 172.17.0.2 # Docker 容器地址
port: 8080
EOF
cilium lb update-service --yaml /var/lib/cilium/static-service.yaml

步骤 6:Docker 容器接入主机网络
docker run -d --name nginx --network host -p 8080:80 nginx:1.25-alpine

步骤 7:验证
cilium service list
curl 10.0.0.10:30080 # 应返回 nginx 欢迎页
cilium bpf lb list # 查看 eBPF map 条目
tcpdump -i eth0 -nn port 30080 -X # 确认无 iptables 规则,直接 XDP 转发

步骤 8:等保审计对接
docker run -d --name hubble-exporter -p 4245:4245 \
-e HUBBLE_SERVER=cilium-agent:4244 \
-e KAFKA_BROKERS=10.0.0.50:9092 \
quay.io/cilium/hubble-exporter:v1.13.4

拓展思考

  1. 双栈与 SR-IOV
    国内运营商已强制 IPv6 单栈上线,可在 cilium-lb.yaml 追加 enable-ipv6: true 并绑定 SR-IOV VF,利用 eBPF 的 TCX 新程序类型实现硬件卸载,降低 30% 延迟。

  2. 与 Docker Swarm 集成
    若客户坚持 Swarm,可部署 cilium-operator-generic 监听 Swarm DNSRR endpoints,实现 “半自动” Service 声明,避免静态 YAML 维护成本。

  3. 故障演练
    在生产环境使用 tc qdisc add dev eth0 clsact bpf obj drop_50_percent.o sec xdp 模拟 50% 丢包,验证 Cilium 的 sessionAffinity=ClientIP 在 eBPF map 老化后能否保持连接,满足金融客户 RPO=0 要求。