第 3 篇 说明程序挂在哪;本篇钉 Map 状态轴。Cilium 数据面的权威运行态很大一块住在 BPF map 里:策略允许谁、Service 指到哪、连接是否已跟踪。内核里 map 类型、哈希冲突与内存布局见 ebpf/;这里只写 Cilium 用哪些表、默认上限、满了或陈旧时人看到什么。
本篇在系列中的位置
篇目 核心内容 第 3 篇 · BPF 挂载 hook 与加载 第 4 篇 · 关键 BPF Map policy / service / CT 等职责与失败表象 第 5 篇 · 东西向包路径 包在路径上何时查这些表 系列目录 全部篇目
版本锚定:Cilium v1.20.0;
docs.cilium.io/en/v1.20/network/ebpf/maps/;源码pkg/maps/*、bpf/@ v1.20.0。容量数字引用官方默认表;生产应用--bpf-*-max/ dynamic sizing 后以实际配置为准。
一、先建立「表 → 职责」卡片
官方 eBPF Maps 文档给出默认上限与规模含义(节选,口径为文档默认值):
| Map(文档名) | Scope | 默认上限(文档) | 规模含义(文档) |
|---|---|---|---|
| Connection Tracking | node | 512k TCP / 256k UDP | 并发连接与预期 UDP 应答规模 |
| NAT | node | 512k | NAT 条目上限 |
| Endpoints | node | 64k | 本地 endpoint + host IP |
| IP cache | node | 512k | 跨集群 endpoint 解析规模叙述 |
| Service Load Balancer | node | 64k | LB 服务条目;与后端数/端口数耦合 |
| Service Backends | node | 64k | 累计唯一后端 |
| Policy | endpoint | 16k | 每 endpoint 允许的 identity+port+protocol 对 |
| Auth / Neighbor / Frag / … | node | 见文档 | 认证关系、邻居、分片等 |
agent 可用
--bpf-policy-map-max、--bpf-ct-global-tcp-max、--bpf-ct-global-any-max、--bpf-nat-global-max、--bpf-lb-map-max
等覆盖;亦可用 --bpf-map-dynamic-size-ratio
按内存比例动态设定若干大表(文档列出受影响的
CT/NAT/neigh/snat/reverse_sk 等)。文档硬约束:若显式设定 CT
上限,NAT 表不得超过 CT(TCP+UDP)合计的
2/3——否则 NAT 与 CT 生命周期会错配。
pkg/maps/
下可见与文档同构的包名:policymap、ctmap、nat、ipcache、lxcmap、authmap、fragmap
等。LB 相关实现分布在 datapath/bpf 的 lb 逻辑与对应 map
封装中;文档称服务 LB map 为
cilium_lb{4,6}_services_v2。
二、Policy map:身份策略的执行表
职责
每 endpoint 一张(前缀)policy map,键语义是
identity + 端口 +
协议(及方向相关字段),值编码允许/拒绝等。源码
pkg/maps/policymap:
// MapName is the prefix for endpoint-specific policy maps...
// "_v3_": semantic change due to policy identity aggregation.
MapName = "cilium_policy_v3_"摘录来自 v1.20.0;注释要求:BPF 格式或既有布局的语义变化时必须改名,以便与旧 map/程序干净分离。v1.20 的 v3 对应 policy identity aggregation 语义,而非单纯字段重排。
另有 cilium_call_policy /
cilium_egresscall_policy 一类 prog
array,用于 tail call 进入 endpoint
策略程序——它们是「跳转表」,与「允许关系表」分工不同。
失败表象
| 现象方向 | 优先怀疑 |
|---|---|
| 特定 Pod 在策略变复杂后开始拒绝合法对端 | 该 endpoint 的 policy map 16k 默认上限被打满(文档:Max 16k allowed identity+port+protocol pairs) |
| 升级 1.19↔︎1.20 后已有连接异常 | map 世代/语义切换窗口;上游用改名前缀降低缺身份丢包 |
| 标签变更后短暂 deny/allow | 条目尚未收敛(见 第 2 篇),不一定是满表 |
压力指标方向:agent 提供 policy map pressure 相关阈值(cmdref 中有 pressure threshold 类选项)。无集群时只记「满表会让策略无法继续写入」,不编造具体 metrics 名输出。
三、Service / Backend map:kube-proxy 替代的状态面
职责
文档:Service LB
map(cilium_lb{4,6}_services_v2)保存 ClusterIP
/ NodePort 等负载均衡条目;默认经
--bpf-lb-map-max 设为 64k。满表时
Cilium 可能无法 reconcile Service 更新,影响连通到
Service IP 或创建新 Service
的能力——这是官方写明的失败模式,不是推测。
Sizing 启发式(文档公式):
[ (#) (#) ]
[ (#) () () ]
文档提醒:若存在「选中海量后端」的离群 Service,均值启发式会低估。Backend map、source range、session affinity 另有独立上限(各默认 64k 叙事)。
失败表象
| 现象方向 | 优先怀疑 |
|---|---|
| 部分 VIP 不通、新建 Service 不生效,节点 CPU 未必高 | LB map 满或 reconcile 失败 |
| 扩容后端后流量仍打到旧 Pod | backend/服务条目未更新或缓存路径异常 |
调整 --bpf-lb-map-max 后重启 |
文档警告:map 已创建后再改大小并重启会导致重填期间连接中断 |
与 第 6 篇 的衔接:本篇只钉「状态在哪、满了怎样」;具体 ClusterIP/NodePort 走哪条 BPF 路径在第 6 篇展开。相对 iptables kube-proxy:规则风暴换成 map 容量与 reconcile 风暴——失败模式从「iptables-restore 卡顿」变为「插入失败 / 条目陈旧」。
四、CT 与 NAT:连接状态与地址转换
职责
Cilium 使用自有 BPF CT 表,而不是把关键路径建立在 netfilter conntrack 上(与「旁路 netfilter」叙事一致;回退路径除外)。文档对比:kube-proxy 按 CPU 核数估算内核 CT 上限;Cilium CT 按内存与 dynamic ratio 估算,并给出示例对照表(同 ratio 0.0025 下不同 vCPU/内存的条目数)。这些数字是文档示例,不是本站实测。
NAT map 服务 SNAT/DNAT 类条目;与 CT 的 2/3 约束防止 NAT 条目无法被 CT 生命周期覆盖。
失败表象
| 现象方向 | 优先怀疑 |
|---|---|
| 突发短连接后新建失败,旧长连接仍在 | CT 表压力 / 驱逐 |
| 出站访问外部或 NodePort 回程异常 | NAT 与 CT 不匹配、NAT 满 |
| 仅 UDP / 仅 TCP 出问题 | ct_any vs ct_tcp
不同上限与超时配置 |
超时类选项(cmdref)如 service TCP/ANY 超时会影响「Service 条目在 CT 中的寿命」——表象可能是偶发后端切换或连接复用异常;需与应用超时区分。本篇不下「应设多少秒」的处方。
五、ipcache、Endpoints 与其它相关表
| Map | 职责直觉 | 失败表象方向 |
|---|---|---|
| IP cache | IP → Identity(及节点信息)解析 | 身份窗口、跨节点策略误判、陈旧身份 |
| Endpoints | 本地 endpoint / host IP | 本地投递找不到 endpoint |
| Neighbor | NodePort 等路径邻居缓存 | 邻居相关转发异常 |
| Auth | 认证关系(若启用) | 认证策略失败 |
| Frag | 分片重组跟踪 | 分片流量异常 |
ipcache 是 Identity 轴与包路径轴的桥梁:策略键是身份,包上先看到的是 IP。缓存滞后会把第 2 篇的变更窗口放大到「IP 已变身份未变」或反向。ClusterMesh 下 ipcache 压力与集群规模耦合——第 11 篇再收。
Endpoints map 的节点局部性常被忽略:它回答「这个节点上谁可以收这个包」,不回答「集群里谁拥有这个身份」。跨节点不通时两边都要查——源侧策略与 ipcache、目的侧 endpoints 与目的侧 policy——不能只在出问题的客户端节点上翻一张表。
分片表默认上限相对较小(文档 IPv4/IPv6 fragmentation 各 8k 量级叙事)。若业务大量依赖分片(少见但在某些 UDP/隧道场景出现),满表表象会像「随机丢大包」,却与 policy deny 无关。把 MTU/分片问题误判成策略,是 Map 轴常见归因错误。
动态 sizing 文档还给出与 kube-proxy CT 条目的对照表(按 vCPU/内存示例)。引用时必须保持口径:那是官方在给定 ratio 下的计算示例,用于理解数量级,不是本站在某一云厂商规格上的实测,也不是「Cilium CT 一定更大/更小」的排名结论。
六、排障顺序:先问哪张表
Symptom → which map axis?
policy deny / label change → policy map + ipcache (+ identity)
Service VIP / NodePort broken → LB services + backends (+ CT)
burst new flows fail → CT (+ NAT)
local delivery miss → endpoints map
upgrade weirdness → map generation (e.g. policy_v3_) + prog reload
口诀与第 1 篇一致:先点名表,再改 YAML。改 NetworkPolicy 解决不了 LB map 满;加大 CT 也解决不了 identity 未解析。
内核实现(hash/LRU/per-CPU 阵列等)如何影响延迟与内存,见 ebpf/ 的 Map 篇章;本系列只要求能把症状映射到上表。
同一症状也可能跨表:例如「偶发连不上 Service」既可能是 CT
驱逐后的重新选后端,也可能是 backend map 与 EndpointSlice
短暂不一致,还可能是目的侧 policy
在身份窗口内拒绝。正确顺序是:先用第 5
篇停顿点缩小到一两类表,再用本篇失败表象做假说,而不是同时改三个
--bpf-*-max。
容量规划上再钉一句工程约束:LB map 文档写明首次创建后改大小并重启会中断连接重填。因此「先用默认 64k 上线、不够再改」会把容量事故变成变更事故。更稳的做法是按启发式估算后端×端口积,对离群 Service 单独核算,把上限写进安装参数——这是 Map 轴上的发布纪律,不是性能玄学。
相对 k8s-network/13 产品文里的 map 概览,本篇多出来的是满表与世代切换的失败合同:产品文告诉你有哪些表,本篇告诉你表拒绝服务时人会看见什么。与 ebpf/ 的分工同样清楚:那边解释 map 在内核里如何分配与查找;这边解释 Cilium 把哪些控制面对象编译进哪些表、以及表满时的业务症状。
七、学术谱系、争论与开放问题
谱系:可编程数据面把「规则列表」换成「可更新的内核映射」——与经典 BPF map 作为共享状态的范式一致。Cilium 的贡献在于把 CNI 策略 / Service / CT 做成一套命名稳定、可配置上限、可动态 sizing 的映射集合,并把失败写成运维可理解的「满表 / reconcile 失败」。
相对经典 netfilter 规则表:iptables 的失败常常是线性匹配变慢与全量刷新卡顿;BPF map 的失败常常是插入返回满与世代切换窗口。两者都是「状态更新跟不上控制面意图」,但信号完全不同。若团队故障手册仍写「检查 iptables 规则条数」,在 KPR 集群上会系统性漏掉 Map 轴。
争论:固定上限 vs 动态 sizing
| 侧 | 主张 | 风险 |
|---|---|---|
固定 --bpf-*-max |
容量可预测;便于容量规划 | 估小则故障;估大则内存常驻 |
| dynamic ratio | 随节点内存伸缩 | 不同节点条目上限不一致;行为更难横向对比 |
文档同时提供两种旋钮,本身说明社区未把单一策略当作教条。可检验问题是:你的故障手册是否包含 map 压力信号,还是只有「重启 agent」。
另一争论与第 2 篇呼应:identity aggregation 减少 policy 条目是否值得排障可读性下降。聚合让 map 更不容易满,但从「一条 map 记录」反推「哪条 CiliumNetworkPolicy」更难。第 7 篇策略编译会给出控制面侧的选择器展开;本篇只强调数据面看到的是已经聚合后的键。
开放问题:
- map 压力与节点规模可观测性是否足够在「将满」前提前告警(系列研究台账 01–04)。
- identity aggregation 降低 policy 条目的收益,与排障时「聚合后更难从 map 反推选择器」的张力——第 7、13 篇。
- LB map 扩容必须中断的约束,在何种编排下可被蓝绿节点池吸收——第 6、12 篇。
- 多集群 ipcache 上限与 ClusterMesh 身份传播如何共同决定「远程身份陈旧」的概率——第 11 篇。
八、小结
- Policy / Service / CT(及 ipcache 等)是 Cilium 数据面的状态主板。
- 官方默认上限与满表后果是 A 级排障依据;动态 sizing 与 2/3 NAT 约束必须写进容量规划。
- v1.20
cilium_policy_v3_标记身份聚合语义世代。 - 内核 map 细节外链 ebpf/;本篇只钉 Cilium 职责与表象。
- 下一篇沿包路径走一遍:何时查哪张表。
九、参考资料
规范 / 官方文档(A)
- Cilium v1.20 eBPF Maps —
docs.cilium.io/en/v1.20/network/ebpf/maps/(含 Service LB Map Sizing)。 - Cilium agent
cmdref(
--bpf-*-max、--bpf-map-dynamic-size-ratio)—docs.cilium.io/en/v1.20/cmdref/cilium-agent/。
源码(A)
pkg/maps/policymap、pkg/maps/ctmap、pkg/maps/nat、pkg/maps/ipcache、pkg/maps/lxcmap@ v1.20.0bpf/lib/policy.h、bpf/lib/lb.h等 @ v1.20.0
站内对照
实验台账
- 无集群:不粘贴
cilium bpf/bpftool map输出;容量数字仅引用文档。
→ 上一篇:BPF 挂载 · 系列目录 · 下一篇:东西向包路径
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Cilium / eBPF】数据面全景:五轴坐标系与 16 篇路线
相对 k8s-network/13、ebpf/ 与 Envoy/HAProxy 排除树,钉清 Cilium eBPF 数据面内核缺口;定义 Identity、BPF 挂载、Map 状态、包路径、策略与观测五条坐标系,给出 16 篇阅读路线。
【Cilium / eBPF】Endpoint 与 Identity:数字身份、标签选择与生命周期
钉清 Cilium Endpoint 与 Numeric Identity 的关系:安全相关标签如何导出集群范围数字身份、保留身份与 well-known 身份、标签变更时的短暂 deny/allow 窗口,以及相对 IP 策略消除了什么。
【Cilium / eBPF】BPF 挂载与程序生命周期:TC、XDP、cgroup 在路径上的角色
说明 Cilium v1.20 如何在 XDP、TC、cgroup socket 等 hook 上分工;对照 bpf_xdp/host/lxc/sock 源码入口与 Intro 中的数据面对象;交代加载/替换边界,不重写 verifier 算法。
【Cilium / eBPF】东西向包路径:Pod→Pod 停顿点与 netfilter 旁路
沿 Cilium v1.20 Life of a Packet 钉清同节点与跨节点东西向停顿点:Endpoint Policy、Service、socket 加速、加密与 L7 重定向;说明与 netfilter/kube-proxy 旁路关系,并为 kube-proxy 替代篇铺路。