Cilium IPAM 技术深潜:容器网络控制流与多模式地址管理全景解析

Cilium IPAM 技术深潜:容器网络控制流与多模式地址管理全景解析 Cilium IPAM 技术深潜容器网络控制流与多模式地址管理全景解析【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium导读本文围绕 Cilium 官方文档 Technical Deep Dive 中的核心控制流图展开系统梳理 Cilium IP 地址管理IPAM从容器创建到 IP 分配完成的完整链路CNI 插件如何触发分配、agent 如何根据--ipam配置选择后端、各后端Kubernetes Host Scope、ClusterPool/Multi-Pool、CRD、AWS ENI、Azure、GKE如何协同 Operator 与自定义资源完成地址分配。读者阅读后既能看懂控制流图中每条分支的走向与依据也能掌握各 IPAM 模式的启停配置、参数语义与排障手段形成从容器要 IP到IP 落网卡的全链路认知。一、总览Cilium 的 IP 地址管理IPAM是什么IP 地址管理IP Address ManagementIPAM负责为 Cilium 所管理的网络端点容器及其他分配和管理 IP 地址。根据官方 IPAM 索引文档Cilium 支持多种 IPAM 模式以适配不同用户场景其能力差异可用下表概括特性Kubernetes Host ScopeCluster Scope默认Multi-PoolCRD-backedAWS ENIAzure IPAMGKETunnel 路由✅✅✅❌❌❌❌Direct 路由✅✅✅✅✅✅✅CIDR 配置方KubernetesCiliumCilium外部外部AWS外部Azure外部GCP每集群多 CIDR❌✅✅N/AN/AN/AN/A每节点多 CIDR❌❌✅N/AN/AN/AN/A动态 CIDR/IP 分配❌❌✅✅✅✅❌重要约束除遵循文档化迁移流程外不要变更现有集群的 IPAM 模式。在运行环境中切换 IPAM 模式可能对存量工作负载造成持续连接中断最安全的路径是使用新 IPAM 配置安装全新的 Kubernetes 集群。当前唯一可用的在线迁移路径是 cluster-pool → multi-pool详见 cluster-pool-to-multi-pool.rst。所有 IPAM 模式的公共底座是一致的当 Kubernetes 调度器把 Pod 放到某个节点后kubelet 通过 CRI 调用 CNI 插件CNI 插件再触发 Cilium agent 的 IPAM 模块从对应后端取 IP。模式之间的差异本质上只在于节点级地址池PodCIDR从哪来、由谁管理、如何增长。这正是 deep_dive.rst 中控制流图想要表达的核心思想。二、容器网络控制流一次完整的 IP 分配之旅上图cilium_container_networking_control_flow.png是理解 Cilium IPAM 的钥匙。它把整个控制流拆解为四个阶段2.1 阶段一容器创建与 CNI 触发Kubelet → CRIkubelet 通过容器运行时接口CRI如 containerd发出Create container请求CRI → Cilium CNI PluginCRI 在创建容器命名空间并识别网络后调用 Cilium CNI 插件CNI Plugin → CNI AgentCNI 插件执行cmdAdd()添加网络/cmdDel()删除网络将控制权交给 Cilium agent 侧的网络配置逻辑CNI Agent → IPAMagent 首先检查 Cilium 配置中的ipam选项根据其取值决定走哪条分配分支。这一步在源码中同样可循agent 的 IPAM 初始化入口 pkg/ipam/ipam.go 首先在cloudProviders中查找ipam.config.IPAMMode()对应的云厂商后端ENI/Azure 等找不到再落入switch分支依次处理kubernetes、cluster-pool、multi-pool等模式最终对未知模式返回unknown IPAM backend错误。而模式字符串常量定义在 pkg/ipam/option/option.gokubernetes、crd、eni、azure、cluster-pool、multi-pool、alibabacloud。2.2 阶段二IPAM 模式分支控制流核心控制流图以ipam配置为分水岭分出三类典型分支分支 1ClusterPool / Node CIDR默认配置-ipamclusterpool源码中实际取值为cluster-pool参见 option.go。默认基于 Kubernetes 节点子网Host-Subnet配合-allocate-node-cidrs让 Kubernetes 为节点分配 CIDR也可以由 Cloud-IPAM Service 拉取 IP 段再从集群节点 CIDR 中分配容器 IP。分支 2CRD 模式配置-ipamcrd使用用户或外部 operator在 CRD 中定义的 CIDRagent 从已分配的 IP 池中取 IP 返回给容器。分支 3ENI 等云模式配置-ipameni或azure等IP 段由云平台定义Operator 负责把该 IP 段写入CiliumNode的 CRD 字段agent 再据此分配。无论走哪条分支最终都由Cilium CNI Plugin → Container返回Container IP完成取 IP这一步。2.3 阶段三网络设备挂接拿到 IP 后CNI 插件继续完成数据面的最后一步Attach veth pair / ipvlan为容器绑定 veth 对或 ipvlan 网卡link up激活网络设备使容器网络可用。2.4 阶段四IP 状态回写IPAM 向 Cloud-IPAM Service或 Kubernetes/CRD 后端回写Used IP Status Update把已分配的 IP 标记为使用中供分配器后续做水印管理watermark与回收决策。这一分配—回写闭环正是各云模式维持节点级可用 IP 缓冲的关键。2.5 辅助机制自动创建 CiliumNode 资源图中还标注了auto-create-cilium-node-resource true这一关键开关当 agent 首次在某节点启动时自动创建与该节点同名的ciliumnodes.cilium.io自定义资源作为节点级 IPAM 信息的载体。CRD 模式、ENI 模式、Azure 模式都依赖这一机制详见下文各模式章节。三、Kubernetes Host Scope把分配权交给 KubernetesKubernetes Host Scope 文档 描述的是最贴近 K8s 原生的模式启用ipam: kubernetes把地址分配委托给集群内每个节点IP 从 Kubernetes 关联给节点的PodCIDR范围中分配。agent 启动时会等待 IPv4/IPv6 的 PodCIDR 通过以下任一路径就绪通过v1.Node资源字段spec.podCIDRsIPv4 和/或 IPv6或spec.podCIDR单栈。通过v1.NodeannotationAnnotation描述network.cilium.io/ipv4-pod-cidrIPv4 PodCIDR 范围network.cilium.io/ipv6-pod-cidrIPv6 PodCIDR 范围network.cilium.io/ipv4-cilium-hostcilium host 接口的 IPv4 地址network.cilium.io/ipv6-cilium-hostcilium host 接口的 IPv6 地址network.cilium.io/ipv4-health-ipcilium-health 端点的 IPv4 地址network.cilium.io/ipv6-health-ipcilium-health 端点的 IPv6 地址network.cilium.io/ipv4-Ingress-ipcilium-ingress 端点的 IPv4 地址network.cilium.io/ipv6-Ingress-ipcilium-ingress 端点的 IPv6 地址注annotation 机制主要适用于尚不支持spec.podCIDRs、但已启用双栈的较老 Kubernetes 版本。关键前提必须让kube-controller-manager携带--allocate-node-cidrs标志Kubernetes 才会分配 PodCIDR 范围。配置方式ConfigMap 选项说明ipam: kubernetes启用 Kubernetes IPAM自动联动enable-ipv4true时自动开启k8s-require-ipv4-pod-cidrenable-ipv6true时自动开启k8s-require-ipv6-pod-cidrk8s-require-ipv4-pod-cidr: true让 agent 等待 Kubernetes node 资源暴露 IPv4 PodCIDRk8s-require-ipv6-pod-cidr: true让 agent 等待 Kubernetes node 资源暴露 IPv6 PodCIDRHelm 等价写法--set ipam.modekubernetes、--set k8s.requireIPv4PodCIDRtrue、--set k8s.requireIPv6PodCIDRtrue后两者仅与ipam.modekubernetes配合生效。四、Cluster Scope默认由 Operator 管理节点 PodCIDRCluster Scope 文档 说明默认的 cluster-pool 模式为每个节点分配 per-node PodCIDR并在各节点用 host-scope 分配器分配 IP。它与 Kubernetes Host Scope 的差别在于不是由 Kubernetes 通过v1.Node分配 per-node PodCIDR而是由 Cilium operator 通过v2.CiliumNode资源管理。优势是不依赖 Kubernetes 配置下发 per-node PodCIDR当 Kubernetes 无法下发 PodCIDR 或需要更多控制权时非常有用。该模式下agent 启动时会等待v2.CiliumNode对象中按地址族启用的podCIDRs就绪字段描述spec.ipam.podCIDRsIPv4 和/或 IPv6 PodCIDR 范围扩容集群池的纪律不要修改clusterPoolIPv4PodCIDRList中已存在的元素否则会产生意外行为池耗尽时应追加新元素最小掩码长度为/30建议至少/29。原因分配器为每个 CIDR 块保留 2 个 IP网络地址与广播地址clusterPoolIPv4MaskSize同样不可更改。排障命令查看节点级 IPAM 分配错误Error字段位于status.ipam.operator-statuskubectl get ciliumnodes -o jsonpath{range .items[*]}{.metadata.name}{\t}{.status.ipam.operator-status}{\n}{end}节点 CIDR 冲突检查默认 Pod CIDR 为10.0.0.0/8。若节点网络处于同一范围会丢失到其他节点的连通性——所有出口流量都会被误判为发往本节点上的 Pod。两种解法显式把clusterPoolIPv4PodCIDRList设置为不冲突的 CIDR或为节点使用不同的 CIDR。五、Multi-Pool按标签与注解从多个池取地址Multi-Pool 文档 展示了一个更灵活的模型根据工作负载注解和节点标签从多个不同 IPAM 池分配 PodCIDR。它是对 cluster-pool 能力的扩展支持每集群/每节点多 CIDR 与动态 CIDR 分配。池选择的优先级顺序显式注解指定在 Pod 或其命名空间上使用ipam.cilium.io/ip-poolpool-name注解IPv4/IPv6 可分别用ipam.cilium.io/ipv4-poolpool-name和ipam.cilium.io/ipv6-poolpool-name指定不同池。标签选择器通过spec.podSelector和/或spec.namespaceSelector定义哪些 Pod 可从该池取 IP两者都定义时需同时匹配。此外还可匹配 Cilium 附加的两个合成标签io.kubernetes.pod.namespacePod 命名空间、io.kubernetes.pod.namePod 名称。若分配时池尚不可知竞态或配置错误Pod 会回退到 default 池若希望阻止此行为可设置ipam.cilium.io/require-pool-matchtrue注解直到 Pod 匹配上非默认池才放行分配。一个 Pod 在给定 IP 族上必须恰好匹配一个池匹配多个池会导致分配失败并记录错误因此务必避免池之间选择器重叠。兜底 default 池无显式注解、也不匹配任何选择器时从名为default的池分配。注意注解只在 Pod 创建时生效修改运行中 Pod 的ip-pool注解无效。CiliumNode 扩展与 CiliumPodIPPool CRDMulti-Pool 模式下CiliumNode资源新增spec.ipam.pools段spec.ipam.pools.requested本节点发起的池请求列表每项含池名与请求的 IP 数由节点上的 Cilium agent 写入、Cilium operator 读取并履行。spec.ipam.pools.allocated分配给本节点的 CIDR 及其来源池operator 追加新 PodCIDRagent 移除已释放不再使用的 PodCIDR。IP 池用集群级CiliumPodIPPool自定义资源管理每个池包含供各节点分配 PodCIDR 的集群级 CIDRapiVersion: cilium.io/v2 kind: CiliumPodIPPool metadata: name: green-pool spec: ipv4: cidrs: - 10.20.0.0/16 - 10.30.0.0/16 maskSize: 24 ipv6: cidrs: - fd00::/104 maskSize: 120运行期约束池可运行时新增、CIDR 列表可扩展使用中的 CIDR 不可删除被 Cilium 节点使用的池不可删除。掩码大小不可变spec.allowFirstIP、spec.allowLastIP同样不可变。默认情况下每个 CIDR 的首尾地址被保留不可分配建池时把allowFirstIP/allowLastIP设为true可放开其中之一少于 3 个地址的池/31、/32、/127、/128不受此限制。启用与预分配ipam: mode: multi-pool operator: autoCreateCiliumPodIPPools: default: ipv4: cidrs: - 10.10.0.0/16 maskSize: 24 other: ipv4: cidrs: - 10.20.0.0/16 maskSize: 24ipam.modemulti-pool启用该模式ipam.operator.autoCreateCiliumPodIPPools让 operator 启动时自动创建CiliumPodIPPools资源。预分配参数ipam-multi-pool-pre-allocation标志携带pool-namepreAllocIPs映射控制每个池为本地节点预分配多少 IP每个地址族相同数量。默认default8未在映射中的池视为 0。agent 计算每池绝对 IP 需求量的公式neededIPs roundUp(inUseIPs pendingIPs preAllocIPs, preAllocIPs)其中inUseIPs为在用 IP 数pendingIPs为已调度未取 IP 的 Pod 数preAllocIPs为期望缓冲量。路由通告与 Masquerade 行为从池中分配的 PodCIDR 可经 BGP 控制面通告到网络也可用autoDirectNodeRoutesHelm 选项在 L2 网络节点间启用自动路由。当 multi-pool 与 BGP 控制面结合时可能不希望对这些池的流量做 masqueradePod IP 已通过 BGP 通告回程流量可直达。若仅靠--ipvX-native-routing-cidr或ip-masq-agent规则无法区分可启用--only-masquerade-default-pool关闭所有非默认池的 masquerade或给CiliumPodIPPool打注解ipam.cilium.io/skip-masqueradetrue。改动只对重新调度后的 Pod 生效。更新使用中的池重要运维流程更新CiliumPodIPPools的约束可以追加新 IPv4/IPv6 CIDR但不能删除或更新使用中的 CIDR。若确需更换使用中 CIDR官方流程是把集群拆成两个节点组分批迁移以 kind 双节点集群为例把池更新为新 CIDR10.20.0.0/16替代10.10.0.0/16。operator 会对仍被节点占用的旧 CIDR 打印警告CIDR from pool still in use by node$ kubectl -n kube-system logs deploy/cilium-operator | grep CIDR from pool still in use by node ... time2025-11-01T11:24:13.076246842Z levelwarn msgCIDR from pool still in use by node moduleoperator... cidr10.10.0.0/24 poolNamedefault nodekind-control-plane重启 Cilium operatorkubectl -n kube-system rollout restart deploy/cilium-operator也可改 Helm 值后删除旧 CR 并让 operator 重建。cordon 并 drain 节点组 1其 Pod 会以新池 IP 重调度到节点组 2。删除节点组 1 的CiliumNodes、重启其上的 agent 并 uncordon。对节点组 2 重复 cordon/drain、删除CiliumNodes、重启 agent、uncordon。可选重调度 Pod 使负载均衡。reservedRanges 平滑迁移也可把旧 CIDR 保留在cidrs里并用reservedRanges保留整段Cilium 会保留旧 CIDR 的既有分配、但不再从中分配新 PodCIDRapiVersion: cilium.io/v2 kind: CiliumPodIPPool metadata: name: default spec: ipv4: cidrs: - 10.10.0.0/16 - 10.20.0.0/16 maskSize: 24 pool: - cidr: 10.10.0.0/16 reservedRanges: - start: 10.10.0.0 end: 10.10.255.255待节点全部迁走后再把旧 CIDR 与对应pool条目移除。按节点的默认池多数据中心场景下可按节点标签分配特定池如 DC1 用10.1.0.0/16、DC2 用10.2.0.0/16。通过CiliumNodeConfig在匹配节点标签的节点上设置ipam-default-ip-poolapiVersion: cilium.io/v2 kind: CiliumNodeConfig metadata: name: ip-pool-dc1 namespace: kube-system spec: defaults: ipam-default-ip-pool: dc1-pool nodeSelector: matchLabels: topology.kubernetes.io/zone: dc1限制重叠 CIDR 的池不受支持Cilium 依靠 IPCache 判定端点安全身份集群内每个 Pod IP 必须唯一iptables 型 masquerade 必须设置egressMasqueradeInterfaces建议直接使用完全受支持的 eBPF masquerade池不属于同一 native-routing CIDR 时可考虑ip-masq-agent定义多个互斥的非 masquerade CIDR。六、CRD-Backed把 IPAM 交给外部 operatorCRD-backed 文档 说明该模式通过 Kubernetes 自定义资源提供可扩展的 IPAM 接口允许把 IPAM 委托给外部 operator 或让用户按节点配置。启用后每个 agent 会监听与其所在节点同名的ciliumnodes.cilium.io自定义资源资源每次更新时节点分配池会以spec.ipam.available中列出的所有地址刷新已分配 IP 被移除时该 IP 可继续使用但释放后不再参与再分配池中分配出 IP 后该 IP 被加入status.ipam.inuse。状态更新节流节点状态更新限制为最多每 15 秒一次因此多个 Pod 同时调度时 status 段更新可能滞后。启用与等待行为ipam: crdConfigMap或--ipamcrd启用。启用后 agent 会等待与节点同名的CiliumNode资源出现且至少含一个可用 IP开启连通性健康检查时需至少两个可用 IP。等待期间打印Waiting for initial IP to become available in node-name custom resource所需权限ClusterRoleapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cilium rules: - apiGroups: - cilium.io resources: - ciliumnodes - ciliumnodes/status verbs: - *标准 Cilium 部署工件会自动授予这些权限。CRD 定义源码级CiliumNode遵循标准 K8s 资源结构分为spec与statustype CiliumNode struct { [...] Spec NodeSpec json:spec Status NodeStatus json:status }spec侧可由用户或 IPAM operator 填充type NodeSpec struct { [...] IPAM IPAMSpec json:ipam,omitempty } type IPAMSpec struct { // Pool 是本节点可用于分配的 IP 列表IP 被使用后仍保留在列表中 // 但会加入 Status.IPAM.InUse Pool AllocationMap json:pool,omitempty } type AllocationIP struct { // Owner 在 IP 被分配时填写Pod 名或其它标识未分配时留空 Owner string json:owner,omitempty // Resource 同时用于可用与已分配 IP表示关联的资源如 AWS ENI 场景下的 ENI ID Resource string json:resource,omitempty }status侧type NodeStatus struct { [...] IPAM IPAMStatus json:ipam,omitempty } type IPAMStatus struct { // InUse 列出 Spec.IPAM.Pool 中已被分配且正在使用的所有 IP InUse AllocationMap json:used,omitempty }注意上述 Go 类型定义与 crd.rst 文档一致读者可在仓库 api 包中查得对应 CRD 结构。CRD 模式正是控制流图中分支 2的实体化User-defined_cidrs写入spec.ipam.pool分配后进入status.ipam.used。七、云厂商模式AWS ENI 与 Azure云模式共有的设计哲学ENI 文档、Azure 文档只有单个 operator 与云 API 通信以避免大型集群的限流问题同时用预分配水印pre-allocation watermark保证节点随时有可用 IPPod 调度时无需即时访问云 API。7.1 AWS ENI构建于 multi-pool 之上的分配器AWS ENI 分配器面向 AWS 云环境基于Elastic Network InterfacesENI的 IP通过 EC2 API 分配。架构要点节点首次启动时创建同名ciliumnodes.cilium.io资源并通过 EC2 metadata API 获取实例 ID、实例类型与 VPC 信息写入资源operator 监听新资源扫描实例已有 ENI 及关联 IP逐 ENI 发布到status.eni.enis随后持续监控各 agent 在spec.ipam.pools.requested中上报的聚合 IP 需求按需创建 ENI、分配 IP以满足预分配水印。agent 与 operator 分工这是理解 ENI 模式的关键operator 是唯一与 EC2 API 通信的组件拥有 ENI 生命周期创建、挂接、删除与 IP/前缀分配并把结果记录到各CiliumNode的status.eni.enisagent 消费status.eni.enis并转换为 multi-pool 分配器的视角每个次要 IP 变成 host-prefix CIDRIPv4 为/32委派前缀保留原生 CIDRIPv4/28、IPv6/80全部发布在default池的spec.ipam.pools.allocated下agent 在本地从这些 CIDR 分配 Pod IP不像 CRD 分配器那样逐 IP 写status.ipam.usedagent 在spec.ipam.pools.requested的default池下按ipv4-addrs/ipv6-addrs上报聚合需求供 operator 决定分配多少 IP/前缀/ENI。与标准 multi-pool 的差异标准模式下 operator 依据集群级CiliumPodIPPool写spec.ipam.pools.allocated而 ENI 模式下agent 是spec.ipam.pools.allocated的唯一写入者且不涉及CiliumPodIPPool也不支持ipam.cilium.io/ip-pool注解——所有分配都来自default池。启用与关键配置agent 与 operator 均以--ipameni或 ConfigMapipam: eni运行Helm 安装时还需eni.enabledtrue该标志会配置 ENI 环境所需的全部要求operator 镜像选择、端点路由、CiliumNode 管理、IPv4 masquerade 默认值。建议启用--auto-create-cilium-node-resourceConfigMapauto-create-cilium-node-resource: true以自动创建节点 CR。IPv4 受限时可让 operator 携带--aws-release-excess-ipstrue定期检查并尝试释放 ENI 上多余的 IPv4。ENI 默认打上集群名标签以便 operator 垃圾回收游离 ENI集群名取自cluster-name标志或 EC2 实例上的aws:eks:cluster-name标签可用--eni-gc-tags覆盖。ENI 分配参数速查可经 Helm 或自定义 CNI ConfigMap 配置CNI 优先于 Helm参数说明与默认值spec.ipam.min-allocate节点首次引导时的最小 IP 数未指定则无下限spec.ipam.pre-allocate始终保持可分配的缓冲 IP 数默认 8spec.eni.first-interface-index用于 Pod IP 分配的首个 ENI 索引默认 0用 eth0spec.eni.subnet-ids/spec.eni.subnet-tags选择子网的 ID 列表/标签与availability-zone、vpc-id叠加subnet-ids与subnet-tags互斥且优先spec.eni.security-groups/spec.eni.security-group-tags新 ENI 挂接的安全组 ID 列表/标签过滤未设置时继承 eth0 的安全组spec.eni.exclude-interface-tags排除特定标签接口不参与分配spec.eni.use-primary-address是否允许分配 ENI 主地址默认禁用spec.eni.disable-prefix-delegation是否禁用 IPv4 前缀委派spec.eni.delete-on-termination实例终止时删除 ENI默认启用Helm 示例选择标签为foobar的子网、从索引 1 的接口开始、最少分配 10 个 IP--set eni.enabledtrue \ --set eni.nodeSpec.subnetTags{foobar} \ --set eni.nodeSpec.firstInterfaceIndex1 \ --set ipam.nodeSpec.ipamMinAllocate10自定义 CNI ConfigMap 示例子网标签过滤apiVersion: v1 kind: ConfigMap metadata: name: cni-configuration namespace: kube-system data: cni-config: |- { cniVersion:0.3.1, name:cilium, plugins: [ { cniVersion:0.3.1, type:cilium-cni, eni: { subnet-tags:{ foo:true } } } ] }部署后通过--set cni.customConftrue --set cni.configMapcni-configuration让 Cilium 使用该配置。运营细节源码文档佐证缓存operator 缓存账号下所有 ENI/VPC/子网通过DescribeNetworkInterfaces、DescribeSubnets、DescribeVpcs、DescribeRouteTables维护每分钟或每次分配/创建后刷新基于事件触发时每秒至多一次。可用 IP 发布缓存刷新后更新所有 CiliumNode扫描接口索引大于first-interface-index的 ENI 的可分配 IP 与委派前缀写入status.eni.enis变更时通过Update()/UpdateStatus()回写。赤字/富余判定在CiliumNode更新时与每分钟全量扫描时检查--aws-release-excess-ips启用时按间隔扫描识别 IPv4 富余。赤字计算公式neededIPs max(spec.ipam.pre-allocate - (availableIPs - usedIPs), spec.ipam.min-allocate - availableIPs) if spec.ipam.max-allocate 0 { neededIPs min(max(spec.ipam.max-allocate - availableIPs, 0), neededIPs) }分配优先复用满足条件ENI 有未用地址且未超实例类型上限、子网有可用 IP的 ENI通过AssignPrivateIpAddresses分配无可用 ENI 时创建新 ENI。单次分配量公式min(AvailableOnSubnet, min(AvailableOnENI, NeededAddresses spec.ipam.max-above-watermark surgeAllocate))释放IPv4agent 从spec.ipam.pools.allocated移除已完全空闲的 CIDRoperator 跟踪消失的 CIDR经--excess-ip-release-delay默认 180 秒延迟后用UnassignPrivateIpAddresses单次要 IP或UnassignENIPrefixes委派 /28 前缀释放。ENI 创建按 VPC ID 可用区匹配子网subnet-ids/subnet-tags进一步收窄多子网时选可用地址最多者无显式配置时回退到node-subnet-id→ 同路由表子网 → 匹配 VPC/AZ 的最大子网。创建描述格式为Cilium-CNI (EC2 instance ID)。节点终止apiserver 的节点删除事件触发 operator 删除对应ciliumnodes.cilium.io资源。operator 需要的一组 EC2 权限DeleteNetworkInterface、CreateNetworkInterface、AttachNetworkInterface、AssignPrivateIpAddresses、ModifyNetworkInterfaceAttribute等启用 ENI GC 需DescribeTags释放富余 IP 需UnassignPrivateIpAddresses启用 IPv6 需AssignIpv6Addresses完整清单见 eni.rst。ENI IPv6betaENI IPAM 支持 IPv6beta无论 Cilium 配置如何ENI 都创建在双栈子网启用 IPv6 后 operator 按需为 ENI 委派一个/80前缀agent 从该前缀分配 Pod IPv6。要点每节点只分配一个前缀且节点删除前不释放pre-allocate/min-allocate/max-allocate/max-above-watermark及富余计算仅作用于 IPv4IPv6 是需要一个前缀就申请一个的布尔式需求。Helm 启用方式--set ipam.modeeni --set eni.enabledtrue --set ipv6.enabledtrue节点侧注意事项ENI 上 IP 与路由由 agent 管理需禁用NetworkManager/systemd-networkd等系统服务对新挂接接口的自动 DHCP 管理否则会干扰 Cilium 配置。示例NetworkManager 排除 eth0 外的 eth* 接口systemd-networkd 对eth[1-9]*设置Unmanagedyes参见 eni.rst。7.2 Azure IPAM构建于 CRD-backed 之上的分配器Azure 文档 说明该分配器面向在 Azure VM/VMSS 上自建非 AKS 托管的集群基于Azure 私有 IP 地址分配。同样遵循单 operator 访问云 API 预分配水印的架构节点首次启动创建同名ciliumnodes.cilium.io资源agent 从 Kubernetesv1.Node的.Spec.ProviderID推导 Azure 实例 IDoperator 监听新资源扫描实例现有接口及关联 IP通过spec.ipam.available发布随后持续监控status.ipam.used并按水印补足 IP。启用与关键配置--ipamazure或 ConfigMapipam: azure同时启用 agent 与 operator 的 Azure 分配建议同样开启--auto-create-cilium-node-resourceoperator 建议开启--enable-metrics。operator 作用域--azure-subscription-id未设置时经 IMDS 探测自身订阅、--azure-resource-group必须为集群节点所在资源组未设置时经 IMDS 探测worker VM/VMSS 与其他节点不同资源组时必须显式设置、VNet/子网资源组在运行时由各接口的子网 ID 推导。认证基于 Azure Identity SDK。--azure-user-assigned-identity-id为空时走DefaultAzureCredential链环境变量 → workload identity → 系统托管身份 → Azure CLI设置时认证为指定用户托管身份必须传 client IDUUID而非完整资源 ID。Azure 分配参数spec.ipam.min-allocate节点引导最小 IP 数未指定无下限、spec.ipam.pre-allocate常驻缓冲 IP 数默认 8、spec.azure.interface-name用于分配的接口名如 eth0。Helm 示例使用 eth0、最少分配 10 个 IP--set azure.enabledtrue \ --set azure.nodeSpec.azureInterfaceNameeth0 \ --set ipam.nodeSpec.ipamMinAllocate10自定义 CNI ConfigMapazure.interface-name字段与 ENI 模式同构部署后同样用cni.customConftrue/cni.configMapcni-configuration接入。运营细节与排障缓存operator 缓存 ScaleSets、Instances、Interfaces、VirtualNetworks、Subnets每分钟或分配后刷新事件触发时每秒至多一次。发布接口扫描出的 IP 全部加入spec.ipam.available每个接口记入status.azure.interfaces。赤字/富余// deficit spec.ipam.pre-allocate - (len(spec.ipam.available) - len(status.ipam.used)) // excess (len(spec.ipam.available) - len(status.ipam.used)) - (spec.ipam.pre-allocate spec.ipam.max-above-watermark)分配复用满足条件的接口有未用地址且未超上限、子网有可用 IP单次分配量min(AvailableOnSubnet, min(AvailableOnInterface, NeededAddresses spec.ipam.max-above-watermark))。静态公网 IP创建带标签的 Public IP Prefix 后在 CNI 配置的ipam.static-ip-tags中指定标签operator 从首个有容量的匹配 Prefix 分配公网 IPPrefix ID 存于status.ipam.assigned-static-ip。RBAC所需 Azure 权限按拓扑分三档公共部分含Microsoft.Network/networkInterfaces/read、virtualNetworks/read、virtualNetworks/subnets/read、virtualNetworks/subnets/join/action、Microsoft.Compute/virtualMachineScaleSets/readVMSS 集群追加virtualMachineScaleSets/virtualMachines/read与write独立 VM 追加networkInterfaces/write静态公网 IP 追加publicIPPrefixes/read、publicIPPrefixes/join/action、virtualMachines/read详见 azure.rst。常见排障AuthorizationFailed on Microsoft.Network/virtualNetworks/read说明身份对 VNet 资源组无读权限spec.ipam.available为空且无分配说明--azure-resource-group指错资源组ManagedIdentityCredential authentication failed说明传了完整资源 ID 而非 client ID。八、GKE复用 Kubernetes Host ScopeGKE 文档 说明 Cilium 在 Google GKE 上运行时直接利用 GCP 原生网络层做地址管理与 IP 转发GKE 模式本质是 Kubernetes hostscope IPAM 模式agent 等待 Kubernetes node 资源按启用的地址族填充spec.podCIDR/spec.podCIDRs。启用方式Helmipam.modekubernetes或 ConfigMapipam: kubernetes。排障两步走验证节点podCIDR字段是否有值$ kubectl get nodes -o jsonpath{range .items[*]}{.metadata.name}{\t}{.spec.podCIDR}{\n}{end} gke-cluster4-default-pool-b195a3f3-k431 10.4.0.0/24 gke-cluster4-default-pool-b195a3f3-zv3p 10.4.1.0/24在目标节点上执行cilium-dbg status核对 IPAM 所用 CIDR 与节点公告的 PodCIDR 一致例如IPAM: IPv4: 7/255 allocated from 10.4.0.0/24,九、模式选择对照与总结回到控制流图与各模式文档可提炼出选择 IPAM 模式的核心判据Kubernetes Host Scope / GKE希望完全依赖 Kubernetes 或 GCP 下发 PodCIDR最贴近云原生原生语义但缺乏 Cilium 侧的多 CIDR 与动态扩展能力ClusterPool默认不依赖 Kubernetes 下发 PodCIDR由 operator 经CiliumNode管理是多数场景的稳妥起点注意扩容纪律只追加不修改、掩码不可变Multi-Pool需要按工作负载注解/节点标签区分地址域多数据中心、多租户隔离地址支持运行时建池与按池预分配迁移时遵循分组滚动流程或reservedRanges平滑方案CRD-Backed需要把 IPAM 委托给外部系统或自定义 operator接口完全通过CiliumNode的spec.ipam.pool/status.ipam.used暴露AWS ENI / Azure云原生直连模式单 operator 访问云 API 预分配水印保证低延迟取 IPENI 模式还构建在 multi-pool 分配器之上并仅使用 default 池。无论哪种模式控制流都遵循同一条主线kubelet → CRI → CNI 插件 → agent IPAM → 对应后端取 IP → veth/ipvlan 挂接与 link up → 状态回写。理解这条主线与 deep_dive.rst 中的控制流图即可在面对任何 IPAM 故障时迅速定位是取 IP 阶段还是挂网卡阶段出了问题再依据对应模式文档的排障命令精准处置。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考