news 2026/9/13 11:46:14

Cilium 与 AWS VPC CNI 混合部署:CNI Chaining 模式下 eBPF 数据面接管实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cilium 与 AWS VPC CNI 混合部署:CNI Chaining 模式下 eBPF 数据面接管实战指南

Cilium 与 AWS VPC CNI 混合部署:CNI Chaining 模式下 eBPF 数据面接管实战指南

【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium

在 AWS EKS 环境中,Cilium 通常以独占 CNI 的身份接管全部网络数据面,但并非所有场景都适合一步到位地完成迁移。本文基于 Cilium 官方安装指南(Documentation/installation/cni-chaining-aws-cni.rst),完整讲解"混合模式":由 AWS VPC CNI 插件继续负责 Pod 虚拟网卡创建与基于 ENI 的 IP 地址分配(IPAM),Cilium 仅作为 CNI 链(chaining)的下游插件被调用,将 eBPF 程序挂载到 AWS VPC CNI 已建好的网络设备上,从而在不改变现有 Pod 网络模型的前提下启用网络策略、负载均衡与加密能力。读完本文,你将掌握该模式的 Helm 部署参数、存量 Pod 的识别与重启方法,以及 EKS "security groups for pods" 特性的配套启用步骤。

混合模式的工作原理

在 Cilium 与 AWS VPC CNI 的混合部署中,两个 CNI 插件各司其职,职责边界非常清晰:

  • AWS VPC CNI 插件:负责创建 Pod 的虚拟网络设备(veth 对),并通过 ENI(Elastic Network Interface)完成 IPAM,即 Pod 直接使用 VPC 内的 ENI IP 地址;
  • Cilium CNI 插件:在网络设备就绪后被链式调用(chained call),将 eBPF 程序挂载到上述设备上,执行网络策略(policy enforcement)、服务负载均衡(load-balancing)以及(可选的)流量加密。

从源码可以确认这一"链式接管"的具体实现。Cilium CNI 插件在启动时通过init()函数把aws-cni这一 chaining mode 注册到全局的 chaining API 中,其处理逻辑直接复用通用 veth chainer:

// plugins/cilium-cni/chaining/awscni/aws-cni.go func init() { chainingapi.Register("aws-cni", &genericveth.GenericVethChainer{}) }

而在 generic-veth chainer 的实现中,针对 AWS CNI 场景构造 endpoint 时明确设置了四项数据面配置,精确对应了"只接管 eBPF、不接管网络"的职责划分:

// plugins/cilium-cni/chaining/generic-veth/generic-veth.go DatapathConfiguration: &models.EndpointDatapathConfiguration{ // aws-cni requires ARP passthrough between Linux and // the pod RequireArpPassthrough: true, // The route is pointing directly into the veth of the // pod, install a host-facing egress program to // implement ingress policy and to provide reverse NAT RequireEgressProg: true, // The IP is managed by the aws-cni plugin, no need for // Cilium to manage any aspect of addressing ExternalIpam: true, // All routing is performed by the Linux stack RequireRouting: &disabled, },

逐项解读:

配置项取值含义
RequireArpPassthroughtrueLinux 宿主机与 Pod 之间需要 ARP 直通,因为 Pod 的 IP 是 VPC 内真实可路由的地址
RequireEgressProgtrue路由直接指向 Pod veth,需在宿主机侧安装 host-facing egress 程序来实现 ingress 策略与反向 NAT
ExternalIpamtrueIP 由 AWS VPC CNI 管理,Cilium 完全不介入地址分配
RequireRouting禁用所有路由均由 Linux 协议栈完成,Cilium 不安装自己的路由表

此外,由于 AWS VPC CNI 会在 iptables 中创建自己的规则(例如 conntrack 跟踪 Pod IP),Cilium 在 iptables 数据面实现中专门识别了aws-cnichaining mode,对形如eni621c0fc8425的容器接口名称做特殊处理,避免与 AWS CNI 的规则冲突。Helm chart 也提供了配套开关cni.iptablesRemoveAWSRules(默认true),用于在部署时移除 AWS CNI 插件创建的 iptables 规则。

功能限制:混合模式能做什么、不能做什么

在动手之前必须先明确边界。根据文档中引用的cni-chaining-limitations.rst,与其他 CNI 插件链式部署时,部分 Cilium 高级功能会受到限制,明确列出受限能力的有:

  • L7 网络策略(Layer 7 Policy)
  • IPSec 加密(encryption)

因此,如果你需要这些高级能力,文档给出的建议是彻底迁移到 Cilium 独占模式(即完全替换 AWS VPC CNI),而不是长期停留在 chaining 模式。

前置条件:准备 EKS 集群并升级 AWS VPC CNI

1. 创建集群

可以参照 Cilium 文档中的 EKS 快速安装指南(Documentation/installation/k8s-install-eks.rst对应章节k8s_install_quick)来创建集群,也可以使用任意你熟悉的方式(Terraform、eksctl 等)在 AWS 上部署 Kubernetes 集群。

需要确认两点:

  • aws-vpc-cni-k8s插件已安装——如果集群是通过 EKS 控制台/API 创建的,这通常是默认状态;
  • 插件版本足够新。

2. 检查并升级 AWS VPC CNI 版本(关键前提)

文档明确要求:AWS VPC CNI 插件版本必须为 1.11.2 或更高,才能保证与 Cilium 的兼容性。检查当前版本:

$ kubectl -n kube-system get ds/aws-node -o json | jq -r '.spec.template.spec.containers[0].image' 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni:v1.11.2

如果输出版本低于 1.11.2,通过 apply AWS 官方发布清单进行升级:

$ kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/release-1.11/config/master/aws-k8s-cni.yaml

提示:aws-node是 AWS VPC CNI 以 DaemonSet 形式在kube-system命名空间运行的工作负载,每个节点一个副本,Cilium 的 chaining 逻辑将直接作用于它创建的网络设备。

3. 下载 Cilium 发行版

按 Cilium 标准的 Kubernetes 安装流程下载所需版本的 Cilium 发布包(对应文档中的k8s-install-download-release.rst章节),后续 Helm 安装将从本地 chart 目录部署。

通过 Helm 部署 Cilium:四个关键参数

下载完成后,以本地 chart 目录为源执行 Helm 安装:

helm install cilium cilium/cilium \ --namespace kube-system \ --set cni.chainingMode=aws-cni \ --set cni.exclusive=false \ --set enableIPv4Masquerade=false \ --set routingMode=native

这组参数就是混合模式的核心配置,逐一说明其作用:

参数取值作用与原理
cni.chainingModeaws-cni声明 Cilium 以 chaining 方式运行在 AWS VPC CNI 之上。在 Helm chart 的 values.yaml中,cni.chainingMode的合法取值为noneaws-cniflannelgeneric-vethportmap;同时 chart 注释指出一个特殊约定:"chaining mode of aws-cni implies a chainingTarget of aws-cni",即设置了该模式后无需再显式指定cni.chainingTarget
cni.exclusivefalse关闭 Cilium 对/etc/cni/net.d的独占接管。默认(exclusive: true)时 Cilium 会把非 Cilium 的 CNI 配置重命名为*.cilium_bak;混合模式下必须保留 AWS VPC CNI 的配置(10-aws.conflist)生效,因此要设为false
enableIPv4Masqueradefalse关闭 masquerade(SNAT)。原因是 ENI IP 地址在 VPC 内本来就可以直接路由,Pod 流量无需再改写源地址
routingModenative使用原生路由模式,同样因为隧道(tunnel)在此场景下没有必要——ENI IP 可在 VPC 中直接寻址

部署完成后,Cilium 的 Helm 校验逻辑(见 validate.yaml 模板)会对 chaining 配置做一致性检查,确保chainingMode与集群中实际存在的 CNI 配置相匹配。

重启存量 Pod:chaining 配置为何不会追溯生效

这是部署流程中最容易被忽略、却直接影响功能正确性的一步。文档明确警告:

新的 CNI chaining 配置不会作用于集群中已经在运行的任何 Pod。

对于存量 Pod,其网络状态是:

  • Pod 仍然可达
  • Cilium 能对其做负载均衡(tothem);
  • 但从 Pod 发出的流量不走Cilium 数据面(notfromthem),策略强制执行同样不生效。

原因是 eBPF 程序只在 CNI ADD 事件时挂载到接口上,存量 Pod 的接口早已由 AWS VPC CNI 单独创建,Cilium 从未被调用过。因此必须重启这些 Pod,让 kubelet 重新触发 CNI 调用链,Cilium 才有机会将 eBPF 程序挂上去。

官方提供的检测脚本用于找出"有 Pod 但尚无对应 Cilium endpoint(CEP)"的对象——Cilium endpoint 的 CustomResource(ciliumendpoint,缩写cep)只有在本插件成功处理过该 Pod 后才会生成:

for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do ceps=$(kubectl -n "${ns}" get cep \ -o jsonpath='{.items[*].metadata.name}') pods=$(kubectl -n "${ns}" get pod \ -o custom-columns=NAME:.metadata.name,NETWORK:.spec.hostNetwork \ | grep -E '\s(<none>|false)' | awk '{print $1}' | tr '\n' ' ') ncep=$(echo "${pods} ${ceps}" | tr ' ' '\n' | sort | uniq -u | paste -s -d ' ' -) for pod in $(echo $ncep); do echo "${ns}/${pod}"; done done

脚本逻辑解读:

  1. 遍历所有命名空间;
  2. 分别取出该命名空间下的 Cilium endpoint 名称集合(ceps)与非 hostNetwork Pod 名称集合(pods);
  3. sort | uniq -u做差集运算,剩下的就是"有 Pod 却没有 endpoint"的存量 Pod;
  4. 逐条输出namespace/pod-name,供你执行kubectl -n <ns> delete pod <pod>触发重建(由 Deployment/StatefulSet 等控制器自动拉起新实例,新实例将完整走一遍 CNI 链)。

重启完成后,每个新建 Pod 都应有对应的 CEP 资源,且cilium status中 endpoint 状态应为 ready。

验证安装

部署并重启存量 Pod 后,按 Cilium 标准流程验证(对应k8s-install-validate.rst):

方式一:Cilium CLI

# 查看整体状态:节点、agent、BPF 后端、策略引擎均应正常 cilium status --verbose # 运行端到端连通性测试套件,覆盖 L3/L4(及策略)转发路径 cilium connectivity test

方式二:kubectl 手动验证

# 确认每个节点上 cilium-agent 处于 Running 状态 kubectl -n kube-system get pods -l k8s-app=cilium -o wide # 手动构造两个测试 Pod 验证策略与转发 kubectl run client --image=quay.io/cilium/cilium:v1.17.0 --rm -it -- sh

在混合模式下重点观察:新创建的 Pod 是否生成了 CEP、跨节点 Pod 间流量是否经由 ENI IP 直连(而非隧道封装)、Service 负载均衡是否由 Cilium 完成(节点上不应再依赖 kube-proxy 处理 Cilium 管理的 endpoint)。

进阶:为 Pod 启用 EKS Security Groups(SGP)

在支持 security groups for pods(SGP)特性的 EKS 集群上,Cilium 的 chaining 模式可以与该特性共存。SGP 允许直接给 Pod 关联 AWS 安全组,从而把网络准入控制的一部分下沉到 AWS VPC 层。启用步骤如下(前置要求:本机已安装并配置好jq与 AWS CLI)。

步骤 1:为 EKS 集群角色附加 IAM 托管策略

AmazonEKSVPCResourceController策略附加到集群的 IAM 角色:

export EKS_CLUSTER_NAME="my-eks-cluster" # Change accordingly export EKS_CLUSTER_ROLE_NAME=$(aws eks describe-cluster \ --name "${EKS_CLUSTER_NAME}" \ | jq -r '.cluster.roleArn' | awk -F/ '{print $NF}') aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController \ --role-name "${EKS_CLUSTER_ROLE_NAME}"

步骤 2:确认 AWS VPC CNI 版本足够新

SGP 特性要求较新的aws-node版本(1.7.10 及以上,而本文前述的 Cilium 兼容性要求是 1.11.2+,满足其一即可同时满足两者):

kubectl -n kube-system get ds/aws-node \ -o jsonpath='{.spec.template.spec.containers[0].image}' 602401143452.dkr.ecr.us-west-2.amazonaws.com/amazon-k8s-cni:v1.7.10

步骤 3:Patchaws-nodeDaemonSet 开启 Pod ENI

kubectl -n kube-system patch ds aws-node \ -p '{"spec":{"template":{"spec":{"initContainers":[{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}],"containers":[{"env":[{"name":"ENABLE_POD_ENI","value":"true"}],"name":"aws-node"}]}}}}' kubectl -n kube-system rollout status ds aws-node

两个环境变量分别的作用:

  • ENABLE_POD_ENI=true(注入aws-node容器):开启 trunk ENI 上的 member ENI 分配,即每个 Pod 获得独立的 member ENI,从而可以单独关联安全组;
  • DISABLE_TCP_EARLY_DEMUX=true(注入aws-vpc-cni-init容器):禁用 TCP early demux sysctl,保证 trunk ENI 的流转发行为正确。

步骤 4:验证 trunk 挂载

rollout 完成后,所有节点应带有vpc.amazonaws.com/has-trunk-attached: "true"标签:

kubectl get nodes -L vpc.amazonaws.com/has-trunk-attached NAME STATUS ROLES AGE VERSION HAS-TRUNK-ATTACHED ip-192-168-111-169.eu-west-2.compute.internal Ready <none> 22m v1.19.6-eks-49a6c0 true ip-192-168-129-175.eu-west-2.compute.internal Ready <none> 22m v1.19.6-eks-49a6c0 true

至此,Cilium chaining 与 SGP 两条能力同时就绪:Pod 层面由 AWS 安全组做第一道边界,Cilium 在其上叠加 L3/L4 策略与服务级负载均衡。具体如何把安全组关联到 Pod(通过 Pod 注解vpc.amazonaws.com/pod-assign-eni-classvpc.amazonaws.com/pod-security-group-ids),按 AWS EKS 官方 SGP 文档操作即可——这部分是 AWS 平台侧配置,与 Cilium 配置相互独立。

小结:混合模式的能力边界与迁移决策

把整个部署流程串起来:

  1. 准备 EKS 集群,确认aws-vpc-cni-k8s≥ 1.11.2(不足则 apply 官方清单升级);
  2. Helm 安装 Cilium,设置cni.chainingMode=aws-cnicni.exclusive=falseenableIPv4Masquerade=falseroutingMode=native
  3. 用"Pod 与 CEP 差集"脚本找出存量 Pod 并逐个重启;
  4. cilium status/cilium connectivity test验证数据面接管效果;
  5. (可选)按 SGP 四步流程叠加 Pod 级 AWS 安全组。

源码层面,这一模式的本质是GenericVethChainer配合ExternalIpam + RequireArpPassthrough + RequireEgressProg的数据面配置,让 Cilium 只挂程序、不碰 IPAM 和路由。需要牢记的限制是:L7 策略与 IPSec 加密在 chaining 模式下受限。如果你的业务依赖这两项能力,混合模式只应作为过渡方案,最终目标是迁移到 Cilium 独占模式——届时cni.chainingMode回退为noneroutingMode可选nativevxlan,Cilium 将完整接管从 IPAM 到策略执行的全部职责。

【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 11:43:46

Symfony框架核心特性与PHP企业级开发实践

1. Symfony框架概述与核心特性Symfony是一个基于PHP语言的成熟Web应用框架&#xff0c;自2005年发布以来已成为企业级开发的标准选择。这个全栈框架采用模块化组件设计&#xff0c;其核心思想是"约定优于配置"&#xff0c;同时保持高度的灵活性。与其他PHP框架相比&a…

作者头像 李华
网站建设 2026/9/13 11:43:42

PIC12F675 ADC寄存器配置与采样稳定性实战

简介&#xff1a;本资源是面向嵌入式初学者与PIC单片机开发者的PIC12F675微控制器ADC功能实践例程&#xff0c;聚焦模拟信号采集核心需求&#xff0c;适用于温度检测、电位器读取、传感器数据采集等典型应用场景。压缩包共21个文件&#xff0c;涵盖C源码&#xff08;ADC.C&…

作者头像 李华
网站建设 2026/9/13 11:43:12

国产ScaleFabric400网络技术解析与AI集群应用

1. 国产自研网络ScaleFabric400的技术突破在万卡级AI训练集群中&#xff0c;网络通信耗时占比往往超过30%&#xff0c;传统TCP/IP协议栈的传输效率成为制约算力释放的瓶颈。中科曙光推出的ScaleFabric400网络方案通过三大核心技术实现了质的突破&#xff1a;1.1 全栈自主架构设…

作者头像 李华
网站建设 2026/9/13 11:42:54

Kingfisher 出现 notCurrentSourceTask 错误时图片是否已下载缓存?

Kingfisher 出现 notCurrentSourceTask 错误时图片是否已下载缓存&#xff1f; 【免费下载链接】Kingfisher A lightweight, pure-Swift library for downloading and caching images from the web. 项目地址: https://gitcode.com/GitHub_Trending/ki/Kingfisher 在 Ki…

作者头像 李华
网站建设 2026/9/13 11:42:30

消费电子ESD整改实战:三层防御体系设计与落地

1. 从“啪”一声到整机黑屏&#xff1a;这副耳机的ESD问题不是偶然&#xff0c;是设计链上的系统性失守你有没有过这样的经历——刚摘下耳机&#xff0c;手指碰到金属耳罩边缘&#xff0c;“啪”地一声脆响&#xff0c;手心一麻&#xff1b;下一秒&#xff0c;耳机RGB灯带突然熄…

作者头像 李华