使用 Cilium 在 Docker 主机上开启 eBPF kube-proxy 替换
解读
国内云原生面试中,**“Docker 主机”通常指裸金属或虚拟机节点,“Cilium”作为 CNCF 毕业级 CNI,默认依赖 Kubernetes。题目要求“脱离 K8s,仅用 Docker Engine”完成 kube-proxy 替换,本质是考察候选人能否把 Cilium 的 eBPF 数据面“降级”**到单机 Docker 环境,同时保留 ClusterIP、NodePort、LoadBalancer 等 Service 语义。
面试官想看到:
- 是否理解 kube-proxy 的 iptables/ipvs 模式痛点(规则爆炸、收敛慢、跟踪困难)。
- 能否在无 K8s API Server场景下,用 Cilium 的**“lib-only”**模式(cilium-agent --datapath-mode=lb-only)接管主机网络栈,实现南北向与东西向负载均衡。
- 对 eBPF 程序加载、map 管理、Docker 网络命名空间打通、XDP 驱动选型(veth/ipvlan/DPDK)是否具备落地经验。
- 是否掌握国内合规要求:等保 2.0 对容器网络审计、RBAC、流量镜像的强制条款,以及信创环境下内核版本 ≥ 5.10 的硬性门槛。
知识点
-
eBPF 与 kube-proxy 替换原理
- eBPF 程序在 tc ingress/egress 或 XDP 层提前做 NAT、会话保持,无需逐包遍历 iptables。
- Cilium 的 “Kube-Proxy Replacement” 提供完全兼容的 Service 语义,但需内核开启 CONFIG_NET_CLS_BPF、CONFIG_XDP_SOCKETS。
-
Cilium 运行模式
- k8s 模式:依赖 kube-apiserver,自动监听 Endpoints/Service。
- lb-only 模式:独立运行,通过 cilium-agent --config-file=lb-config.yaml 静态声明 Service/Backend,适用于裸金属 Docker 主机。
-
Docker 网络模型限制
- 默认 bridge 网络与主机网络隔离,需使用 --network host 或 ipvlan/macvlan 驱动,确保容器与主机共用网络命名空间,否则 eBPF 程序无法 attach 到容器 veth 另一端。
-
国内内核与驱动痛点
- 阿里云、腾讯云 CentOS 7.9 默认 3.10 内核,需手动升级至 5.4 LTS 或 5.10+ 并安装 kernel-devel-5.x。
- 华为鲲鹏 ARM 服务器需确认 arm64 eBPF JIT 已开启,避免程序加载失败。
-
等保合规
- 必须开启 --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
拓展思考
-
双栈与 SR-IOV
国内运营商已强制 IPv6 单栈上线,可在 cilium-lb.yaml 追加 enable-ipv6: true 并绑定 SR-IOV VF,利用 eBPF 的 TCX 新程序类型实现硬件卸载,降低 30% 延迟。 -
与 Docker Swarm 集成
若客户坚持 Swarm,可部署 cilium-operator-generic 监听 Swarm DNSRR endpoints,实现 “半自动” Service 声明,避免静态 YAML 维护成本。 -
故障演练
在生产环境使用 tc qdisc add dev eth0 clsact bpf obj drop_50_percent.o sec xdp 模拟 50% 丢包,验证 Cilium 的 sessionAffinity=ClientIP 在 eBPF map 老化后能否保持连接,满足金融客户 RPO=0 要求。