cilium取代kube-proxy

参考文档:https://docs.cilium.io/en/v1.17/network/kubernetes/kubeproxy-free/#kubeproxy-free

Kubernetes Without kube-proxy

备注:

Cilium的kube-proxy替换依赖于socket-LB功能,该功能需要v4.19.57、v5.1.16、v5.2.0或更高版本的Linux内核。Linux内核v5.3和v5.8添加了Cilium可以用来进一步优化kube-proxy替换实现的附加功能。 请注意,v5.0.y内核没有运行kube-proxy替换所需的修复程序,因为此时v5.0.y稳定内核已经报废(EOL),不再在kernel.org上维护。对于单个发行版维护的内核,情况可能会有所不同。因此,请与您的发行版核对。

通过kubeadm init初始化控制平面节点,跳过kube-proxy的安装:

kubeadm init --skip-phases=addon/kube-proxy  --config /root/kubeadm-config.yaml

根据使用的CRI实现,可能需要在kubeadm init..中使用-cri-socket标志。例如:如果正在使用Docker CRI,将使用--cri-socket unix:/var/run/cri-dockerd.sock。

如果node有多个接口,请确保在每个worker上正确设置kubelet的--node-ip。否则,Cilium的kube-proxy替换可能无法正常工作。可以通过运行kubectl get nodes -o wide来验证这一点,以查看每个节点是否都有一个分配给每个节点上同名设备的InternalIP。

删除kube-proxy

$ kubectl -n kube-system delete ds kube-proxy
$ # Delete the configmap as well to avoid kube-proxy being reinstalled during a Kubeadm upgrade (works only for K8s 1.19 and newer)
$ kubectl -n kube-system delete cm kube-proxy
$ # Run on each node with root permissions:
$ iptables-save | grep -v KUBE | iptables-restore

注意,移除kube-proxy会中断现有的服务连接。在安装Cilium替代方案之前,与服务相关的流量也会停止。

安装

cilium install \
--set kubeProxyReplacement=strict \
--set tunnel=disabled \
--set routingMode=native \
--set autoDirectNodeRoutes=true \ #必须所有节点在同一 L2层,通过ARP实现节点间直接通信,跨子网需禁用
--set bpf.masquerade=true \
--set bpf.hostRouting=true \ # 启用 eBPF 主机路由(内核 ≥5.10)
--set ipv4NativeRoutingCIDR=10.244.0.0/16 \
--set ipam.mode=cluster-pool | kubernetes \
--set ipam.operator.clusterPoolIPv4PodCIDRList=10.244.0.0/16 \
--set ipam.operator.clusterPoolIPv4MaskSize=24 \
--set loadBalancer.acceleration=native \
--set hubble.enabled=true \
--set hubble.ui.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.metrics.enabled="{dns,drop,tcp,flow,icmp,http}" \
--set prometheus.enabled=true \
--set operator.prometheus.enabled=true \
--set hubble.metrics.serviceMonitor.enabled=true \
--version 1.17.5

参数说明:

kubeProxyReplacement=strict

  • 作用完全替代 kube-proxy,使用 eBPF 实现 Kubernetes Service 的负载均衡(ClusterIP/NodePort/LoadBalancer)

  • 机制

    • 将 Service 的 IP:Port 映射注入 eBPF Map(cilium_lb

    • 在 TC(Traffic Control)层 直接重写数据包目标地址(DNAT)

  • 优势

    • 性能提升 2-3 倍(绕过 iptables 和内核协议栈)

    • 支持 DSR(Direct Server Return)模式(保留客户端源 IP)

  • 要求:内核 ≥ 5.7

 

tunnel=disabled

  • 作用禁用 VXLAN/Geneve 隧道封装,使用原生三层路由

  • 机制

    • 不再生成 cilium_vxlan 虚拟设备

    • 跨节点流量以 原始 Pod IP 传输(无额外 IP/UDP 头)

  • 优势

    • 零封装开销(带宽利用率提升 20%)

    • 延迟降低 15-30%(减少封包/解包 CPU 消耗)

  • 要求:需配合 routingMode=native 和路由发布机制

 

routingMode=native

  • 作用:启用 Native 路由模式,集成底层网络设施

  • 机制

    • 依赖 ipv4NativeRoutingCIDR 定义直连 CIDR

    • 通过以下方式发布路由:

      • 云环境:与 CCM 集成发布到 VPC 路由表

      • 物理网络:通过 BGP 或静态路由发布

  • 优势

    • 实现 Pod IP 全局可达(无需 SNAT)

    • 支持与 VM/物理服务器直接通信

 

autoDirectNodeRoutes=true

  • 作用自动管理节点直连路由

  • 机制

    • 为每个节点添加 /32 主机路由(通过 ip route 查看)

    10.0.2.101 dev eth0  # 节点A
    10.0.2.102 dev eth0  # 节点B
    • 结合 ARP 协议实现 同子网节点直连

  • 限制

    • 仅适用于 节点在同一 L2 网络

    • 跨子网场景需禁用此参数(改用 BGP/静态路由)

 

bpf.masquerade=true

  • 作用:启用 基于 eBPF 的 IP 伪装(SNAT)

  • 机制

    • 替换 iptables MASQUERADE 规则

    • 在 eBPF 层动态修改源 IP:

      • Pod 访问外部网络 → SNAT 为节点 IP

      • 外部访问 NodePort → SNAT 为节点 IP(可选 DSR 规避)

  • 优势

    • 性能提升 40%(避免 iptables 锁竞争)

    • 支持 IP 伪装排除规则(如 --set bpf.masqueradeExcludeCIDRs

  • 验证命令

    cilium bpf nat list

 

bpf.hostRouting=true

  • 作用启用 eBPF 主机路由加速

  • 机制

    • 绕过内核协议栈

    • 通过 bpf_redirect_neigh() 直接重定向数据包

  • 效果

    • 降低延迟 50%

    • 提升吞吐量 30%

    • 要求:内核 ≥5.10 + 网卡驱动支持

 

ipv4NativeRoutingCIDR

这个参数用于指定一个或多个IPv4 CIDR范围,Cilium将对这些范围内的目标使用本地路由(而不是隧道封装)。当流量目标位于这些CIDR范围内时,Cilium不会进行封装(如VXLAN或IPIP),而是直接通过节点的网络接口路由。

作用:

声明需原生路由(非隧道)的 CIDR 范围,用于:

  1. 绕过隧道封装(VXLAN/IPIP)

  2. 与云厂商 CCM 集成发布路由

  3. 直连物理网络设备

 

ipam.mode=cluster-pool | kubernetes

核心作用

  • 自主 IP 地址管理:Cilium Operator 完全掌控 Pod IP 的分配,不依赖 Kubernetes 原生机制

  • 多网段支持:允许定义多个隔离的 IP 池(如 10.244.0.0/16,172.16.0.0/12

  • 动态子网分配:按需为节点划分子网,实现弹性 IP 资源管理

关键优势

特性 传统模式 cluster-pool 模式
IP 分配权 kube-controller-manager Cilium Operator
多网段支持  单个 CIDR 多个 CIDR
动态扩容 需重启控制平面 实时添加新 CIDR
跨集群协调 复杂 通过 CRD 全局管理
最大节点数 受限于初始 CIDR 无限制

多网段场景配置

cilium install \
  --set ipam.mode=cluster-pool \
  --set ipam.operator.clusterPoolIPv4PodCIDRList='10.244.0.0/16,172.16.0.0/12' \
  --set ipam.operator.clusterPoolIPv4MaskSize=24 \
  --set ipv4NativeRoutingCIDR='10.244.0.0/16,172.16.0.0/12'

模式对比

特性 ipam.mode=kubernetes ipam.mode=cluster-pool
IP 来源 v1.Node.spec.podCIDR CiliumNode.spec.ipam.pool
控制平面 kube-controller-manager Cilium Operator
云集成 自动 (CCM) 需手动发布路由
故障域 单 CIDR 可跨多 CIDR
适用规模 ≤200 节点 ≥500 节点集群

动态添加新 CIDR

  1. 修改 Helm values:

    ipam:
      operator:
        clusterPoolIPv4PodCIDRList: "10.244.0.0/16,172.16.0.0/12"  # 新增CIDR
  2. 滚动更新:

    helm upgrade cilium cilium/cilium -f values.yaml

典型使用场景

  1. 混合云部署

    • 本地 DC:10.244.0.0/16

    • 公有云:172.16.0.0/12

  2. 业务隔离

    # 开发环境
    clusterPoolIPv4PodCIDRList: "10.1.0.0/16"
    # 生产环境
    clusterPoolIPv4PodCIDRList: "10.2.0.0/16"
  3. IP 耗尽扩容

    • 初始:10.244.0.0/16

    • 扩容:新增 172.16.0.0/12 无需重启集群

最佳实践:在私有云/混合云中优先使用此模式,配合 routingMode=native 实现高性能网络平面。公有云环境建议使用 kubernetes 模式简化运维。

 

ipam.operator.clusterPoolIPv4PodCIDRList

这个参数用于定义集群中Pod使用的IPv4 CIDR范围列表。当使用`cluster-pool` IPAM模式时,Cilium Operator会从这个CIDR列表中为每个节点分配一个子网(由`clusterPoolIPv4MaskSize`指定大小)。然后,每个节点上的Cilium Agent将从分配给该节点的子网中为Pod分配IP地址。

作用:

定义集群级别的 IPv4 Pod CIDR 池,Operator 将从这个列表中为节点分配子网。

特点:

  • 支持多个 CIDR 块(逗号分隔)

  • 按顺序分配,前一个 CIDR 用尽后自动使用下一个

  • 需确保 CIDR 不与节点网络重叠

 

ipam.operator.clusterPoolIPv4MaskSize

作用:

设置每个节点的子网掩码大小,决定单个节点可分配的 Pod IP 数量。

计算逻辑:

  • 默认值:24(/24 子网 = 256 个 IP)

  • 可用 IP 数 = 2^(32 - maskSize) - 2(减2是去掉网络和广播地址)

  • 示例:

    maskSize=24254 个可用 IP
    maskSize=2662 个可用 IP

hubble.enabled=true: 启用 Hubble 可观测性

hubble.ui.enabled=true: 启用 Hubble UI

hubble.relay.enabled=true: 启用 Hubble Relay 聚合服务

hubble.metrics.enabled: 启用的 Hubble 指标类型

prometheus.enabled=true: 启用 Cilium Prometheus 指标

operator.prometheus.enabled=true: 启用 Cilium Operator 指标

hubble.metrics.serviceMonitor.enabled=true: 为 Prometheus 创建 ServiceMonitor

注意事项

  1. CIDR 规划冲突

    • 确保 clusterPoolIPv4PodCIDRList 不与 Service CIDR 或节点网络重叠

    • 检查命令:

      kubectl cluster-info dump | grep -E 'service-cluster-ip-range|cluster-cidr'
  2. MaskSize 与节点规模

    • 示例:10.244.0.0/16 + maskSize=26 → 1024 节点

  3. 云厂商特殊要求

    • 阿里云:ipv4NativeRoutingCIDR 需与 VPC 路由表兼容(通常为 /16 或更大)

    • AWS:需额外配置 --set enable-endpoint-routes=true

CIDR参数对比

特性 ipam.operator.clusterPoolIPv4PodCIDRList ipv4NativeRoutingCIDR
作用 定义 Pod IP 地址池范围(IP 分配来源) 定义 需原生路由的 CIDR 范围(流量转发规则)
影响对象 Cilium Operator(IP 分配管理) Cilium Agent(数据包转发决策)
配置位置 Helm 的 ipam.operator 子项 Helm 的全局参数
默认值 无(必须显式设置) 无(必须显式设置)
依赖关系 需要 ipam.mode=cluster-pool 需要 tunnel=disabled 或 routingMode=native
典型场景 自定义 Pod IP 范围 云厂商集成/物理网络直连

 

参数组合效果图示

查看部署情况

# k -n kube-system get pods -l k8s-app=cilium
NAME                READY     STATUS    RESTARTS   AGE
cilium-d5zhp        1/1       Running   0          10m
cilium-mtvdp        1/1       Running   0          10m

验证安装程序

# kubectl -n kube-system exec ds/cilium -- cilium-dbg status --verbose
[...]
KubeProxyReplacement Details:
Status: True
Socket LB: Enabled
Protocols: TCP, UDP
Devices: eth0 (Direct Routing), eth1
Mode: SNAT
Backend Selection: Random
Session Affinity: Enabled
Graceful Termination: Enabled
NAT46/64 Support: Enabled
XDP Acceleration: Disabled
Services:
- ClusterIP: Enabled
- NodePort: Enabled (Range: 30000-32767)
- LoadBalancer: Enabled
- externalIPs: Enabled
- HostPort: Enabled
[...]

 

状态:

KubeProxyReplacement Details:
  Status:                True

 

样例

创建一个Nginx部署。然后,我们将创建一个新的NodePort服务,并验证Cilium是否正确安装了该服务。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80

 

kubectl expose deployment my-nginx --type=NodePort --port=80

在Cilium-dbg service list命令的帮助下,我们可以验证Cilium的EBPF kube-proxy替换是否创建了新的NodePort服务。在此示例中,创建了端口为31940的服务(设备eth0和eth1各一个):

# kubectl -n kube-system exec ds/cilium -- cilium-dbg service list
ID   Frontend               Service Type   Backend
[...]
4    10.104.239.135:80/TCP      ClusterIP      1 => 10.217.0.107:80/TCP
                                               2 => 10.217.0.149:80/TCP
5    0.0.0.0:31940/TCP          NodePort       1 => 10.217.0.107:80/TCP
                                               2 => 10.217.0.149:80/TCP
6    192.168.178.29:31940/TCP   NodePort       1 => 10.217.0.107:80/TCP
                                               2 => 10.217.0.149:80/TCP
7    172.16.0.29:31940/TCP      NodePort       1 => 10.217.0.107:80/TCP
                                               2 => 10.217.0.149:80/TCP

我们可以使用主机名称空间中的iptables验证该服务不存在iptables规则:

# iptables-save | grep KUBE-SVC
[ empty line ]