news 2026/9/14 7:08:58

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 Management,IPAM)负责为 Cilium 所管理的网络端点(容器及其他)分配和管理 IP 地址。根据官方 IPAM 索引文档,Cilium 支持多种 IPAM 模式以适配不同用户场景,其能力差异可用下表概括:

特性Kubernetes Host ScopeCluster Scope(默认)Multi-PoolCRD-backedAWS ENIAzure IPAMGKE
Tunnel 路由
Direct 路由
CIDR 配置方KubernetesCiliumCilium外部外部(AWS)外部(Azure)外部(GCP)
每集群多 CIDRN/AN/AN/AN/A
每节点多 CIDRN/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 触发

  1. Kubelet → CRI:kubelet 通过容器运行时接口(CRI,如 containerd)发出Create container请求;
  2. CRI → Cilium CNI Plugin:CRI 在创建容器命名空间并识别网络后,调用 Cilium CNI 插件;
  3. CNI Plugin → CNI Agent:CNI 插件执行cmdAdd()(添加网络)/cmdDel()(删除网络),将控制权交给 Cilium agent 侧的网络配置逻辑;
  4. CNI Agent → IPAM:agent 首先检查 Cilium 配置中的ipam选项,根据其取值决定走哪条分配分支。

这一步在源码中同样可循:agent 的 IPAM 初始化入口 pkg/ipam/ipam.go 首先在cloudProviders中查找ipam.config.IPAMMode()对应的云厂商后端(ENI/Azure 等),找不到再落入switch分支,依次处理kubernetescluster-poolmulti-pool等模式,最终对未知模式返回unknown IPAM backend错误。而模式字符串常量定义在 pkg/ipam/option/option.go:kubernetescrdeniazurecluster-poolmulti-poolalibabacloud

2.2 阶段二:IPAM 模式分支(控制流核心)

控制流图以ipam配置为分水岭,分出三类典型分支:

  • 分支 1:ClusterPool / Node CIDR(默认):配置-ipam=clusterpool(源码中实际取值为cluster-pool,参见 option.go)。默认基于 Kubernetes 节点子网(Host-Subnet),配合-allocate-node-cidrs让 Kubernetes 为节点分配 CIDR;也可以由 Cloud-IPAM Service 拉取 IP 段,再从集群节点 CIDR 中分配容器 IP。
  • 分支 2:CRD 模式:配置-ipam=crd,使用用户(或外部 operator)在 CRD 中定义的 CIDR,agent 从已分配的 IP 池中取 IP 返回给容器。
  • 分支 3:ENI 等云模式:配置-ipam=eni(或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:把分配权交给 Kubernetes

Kubernetes Host Scope 文档 描述的是最贴近 K8s 原生的模式:启用ipam: kubernetes,把地址分配委托给集群内每个节点,IP 从 Kubernetes 关联给节点的PodCIDR范围中分配

agent 启动时会等待 IPv4/IPv6 的 PodCIDR 通过以下任一路径就绪:

  • 通过v1.Node资源字段spec.podCIDRs(IPv4 和/或 IPv6)或spec.podCIDR(单栈)。
  • 通过v1.Nodeannotation
Annotation描述
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-ipv4=true时自动开启k8s-require-ipv4-pod-cidrenable-ipv6=true时自动开启k8s-require-ipv6-pod-cidr
k8s-require-ipv4-pod-cidr: true让 agent 等待 Kubernetes node 资源暴露 IPv4 PodCIDR
k8s-require-ipv6-pod-cidr: true让 agent 等待 Kubernetes node 资源暴露 IPv6 PodCIDR

Helm 等价写法:--set ipam.mode=kubernetes--set k8s.requireIPv4PodCIDR=true--set k8s.requireIPv6PodCIDR=true(后两者仅与ipam.mode=kubernetes配合生效)。

四、Cluster Scope(默认):由 Operator 管理节点 PodCIDR

Cluster 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-status):

kubectl 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 分配。

池选择的优先级顺序

  1. 显式注解指定:在 Pod 或其命名空间上使用ipam.cilium.io/ip-pool=<pool-name>注解;IPv4/IPv6 可分别用ipam.cilium.io/ipv4-pool=<pool-name>ipam.cilium.io/ipv6-pool=<pool-name>指定不同池。
  2. 标签选择器:通过spec.podSelector和/或spec.namespaceSelector定义哪些 Pod 可从该池取 IP;两者都定义时需同时匹配。此外还可匹配 Cilium 附加的两个合成标签:io.kubernetes.pod.namespace(Pod 命名空间)、io.kubernetes.pod.name(Pod 名称)。
    • 若分配时池尚不可知(竞态或配置错误),Pod 会回退到 default 池;若希望阻止此行为,可设置ipam.cilium.io/require-pool-match="true"注解,直到 Pod 匹配上非默认池才放行分配。
    • 一个 Pod 在给定 IP 族上必须恰好匹配一个池;匹配多个池会导致分配失败并记录错误,因此务必避免池之间选择器重叠。
  3. 兜底 default 池:无显式注解、也不匹配任何选择器时,从名为default的池分配。

注意:注解只在 Pod 创建时生效,修改运行中 Pod 的ip-pool注解无效。

CiliumNode 扩展与 CiliumPodIPPool CRD

Multi-Pool 模式下CiliumNode资源新增spec.ipam.pools段:

  • spec.ipam.pools.requested:本节点发起的池请求列表,每项含池名与请求的 IP 数;由节点上的 Cilium agent 写入、Cilium operator 读取并履行。
  • spec.ipam.pools.allocated:分配给本节点的 CIDR 及其来源池;operator 追加新 PodCIDR,agent 移除已释放不再使用的 PodCIDR。

IP 池用集群级CiliumPodIPPool自定义资源管理,每个池包含供各节点分配 PodCIDR 的集群级 CIDR:

apiVersion: 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.allowFirstIPspec.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: 24

ipam.mode=multi-pool启用该模式;ipam.operator.autoCreateCiliumPodIPPools让 operator 启动时自动创建CiliumPodIPPools资源。

预分配参数ipam-multi-pool-pre-allocation标志携带<pool-name>=<preAllocIPs>映射,控制每个池为本地节点预分配多少 IP(每个地址族相同数量)。默认default=8;未在映射中的池视为 0。agent 计算每池绝对 IP 需求量的公式:

neededIPs = roundUp(inUseIPs + pendingIPs + preAllocIPs, preAllocIPs)

其中inUseIPs为在用 IP 数,pendingIPs为已调度未取 IP 的 Pod 数,preAllocIPs为期望缓冲量。

路由通告与 Masquerade 行为

  • 从池中分配的 PodCIDR 可经 BGP 控制面通告到网络,也可用autoDirectNodeRoutesHelm 选项在 L2 网络节点间启用自动路由。
  • 当 multi-pool 与 BGP 控制面结合时,可能不希望对这些池的流量做 masquerade(Pod IP 已通过 BGP 通告,回程流量可直达)。若仅靠--ipvX-native-routing-cidrip-masq-agent规则无法区分,可启用--only-masquerade-default-pool关闭所有非默认池的 masquerade,或给CiliumPodIPPool打注解ipam.cilium.io/skip-masquerade="true"。改动只对重新调度后的 Pod 生效。

更新使用中的池(重要运维流程)

更新CiliumPodIPPools的约束:可以追加新 IPv4/IPv6 CIDR,但不能删除或更新使用中的 CIDR。若确需更换使用中 CIDR,官方流程是把集群拆成两个节点组分批迁移(以 kind 双节点集群为例):

  1. 把池更新为新 CIDR(10.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" ... time=2025-11-01T11:24:13.076246842Z level=warn msg="CIDR from pool still in use by node" module=operator... cidr=10.10.0.0/24 poolName=default node=kind-control-plane
  1. 重启 Cilium operator(kubectl -n kube-system rollout restart deploy/cilium-operator;也可改 Helm 值后删除旧 CR 并让 operator 重建)。
  2. cordon 并 drain 节点组 1,其 Pod 会以新池 IP 重调度到节点组 2。
  3. 删除节点组 1 的CiliumNodes、重启其上的 agent 并 uncordon。
  4. 对节点组 2 重复 cordon/drain、删除CiliumNodes、重启 agent、uncordon。
  5. (可选)重调度 Pod 使负载均衡。

reservedRanges 平滑迁移:也可把旧 CIDR 保留在cidrs里并用reservedRanges保留整段,Cilium 会保留旧 CIDR 的既有分配、但不再从中分配新 PodCIDR:

apiVersion: 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-pool

apiVersion: 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 交给外部 operator

CRD-backed 文档 说明该模式通过 Kubernetes 自定义资源提供可扩展的 IPAM 接口,允许把 IPAM 委托给外部 operator 或让用户按节点配置。启用后每个 agent 会监听与其所在节点同名的ciliumnodes.cilium.io自定义资源:

  • 资源每次更新时,节点分配池会以spec.ipam.available中列出的所有地址刷新;
  • 已分配 IP 被移除时,该 IP 可继续使用,但释放后不再参与再分配;
  • 池中分配出 IP 后,该 IP 被加入status.ipam.inuse

状态更新节流:节点状态更新限制为最多每 15 秒一次,因此多个 Pod 同时调度时 status 段更新可能滞后。

启用与等待行为

ipam: crd(ConfigMap)或--ipam=crd启用。启用后 agent 会等待与节点同名的CiliumNode资源出现且至少含一个可用 IP;开启连通性健康检查时需至少两个可用 IP。等待期间打印:

Waiting for initial IP to become available in '<node-name>' custom resource

所需权限(ClusterRole)

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cilium rules: - apiGroups: - cilium.io resources: - ciliumnodes - ciliumnodes/status verbs: - '*'

标准 Cilium 部署工件会自动授予这些权限。

CRD 定义(源码级)

CiliumNode遵循标准 K8s 资源结构,分为specstatus

type 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)保证节点随时有可用 IP,Pod 调度时无需即时访问云 API。

7.1 AWS ENI:构建于 multi-pool 之上的分配器

AWS ENI 分配器面向 AWS 云环境,基于Elastic Network Interfaces(ENI)的 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/前缀分配,并把结果记录到各CiliumNodestatus.eni.enis
  • agent 消费status.eni.enis并转换为 multi-pool 分配器的视角:每个次要 IP 变成 host-prefix CIDR(IPv4 为/32),委派前缀保留原生 CIDR(IPv4/28、IPv6/80),全部发布在defaultspec.ipam.pools.allocated下;agent 在本地从这些 CIDR 分配 Pod IP,像 CRD 分配器那样逐 IP 写status.ipam.used;agent 在spec.ipam.pools.requesteddefault池下按ipv4-addrs/ipv6-addrs上报聚合需求,供 operator 决定分配多少 IP/前缀/ENI。

与标准 multi-pool 的差异:标准模式下 operator 依据集群级CiliumPodIPPoolspec.ipam.pools.allocated;而 ENI 模式下agent 是spec.ipam.pools.allocated的唯一写入者,且不涉及CiliumPodIPPool,也不支持ipam.cilium.io/ip-pool注解——所有分配都来自default池。

启用与关键配置
  • agent 与 operator 均以--ipam=eni(或 ConfigMapipam: eni)运行;Helm 安装时还需eni.enabled=true(该标志会配置 ENI 环境所需的全部要求:operator 镜像选择、端点路由、CiliumNode 管理、IPv4 masquerade 默认值)。
  • 建议启用--auto-create-cilium-node-resource(ConfigMapauto-create-cilium-node-resource: "true")以自动创建节点 CR。
  • IPv4 受限时可让 operator 携带--aws-release-excess-ips=true定期检查并尝试释放 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 数,默认 8
spec.eni.first-interface-index用于 Pod IP 分配的首个 ENI 索引,默认 0(用 eth0)
spec.eni.subnet-ids/spec.eni.subnet-tags选择子网的 ID 列表/标签,与availability-zonevpc-id叠加;subnet-idssubnet-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 示例(选择标签为foo=bar的子网、从索引 1 的接口开始、最少分配 10 个 IP):

--set eni.enabled=true \ --set eni.nodeSpec.subnetTags={foo=bar} \ --set eni.nodeSpec.firstInterfaceIndex=1 \ --set ipam.nodeSpec.ipamMinAllocate=10

自定义 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.customConf=true --set cni.configMap=cni-configuration让 Cilium 使用该配置。

运营细节(源码文档佐证)
  • 缓存:operator 缓存账号下所有 ENI/VPC/子网,通过DescribeNetworkInterfacesDescribeSubnetsDescribeVpcsDescribeRouteTables维护;每分钟或每次分配/创建后刷新,基于事件触发时每秒至多一次。
  • 可用 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))
  • 释放(IPv4):agent 从spec.ipam.pools.allocated移除已完全空闲的 CIDR,operator 跟踪消失的 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 权限(DeleteNetworkInterfaceCreateNetworkInterfaceAttachNetworkInterfaceAssignPrivateIpAddressesModifyNetworkInterfaceAttribute等;启用 ENI GC 需DescribeTags;释放富余 IP 需UnassignPrivateIpAddresses;启用 IPv6 需AssignIpv6Addresses),完整清单见 eni.rst。

ENI IPv6(beta)

ENI IPAM 支持 IPv6(beta):无论 Cilium 配置如何,ENI 都创建在双栈子网;启用 IPv6 后 operator 按需为 ENI 委派一个/80前缀,agent 从该前缀分配 Pod IPv6。要点:每节点只分配一个前缀且节点删除前不释放pre-allocate/min-allocate/max-allocate/max-above-watermark及富余计算仅作用于 IPv4,IPv6 是"需要一个前缀就申请一个"的布尔式需求。Helm 启用方式:

--set ipam.mode=eni --set eni.enabled=true --set ipv6.enabled=true
节点侧注意事项

ENI 上 IP 与路由由 agent 管理,需禁用NetworkManager/systemd-networkd等系统服务对新挂接接口的自动 DHCP 管理,否则会干扰 Cilium 配置。示例(NetworkManager 排除 eth0 外的 eth* 接口;systemd-networkd 对eth[1-9]*设置Unmanaged=yes)参见 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 实例 ID;
  • operator 监听新资源,扫描实例现有接口及关联 IP,通过spec.ipam.available发布,随后持续监控status.ipam.used并按水印补足 IP。
启用与关键配置
  • --ipam=azure或 ConfigMapipam: azure同时启用 agent 与 operator 的 Azure 分配;建议同样开启--auto-create-cilium-node-resource;operator 建议开启--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 ID(UUID)而非完整资源 ID

Azure 分配参数spec.ipam.min-allocate(节点引导最小 IP 数,未指定无下限)、spec.ipam.pre-allocate(常驻缓冲 IP 数,默认 8)、spec.azure.interface-name(用于分配的接口名,如 eth0)。

Helm 示例(使用 eth0、最少分配 10 个 IP):

--set azure.enabled=true \ --set azure.nodeSpec.azureInterfaceName=eth0 \ --set ipam.nodeSpec.ipamMinAllocate=10

自定义 CNI ConfigMap(azure.interface-name字段)与 ENI 模式同构,部署后同样用cni.customConf=true/cni.configMap=cni-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 分配公网 IP,Prefix ID 存于status.ipam.assigned-static-ip
  • RBAC:所需 Azure 权限按拓扑分三档(公共部分含Microsoft.Network/networkInterfaces/readvirtualNetworks/readvirtualNetworks/subnets/readvirtualNetworks/subnets/join/actionMicrosoft.Compute/virtualMachineScaleSets/read;VMSS 集群追加virtualMachineScaleSets/virtualMachines/readwrite;独立 VM 追加networkInterfaces/write;静态公网 IP 追加publicIPPrefixes/readpublicIPPrefixes/join/actionvirtualMachines/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 Scope

GKE 文档 说明 Cilium 在 Google GKE 上运行时,直接利用 GCP 原生网络层做地址管理与 IP 转发:GKE 模式本质是 Kubernetes hostscope IPAM 模式,agent 等待 Kubernetes node 资源按启用的地址族填充spec.podCIDR/spec.podCIDRs。启用方式:Helmipam.mode=kubernetes或 ConfigMapipam: kubernetes

排障两步走:

  1. 验证节点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
  1. 在目标节点上执行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,接口完全通过CiliumNodespec.ipam.pool/status.ipam.used暴露;
  • AWS ENI / Azure:云原生直连模式,单 operator 访问云 API + 预分配水印保证低延迟取 IP,ENI 模式还构建在 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),仅供参考

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

AI数学证明实操:从IMO高分到零配置云端IDE

看到一个标题说“AI已经能证明费马大定理”&#xff0c;我第一反应是营销号又在制造焦虑。但把资料翻了一遍之后&#xff0c;我得承认这件事有个值得认真聊的“靶子”&#xff1a;2025年7月&#xff0c;Google DeepMind带着AlphaProof和AlphaGeometry 2参加了国际数学奥林匹克&…

作者头像 李华
网站建设 2026/9/14 7:07:04

MVDR波束形成原理与工程实践指南

简介&#xff1a;本资源是一份面向信号处理初学者与通信/声学方向工程实践者的波束形成算法对比学习材料&#xff0c;聚焦常规波束形成与MVDR&#xff08;Capon&#xff09;波束形成的原理实现与MATLAB代码验证。资源包含2个核心MATLAB脚本文件&#xff08;.m&#xff09;&…

作者头像 李华
网站建设 2026/9/14 7:07:00

edge-tts 使用指南:免密钥语音合成实战

edge-tts 使用指南&#xff1a;免密钥语音合成实战 【免费下载链接】edge-tts Use Microsoft Edges online text-to-speech service from Python WITHOUT needing Microsoft Edge or Windows or an API key 项目地址: https://gitcode.com/GitHub_Trending/ed/edge-tts …

作者头像 李华
网站建设 2026/9/14 7:06:51

deer-flow:Windows内存流控沙盒原理与C级集成实践

1. “deer-flow”不是框架&#xff0c;是内存沙盒的命名哲学 第一次在 GitHub 上看到 deer-flow 这个仓库名时&#xff0c;我下意识点开 README —— 没有文档&#xff0c;没有安装命令&#xff0c;甚至没有一行示例代码。只有一行 commit message&#xff1a;“v0.3.1: fix …

作者头像 李华
网站建设 2026/9/14 7:03:40

微信聊天记录导出成可搜索网页:WeChatMsg 本地备份完整指南

微信聊天记录导出成可搜索网页&#xff1a;WeChatMsg 本地备份完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/…

作者头像 李华