先说结论:
L3: BGP + ECMP 最稳定,最成熟,最适合大集群
L2: 目前还是 Beta 阶段:也难怪会有一些方案用 metallb 配合提供公网 IP 的维护
主题:Cilium LB IPAM 的功能定位、协同关系、启用机制及 IP Pool 配置与管理、Service 配置与 IP 分配等方面的详细介绍,包括关键问题及答案
1. 一段话总结
LB IPAM 是 Cilium 为 LoadBalancer 类型 Service 分配 IP 地址的功能,通常用于私有云环境(弥补公有云相关设施缺失),需与 Cilium BGP Control Plane、L2 Announcements/L2 Aware LB(Beta) 等功能协同:
- Cilium BGP Control Plane 负责 IP 分配
- L2 Announcements/L2 Aware LB(Beta) 后者负责负载均衡与 IP 宣告
LB IPAM 默认启用但休眠,添加首个 IP Pool 后激活该功能:
-
支持通过 IP Pool 定义可用 IP 范围(CIDR 或起止 IP)
-
服务选择器匹配特定 Service、IPv4/IPv6 单栈/双栈模式
-
还可配置 IP 共享、禁用 Pool 等
-
同时会检测 Pool 冲突
-
通过状态反馈 IP 使用情况
2. 思维导图(mindmap)
3. 详细总结
一、LB IPAM 核心概述
-
功能定位:Cilium 提供的
LoadBalancer类型 Service IP 分配功能,主要用于私有云环境(公有云通常由云厂商提供该能力,私有云常缺失)。 -
协同关系:仅负责 IP 分配,负载均衡与 IP 宣告需依赖其他功能,具体对应关系如下:
| 协同功能 | 负责事项 |
|---|---|
| Cilium BGP Control Plane | 通过 BGP 协议宣告 LB IPAM 分配的 IP |
| L2 Announcements/L2 Aware LB(Beta) | 在本地网络宣告 LB IPAM 分配的 IP |
- 启用机制:默认启用但处于休眠状态,当集群中添加首个 IP Pool 后,控制器被激活并开始工作。
二、IP Pool 配置与管理
IP Pool 是管理员定义的可用 IP 范围集合,是 LB IPAM 分配 IP 的基础,核心配置与管理能力如下:
1. 基础配置(IP 块与特殊设置)
-
IP 块格式:支持两种方式定义可用 IP 范围,可在同一 Pool 中混合使用:
- CIDR notation:如
cidr: "10.0.10.0/24"(IPv4)、cidr: "2004::0/112"(IPv6) - 起止 IP 范围:如
start: "20.0.20.100"+stop: "20.0.20.200"
- CIDR notation:如
-
CIDR 首尾 IP 保留:
-
默认行为:使用 CIDR 中的所有 IP(包括网络地址、广播地址,部分设备可能不兼容)
-
保留配置:设置
.spec.allowFirstLastIPs: No,可保留 CIDR 首尾 IP -
例外情况:
/32//31IPv4 CIDR、/128//127IPv6 CIDR(仅 1 或 2 个 IP),此设置无效;且该设置仅对 CIDR 格式 IP 块生效,对起止 IP 格式无效。
-
2. 服务选择器(Service Selector)
-
作用:限制当前 IP Pool 只能为匹配条件的 Service 分配 IP,无选择器则对所有 Service 开放。
-
匹配方式:
matchExpressions:复杂匹配,如{key: color, operator: In, values: [blue, cyan]}(匹配 label 中 color 为 blue 或 cyan 的 Service)matchLabels:精确匹配,如color: red(匹配 label 中 color 为 red 的 Service)
-
特殊选择器:不匹配 Service 标签,而是匹配元数据,对应关系如下:
| 选择器键 | 匹配的 Service 元数据字段 |
|---|---|
| io.kubernetes.service.namespace | .meta.namespace(Service 所在命名空间) |
| io.kubernetes.service.name | .meta.name(Service 名称) |
3. 冲突处理
-
冲突规则:IP Pool 不允许存在重叠 CIDR,若管理员创建重叠 Pool,会触发“软错误”。
-
冲突表现:后添加的 Pool 会被标记为
Conflicting,且不再从该 Pool 分配 IP。 -
查看冲突:
-
命令 1(jsonpath 查看消息):
kubectl get ippools/[Pool名] -o jsonpath='{.status.conditions[?(@.type=="cilium.io/PoolConflict")].message}' -
命令 2(describe 查看详情):
kubectl describe ippools/[Pool名],在 Status.Conditions 中查看冲突原因(如“CIDR 20.0.10.0/24 与 blue-pool 的 CIDR 重叠”)。
-
4. 禁用 Pool
-
配置方式:在 Pool 定义中设置
.spec.disabled: true。 -
效果:停止从该 Pool 分配新 IP,但保留已分配的 IP(适用于逐步排空 Pool 或预留 Pool 供未来使用)。
-
状态查看:
kubectl get ippools中,该 Pool 的DISABLED列显示为true。
5. 状态监控
Pool 状态包含 IP 使用关键数据,支持机器解析与人类可读两种查看方式:
-
机器解析(jsonpath + jq) :
kubectl get ippools -o jsonpath='{.items[*].status.conditions[?(@.type!="cilium.io/PoolConflict")]}' | jq,可获取以下类型数据:cilium.io/IPsTotal:Pool 总 IP 数cilium.io/IPsAvailable:Pool 可用 IP 数cilium.io/IPsUsed:Pool 已用 IP 数
-
人类可读(describe) :
kubectl describe ippools/[Pool名],在 Status.Conditions 中查看上述三类数据的具体数值(如 Message: 254 表示对应 IP 数量)。
三、Service 配置与 IP 分配
LB IPAM 为 LoadBalancer 类型 Service 分配 IP,需满足匹配规则,且支持多种 IP 配置策略:
1. 基础分配条件与状态反馈
-
分配条件:Service 需满足
spec.type=LoadBalancer,且匹配某 IP Pool 的服务选择器(否则ExternalIP显示为<pending>)。 -
状态反馈:当 LB IPAM 无法分配 IP 时,会更新 Service 状态条件,可通过命令查看:
kubectl -n [命名空间] get svc/[Service名] -o jsonpath='{.status.conditions}' | jq,例如“无启用且匹配的 Pool”时,条件io.cilium/lb-ipam-request-satisfied状态为False,原因是no_pool;分配成功后,该条件状态变为True,原因是satisfied。
2. IPv4/IPv6 家族与策略
LB IPAM 支持 IPv4、IPv6 的单栈(SingleStack)或双栈(DualStack)模式,由 Service 的 .spec.ipFamilyPolicy 控制,具体规则如下:
| IP 家族策略 | 行为说明 | 满足条件 |
|---|---|---|
| SingleStack(默认) | 若双栈启用,优先分配 IPv4;仅单栈启用则分配对应 IP | 分配到一种 IP 即满足 |
| PreferDualStack | 尝试分配 IPv4 + IPv6;仅一种启用时仍正常分配 | 分配到一种或两种 IP 均满足 |
| RequireDualStack | 必须同时分配 IPv4 + IPv6 | 需同时分配两种 IP 才满足,缺一种则不满足 |
- 补充:
.spec.ipFamilies的顺序不影响 LB IPAM 分配,但会影响集群 IP 分配(集群 IP 不由 LB IPAM 处理)。
3. LoadBalancerClass(K8s ≥v1.24)
-
功能作用:K8s 1.24+ 支持集群中存在多个负载均衡器,通过
.spec.loadBalancerClass选择具体负载均衡器。 -
LB IPAM 处理规则:
-
默认:处理 无
loadBalancerClass配置 的 Service。 -
支持的 Cilium 类:需选择 Cilium 相关类才能使用 LB IPAM 分配 IP,对应关系如下:
-
| loadBalancerClass | 关联 Cilium 功能 |
|---|---|
| io.cilium/bgp-control-plane | Cilium BGP Control Plane |
| io.cilium/l2-announcer | L2 Announcements/L2 Aware LB(Beta) |
-
忽略规则:若
loadBalancerClass设为非 Cilium 处理的类,LB IPAM 会完全忽略该 Service,不分配 IP 也不更新状态条件。 -
自定义配置:默认 LB IPAM 处理无类 Service,若需仅处理有认可类的 Service,可通过以下方式配置:
-
Helm:
helm upgrade cilium cilium/cilium --version 1.18.3 --namespace kube-system --reuse-values --set defaultLBServiceIPAM=none -
ConfigMap:设置
default-lb-service-ipam: none
-
4. 手动请求特定 IP
Service 可指定需分配的 IP,支持两种方式:
-
Legacy 方式(弃用) :通过
.spec.loadBalancerIP指定单个 IP,K8s v1.24 已弃用,但暂支持。 -
新方式(推荐) :通过 Annotation
lbipam.cilium.io/ips指定,格式为逗号分隔的多 IP(如"20.0.10.100,20.0.10.200")。 -
限制:请求的 IP 需属于某 IP Pool,且 Service 需匹配该 Pool 的服务选择器;不建议请求 CIDR 的首尾 IP(通常为网络/广播地址,不可用)。
5. IP 共享
多个 Service 可共享同一 IP 或 IP 集合,核心配置与规则如下:
-
基础配置:在 Service 中添加 Annotation
lbipam.cilium.io/sharing-key: [自定义字符串],相同sharing-key的 Service 会共享 IP。 -
共享规则:
- 无端口冲突:多个 Service 共享同一 IP。
- 有端口冲突:为冲突的 Service 分配不同 IP,但这些 IP 仍属于该
sharing-key的共享组。 - 结合手动请求 IP:若 Service 有
sharing-key且手动请求 IP,该 IP 会被分配给 Service 并加入共享组。
-
跨命名空间共享:
-
默认:不允许跨命名空间共享 IP。
-
启用方式:两个 Service 均需添加 Annotation
lbipam.cilium.io/sharing-cross-namespace: [命名空间列表],值为逗号分隔的允许命名空间(如"tenant-a,tenant-b"),或用*表示允许所有命名空间。
-
4. 关键问题
问题 1:在 Cilium LB IPAM 中,IP Pool 出现 CIDR 重叠时会有什么后果?如何查看具体的冲突原因?
答案
-
后果:IP Pool 不允许存在 CIDR 重叠,若管理员创建了重叠的 Pool,后添加的 Pool 会被标记为 Conflicting,且 LB IPAM 会停止从该冲突 Pool 中分配任何 IP;已存在的非冲突 Pool 不受影响,正常提供 IP 分配服务。
-
查看冲突原因:有两种常用方式:
-
使用 jsonpath 提取冲突消息:
kubectl get ippools/[冲突 Pool 名称] -o jsonpath='{.status.conditions[?(@.type=="cilium.io/PoolConflict")].message}',例如输出“Pool conflicts since CIDR '20.0.10.0/24' overlaps CIDR '20.0.10.0/24' from IP Pool 'blue-pool'”。 -
通过 describe 查看详情:
kubectl describe ippools/[冲突 Pool 名称],在 Status.Conditions 段落中,找到类型为cilium.io/PoolConflict的条件,其 Message 字段会明确说明冲突原因(如 CIDR 重叠来源)。
-
问题 2:Cilium LB IPAM 支持 IPv4 和 IPv6 双栈模式,Service 的 .spec.ipFamilyPolicy 不同取值对应什么分配行为?若设置为 RequireDualStack 但集群仅启用了 IPv4,会有什么结果?
答案
-
.spec.ipFamilyPolicy 不同取值的分配行为:
- SingleStack(默认) :若集群同时启用 IPv4 和 IPv6,LB IPAM 优先为 Service 分配 IPv4 地址;若仅启用一种 IP 家族(仅 IPv4 或仅 IPv6),则分配对应家族的 IP。
- PreferDualStack:LB IPAM 会尝试为 Service 同时分配 IPv4 和 IPv6 地址;若集群仅启用一种 IP 家族,仍会分配该家族的 IP,Service 状态视为“满足”(io.cilium/lb-ipam-request-satisfied 为 True)。
- RequireDualStack:LB IPAM 必须为 Service 同时分配 IPv4 和 IPv6 地址才视为“满足”;若集群仅启用一种 IP 家族(如仅 IPv4),无法分配另一种 IP,Service 状态视为“不满足”(io.cilium/lb-ipam-request-satisfied 为 False),且 ExternalIP 可能处于 pending 状态。
-
RequireDualStack 且仅启用 IPv4 的结果:Service 无法同时获取 IPv4 和 IPv6 地址,LB IPAM 不会完成 IP 分配,Service 的
ExternalIP可能显示为<pending>,且通过kubectl get svc/[Service名] -o jsonpath='{.status.conditions}' | jq查看时,io.cilium/lb-ipam-request-satisfied条件状态为 False,提示无法满足双栈 IP 需求。
问题 3:在 Cilium LB IPAM 中,如何配置多个 Service 共享同一 IP?跨命名空间共享 IP 需要额外做什么设置?
答案
-
同命名空间下多个 Service 共享 IP 的配置:
- 为需要共享 IP 的所有 Service 添加相同的 Annotation:
lbipam.cilium.io/sharing-key: [自定义共享密钥](如"sharing-key: "app-common"")。 - 确保这些 Service 无端口冲突(如均使用 80 端口则存在冲突):无端口冲突时,LB IPAM 会为它们分配同一 IP;有端口冲突时,会分配不同 IP,但这些 IP 仍属于该共享密钥对应的 IP 集合。
- (可选)若某 Service 需指定共享的 IP,可额外添加 Annotation
lbipam.cilium.io/ips: [指定 IP],该 IP 会被分配给该 Service 并加入共享组,供其他同共享密钥的 Service 使用(需确保指定 IP 属于匹配的 IP Pool)。
- 为需要共享 IP 的所有 Service 添加相同的 Annotation:
-
跨命名空间共享 IP 的额外设置:
默认情况下,LB IPAM 不允许跨命名空间共享 IP,需在两个共享 IP 的 Service 上均添加以下 Annotation:lbipam.cilium.io/sharing-cross-namespace: [允许的命名空间列表],具体格式:
- 允许特定命名空间:值为逗号分隔的命名空间名称(如
"tenant-a,tenant-b"),表示当前 Service 仅允许与 tenant-a、tenant-b 命名空间中同共享密钥的 Service 共享 IP。 - 允许所有命名空间:值设为
*(如"*"),表示当前 Service 允许与所有命名空间中同共享密钥的 Service 共享 IP。 - 注意:两个跨命名空间共享的 Service 必须同时配置该 Annotation,且允许的命名空间范围需包含对方所在的命名空间(如 Service A 在 ns1,Service B 在 ns2,Service A 的 Annotation 需包含 ns2,Service B 的需包含 ns1,或均设为 *)。