cilium取代kube-proxy
- cilium
- 2025-07-23
- 55热度
- 0评论
参考文档: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 范围,用于:
-
绕过隧道封装(VXLAN/IPIP)
-
与云厂商 CCM 集成发布路由
-
直连物理网络设备
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:
-
修改 Helm values:
ipam: operator: clusterPoolIPv4PodCIDRList: "10.244.0.0/16,172.16.0.0/12" # 新增CIDR
-
滚动更新:
helm upgrade cilium cilium/cilium -f values.yaml
典型使用场景
-
混合云部署:
-
本地 DC:
10.244.0.0/16
-
公有云:
172.16.0.0/12
-
-
业务隔离:
# 开发环境 clusterPoolIPv4PodCIDRList: "10.1.0.0/16" # 生产环境 clusterPoolIPv4PodCIDRList: "10.2.0.0/16"
-
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=24 → 254 个可用 IP maskSize=26 → 62 个可用 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
注意事项
-
CIDR 规划冲突
-
确保
clusterPoolIPv4PodCIDRList
不与 Service CIDR 或节点网络重叠 -
检查命令:
kubectl cluster-info dump | grep -E 'service-cluster-ip-range|cluster-cidr'
-
-
MaskSize 与节点规模
-
示例:
10.244.0.0/16
+maskSize=26
→ 1024 节点
-
-
云厂商特殊要求
-
阿里云:
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 ]