news 2026/9/14 9:56:31

Cilium eBPF Maps 容量规划与调优指南:默认上限、动态尺寸与 Service LB 映射规模计算

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cilium eBPF Maps 容量规划与调优指南:默认上限、动态尺寸与 Service LB 映射规模计算

Cilium eBPF Maps 容量规划与调优指南:默认上限、动态尺寸与 Service LB 映射规模计算

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

eBPF Maps 是 Cilium 数据通路(datapath)的核心存储结构,连接跟踪、NAT、策略、负载均衡等关键能力都依赖这些内核映射,而每个 Map 都带有上限容量。本文以 Documentation/network/ebpf/maps.rst 为主线,系统梳理 Cilium 各类 BPF Map 的默认容量、作用域与扩展性含义,讲解如何通过cilium-agent命令行参数覆盖默认上限、利用--bpf-map-dynamic-size-ratio依据系统内存自动计算容量,并给出 Service Load Balancer Map 的精确容量估算公式与扩容注意事项。读完本文,你将能根据节点规模为 Cilium 数据通路做出合理的容量规划与调优决策。

eBPF Maps 与容量上限的基本概念

Cilium 将所有 BPF Map 创建为带有**上限容量(upper capacity limit)**的映射。当插入条目的数量超过该上限时,插入操作会失败,进而限制数据通路的扩展能力。因此,容量规划是部署 Cilium 前必须考虑的问题:每个限制都可以在源码中调整,cilium-agent也提供了对应的命令行选项(配置选项会按需陆续补充)。

各 Map 的容量上限与扩容影响,体现在数据通路实际处理连接、转发数据包和加载策略的各个环节。下面先看核心 Map 的默认上限总表,再逐一展开容量覆盖与动态计算机制。

BPF Map 默认上限总表

下表汇总了 Cilium 各类 BPF Map 的默认上限值、作用域(Scope)与扩展性含义(数据来源于 maps.rst):

Map 名称作用域默认上限扩展性含义
Auth(认证)node512k每个节点最多 512k 条已认证关系
Connection Tracking(连接跟踪)node512k TCP / 256k UDP每个节点最多 512k 条并发 TCP 连接、256k 条预期的 UDP 应答
NATnode512k最多 512k 条 NAT 条目
Neighbor Table(邻居表)node512k最多 512k 条邻居条目
Endpoints(端点)node64k每个节点最多 64k 个本地端点 + 主机 IP
IP cachenode512k跨所有集群最多 256k 个端点(IPv4+IPv6 混合),或最多 512k 个端点(仅 IPv4 或仅 IPv6)
Service Load Balancer(服务负载均衡)node64k跨所有集群最多约 3k 个 clusterIP/nodePort Service(详见下文 Service LB Map Sizing 一节)
Service Backends(服务后端)node64k跨所有集群的所有服务累计最多 64k 个唯一后端
Service Source Rangesnode64k跨所有服务累计最多 64k 条 LB 源地址范围
Service Session Affinitynode64k来自不同客户端的最多 64k 条亲和性记录
Policy(策略)endpoint16k单个特定端点的最多 16k 个"身份 + 端口 + 协议"允许组合
IPv4 Fragmentation(IPv4 分片)node8k节点上同时最多 8k 个在途分片数据报
IPv6 Fragmentation(IPv6 分片)node8k节点上同时最多 8k 个在途分片数据报
IPv4 Masqnode16k供 BPF 版 ip-masq-agent 使用的最多 16k 条 IPv4 CIDR
IPv6 Masqnode16k供 BPF 版 ip-masq-agent 使用的最多 16k 条 IPv6 CIDR
Egress Policy(出站策略)node16k跨所有集群的所有目标 CIDR 上最多 16k 个端点
Nodenode16k跨所有集群最多 16k 个不同的节点 IP(IPv4 与 IPv6)

从上表可以归纳出几个规划要点:

  • 作用域差异:绝大多数 Map 是节点级(node)共享的,唯独 Policy Map 是**每端点(endpoint)**独立的——它的上限(16k)表示单个端点最多允许的策略组合数,而非整个节点。
  • 连接跟踪是扩容瓶颈:CT(Connection Tracking)Map 的 TCP/UDP 分离设计(512k TCP + 256k UDP)直接决定了节点能支撑的最大并发连接数。
  • 负载均衡相关 Map 的规模:Service LB、Backends、Source Ranges、Session Affinity 四个 Map 都受服务规模约束,具体估算方法见后文。

从源码确认默认值

这些默认上限在 pkg/option/config.go 中以常量形式定义,例如:

  • CTMapEntriesGlobalTCPDefault = 2 << 18(即 512Ki 条目,对应文档的 512k TCP);
  • CTMapEntriesGlobalAnyDefault = 2 << 17(即 256Ki 条目,对应 256k UDP);
  • NATMapEntriesGlobalDefault = int((CTMapEntriesGlobalTCPDefault + CTMapEntriesGlobalAnyDefault) * 2 / 3)(即默认按 CT 合计的 2/3 计算);
  • PolicyMapMax = 1 << 16FragmentsMapMax = 1 << 16等(见 pkg/option/config.go)。

同时,pkg/datapath/maps/maps_generated.go中登记了各 Map 的实际内核名称,如cilium_ct4_globalcilium_ct6_globalcilium_ct_any4_globalcilium_ct_any6_globalcilium_auth_mapcilium_lb4_services_v2cilium_snat_v4_externalcilium_nodeport_neigh4等(见 maps_generated.go),可用于在节点上通过bpftool map list对照检查实际生效的容量。

使用命令行参数覆盖 Map 容量上限

对于部分 BPF Map,可以通过cilium-agent的命令行选项覆盖默认容量上限。文档明确支持的参数包括:

命令行选项作用
--bpf-auth-map-maxAuth Map 最大条目数
--bpf-ct-global-tcp-max全局 TCP 连接跟踪 Map 最大条目数
--bpf-ct-global-any-max全局非 TCP(UDP 等)连接跟踪 Map 最大条目数
--bpf-nat-global-maxNAT Map 最大条目数
--bpf-neigh-global-max邻居表 Map 最大条目数
--bpf-policy-map-max每端点策略 Map 最大条目数
--bpf-fragments-map-max分片 Map 最大条目数
--bpf-lb-map-maxService Load Balancer Map 最大条目数

这些选项在源码中有完整登记:CT/NAT/Neigh 选项定义于 pkg/option/config.go(CTMapEntriesGlobalTCPName = "bpf-ct-global-tcp-max"NATMapEntriesGlobalName = "bpf-nat-global-max"NeighMapEntriesGlobalName = "bpf-neigh-global-max"等),并在Populate阶段通过vp.GetInt(...)读取后写入DaemonConfig(见 pkg/option/config.go);--bpf-lb-map-max定义于 pkg/loadbalancer/config.go,--bpf-policy-map-max定义于 pkg/maps/policymap/cell.go。

CT 与 NAT 表之间的 2/3 约束

这里有一条容易被忽略的硬性约束:当显式指定了--bpf-ct-global-tcp-max和/或--bpf-ct-global-any-max时,NAT 表大小(--bpf-nat-global-max不得超过组合 CT 表大小(TCP + UDP)的 2/3。以下两种情况会自动生效:

  1. 未显式设置--bpf-nat-global-max
  2. 使用了动态 BPF Map 尺寸(见下文)。

源码层面的实现位于 pkg/option/config.go:当 NAT 大小超过CTMapEntriesGlobalTCP + CTMapEntriesGlobalAny时,会自动封顶为(CTMapEntriesGlobalTCP + CTMapEntriesGlobalAny) * 2 / 3,并输出告警日志。此外,pkg/option/config.go 的校验逻辑还保证 CT/NAT 条目数落在LimitTableMin(1Ki)到LimitTableMax(16Mi,即单个 Map 约 1GiB 条目)之间,超出范围会直接报错。

一个配置示例

假设要为每节点 8 vCPU、30GiB 内存的节点显式配置容量:

cilium-agent \ --bpf-ct-global-tcp-max=524288 \ --bpf-ct-global-any-max=262144 \ --bpf-nat-global-max=524288 \ --bpf-neigh-global-max=524288 \ --bpf-policy-map-max=16384 \ --bpf-lb-map-max=65536

注意此时 NAT 表(524288)不能超过 CT 合计(524288 + 262144)的 2/3,即最大应为 524288,示例中恰好满足约束。

基于内存的动态 Map 尺寸:--bpf-map-dynamic-size-ratio

手动规划每个 Map 的上限既繁琐又容易出错。Cilium 提供了--bpf-map-dynamic-size-ratio选项:在 agent 启动时,根据给定比例的系统总内存自动确定多个大型 BPF Map 的上限。例如,比例0.0025表示这些 Map 最多使用系统总内存的 0.25%。

该选项影响以下内存占用最大的 BPF Map:

  • cilium_ct_{4,6}_global(TCP 连接跟踪)
  • cilium_ct_{4,6}_any(UDP/任意协议连接跟踪)
  • cilium_nodeport_neigh{4,6}(NodePort 邻居表)
  • cilium_snat_v{4,6}_external(外部 SNAT)
  • cilium_lb{4,6}_reverse_sk(sock reverse NAT)

这些内核 Map 名称均可在 pkg/datapath/maps/maps_generated.go 中找到对应登记。

动态计算原理(源码级)

动态尺寸的计算逻辑位于 pkg/option/config.go 的getDynamicSizeCalculator

  1. 计算可用内存memoryAvailableForMaps = totalMemory * dynamicSizeRatio
  2. 计算默认内存基线:将各 Map 默认条目数乘以其单元素大小(SizeofCTElementSizeofNATElementSizeofNeighElementSizeofSockRevElement)求和,得到totalMapMemoryDefault
  3. 按比例分配:每个 Map 的条目数按(entriesDefault * memoryAvailableForMaps) / totalMapMemoryDefault计算,并受最小值(如 TCP CT 为 128Ki、UDP CT 为 64Ki、NAT 为 128Ki)与最大值LimitTableMax约束;
  4. CPU 对齐:启用分布式 LRU 时,条目数会向上取整到num_possible_cpus()的倍数,与内核htab_map_alloc()的行为保持一致,避免 Map 属性不匹配导致反复重建(见 pkg/option/config.go)。

注释中还给出了直观的计算示例:512MB 内存 → CT TCP 约 33140 条;1GB → 约 66280 条;4GB → 约 265121 条;16GB → 约 1060485 条。

显式设置优先:如果某个 Map 已通过命令行选项显式指定,则动态尺寸对该 Map 失效,使用用户提供的值(见calculateDynamicBPFMapSizesif !vp.IsSet(...)的分支逻辑,pkg/option/config.go)。

与 kube-proxy 的连接跟踪对比

kube-proxy根据机器 CPU 核数设置 Linux 连接跟踪表(nf_conntrack)的最大条目数:每个核默认 32768 条,且无论核数多少,最低为 131072 条。Cilium 则有自己基于 BPF Map 的连接跟踪表,条目数根据节点总内存计算,且无论内存多少,最低为 131072 条

当 Cilium 配置--bpf-map-dynamic-size-ratio: 0.0025时,两种方案的连接跟踪条目数对比如下(数据来自 maps.rst):

vCPU内存(GiB)Kube-proxy CT 条目Cilium CT 条目
13.75131072131072
27.5131072131072
415131072131072
830262144284560
1660524288569120
3212010485761138240
6424020971522276480
9636031457284552960

可以观察到:小内存节点上两者都收敛于 131072 的下限;从 8 vCPU / 30GiB 开始,Cilium 由于基于内存而非核数计算,CT 条目数开始超过 kube-proxy,且在内存增长更快的高端节点上优势更明显(96 vCPU / 360GiB 时 Cilium 约 455 万条,而 kube-proxy 约 314 万条)。这印证了 BPF 数据通路在高并发场景下连接跟踪容量的扩展性优势。

Service LB Map Sizing:服务负载均衡容量估算

核心 Map 与容量影响

Cilium 使用名为cilium_lb{4,6}_services_v2的 LB services Map 存放 clusterIP 与 nodePort 类型的 Service 负载均衡条目,通过--bpf-lb-map-max配置,默认 64k。如果该 Map 写满,Cilium 可能无法对 Service 更新进行调和(reconcile),从而影响 Service IP 的连通性,或导致无法创建新 Service

在节点上可通过bpftool map list | grep cilium_lb找到cilium_lb4_services_v2/cilium_lb6_services_v2两个实例(对应 maps_generated.go 中的登记)。

容量计算公式

单个 Service 在 LB Map 中产生的条目数取决于两个因素:Service 选中的 Pod 后端数量,以及Service spec 中的端口/协议条目数量

每个 Service 的 LB Map 条目数 =(每个 Service 的端点数量)×(每个 Service 的端口/协议数量)

由此可以粗略估算所需的整体 Map 大小:

LB Map 条目数 ≈(LB Service 数量)×(每个 Service 的平均端点数量)×(每个 Service 的平均端口/协议数量)

例如:假设有 1000 个 Service,平均每个 Service 选中 3 个 Pod 后端、暴露 2 个端口/协议,则所需条目约为1000 × 3 × 2 = 6000,远低于 64k 默认上限;但如果单个 Service 选中了数千个 Pod 后端,则必须单独核算。

注意:该启发式估算假设各 Service 选中的 Pod 数量与端口/协议条目大致呈正态分布。如果你的场景存在较大离群值(例如某个 Service 选中了非常庞大的 Pod 后端集合),则可能需要做更精确的逐项估算。

扩容的代价:连接中断风险

一旦 Cilium 在某个节点上创建了 Service LB Map(即该节点首次运行 Cilium agent 之后),再尝试修改容量参数并重启 Cilium,将导致连接中断——因为新 Map 需要重新填充现有 Service 条目。因此,如果连接中断不可接受,务必在安装 Cilium 之前仔细评估 Map 需求,将容量规划前置。

小结与容量规划建议

规划要点建议
默认上限足够大多数场景512k CT、512k NAT、64k Service LB 是常见节点规模的合理起点
高并发节点优先用动态尺寸通过--bpf-map-dynamic-size-ratio=0.0025让 agent 按内存自动分配,避免手工估算
显式配置必须满足 CT/NAT 2/3 约束NAT 表 ≤ (CT TCP + CT UDP) × 2/3,否则会被自动封顶或启动校验失败
Service 规模巨大时提前核算使用"Service 数 × 平均后端数 × 平均端口数"估算cilium_lb{4,6}_services_v2所需容量
扩容动作尽量前置首次运行 agent 后调整 LB Map 容量并重启会中断连接,尽量在安装阶段定稿
参考源码核对实际生效值常量默认值见 pkg/option/config.go,Map 内核名称见 pkg/datapath/maps/maps_generated.go

容量规划的核心原则是:默认值适合作为起点,动态尺寸适合作为通用基线,显式覆盖用于已知的极端场景,而 Service LB 必须结合真实服务拓扑在部署前完成核算。理解这些 Map 上限及其背后的源码实现(pkg/option/config.go 中的默认常量、校验与动态计算逻辑),将帮助你在规模增长时做出有依据的调优决策。

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

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

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

GPU Aspect-Based架构解析:专用计算单元设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 9:50:10

机器人端侧AI硬件选型:MCU与MPU的确定性与算力博弈

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 9:46:32

Context-Mode:基于MCP+SQLite+FTS5的本地化上下文感知工作流

1. 项目概述&#xff1a;Context-Mode 不是玄学&#xff0c;而是现代数据驱动工作流的底层操作系统 “Context-Mode”这个词最近在开发者、AI 工程师和低代码平台使用者的圈子里频繁出现&#xff0c;但它既不是某个新发布的编程语言&#xff0c;也不是某家大厂刚推出的闭源 SDK…

作者头像 李华
网站建设 2026/9/14 9:44:58

强化学习与VR虚拟建模在工业控制中的融合应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华