第 1 篇 把排障收束到五轴;本篇钉 Identity 轴。读者常见误区有两个:一是把 Cilium「基于标签的策略」理解成运行时仍在匹配 Pod IP;二是把滚动更新时的偶发拒绝一律写成「NetworkPolicy 写错了」。真正要钉死的是:Endpoint 是节点上的网络实体,Identity 是策略在 BPF 里看到的数字键;标签变更会迫使身份重解析,并可能打开短暂的拒绝或放行窗口。
本篇在系列中的位置
篇目 核心内容 第 1 篇 · 数据面全景 五轴坐标系 第 2 篇 · Endpoint 与 Identity 数字身份、标签选择、生命周期与变更窗口 第 3 篇 · BPF 挂载 TC/XDP/cgroup 角色 系列目录 全部篇目
版本锚定:Cilium v1.20.0(
docs.cilium.io/en/v1.20/;源码 tag v1.20.0,重点pkg/identity/)。机制叙述对齐官方 Terminology 与 Identity-Based 文档。无真实集群则不粘贴伪造cilium endpoint/ identity 列表输出。
一、Endpoint:节点上的网络实体,不是「又一个 Pod 别名」
Cilium Terminology(v1.20)把 Endpoint 定义为:共享同一地址、由 Cilium 在网络上代表的一组应用容器。Kubernetes 下典型就是一个 Pod——多容器共享网络命名空间与 IP,因此共享一个 Endpoint。
关键可核对点:
| 概念 | 作用域 | 用途 |
|---|---|---|
| Endpoint ID | 单节点内唯一 | agent 本地管理、程序/map 绑定 |
| Pod IP / 地址 | 集群编址 | 路由与连接;不是策略的稳定主键 |
| Labels(带 source 前缀) | 元数据 | 导出 Identity;如 k8s:app=frontend |
标签带 source
前缀以避免冲突:k8s: 来自
Kubernetes,reserved:
为保留身份,未指定源时选择器可用 any:
匹配任意源(Terminology · Label
Source)。策略选择器匹配的是键值对,不是「长得像」的字符串;my.corp.foo
不会匹配到 my.corp.foo=bar
这类带值标签——文档写得很硬。
Endpoint 的生命周期由编排事件驱动:Pod 创建 → Cilium 创建 Endpoint → 解析 Identity → 把身份与策略写入数据面;Pod 删除则回收。Endpoint ID 不会也不应被当成跨节点稳定标识——跨节点协调的是 Identity 与 IP→Identity 缓存(ipcache),不是本地 endpoint id。
相对 k8s-network/13 的产品叙述,本篇收紧一句:产品文解释「为什么用 Identity」;这里解释 Identity 相对 Endpoint / IP 的职责切分,以便后面 map 与包路径有主语。
二、Numeric Identity:策略匹配的稳定键
身份从哪来
官方 Identity-Based 文档把问题钉成:若策略用 IP
列表表达「role=frontend →
role=backend」,则每个 backend
所在节点都必须维护全部 frontend IP;frontend
扩缩容会迫使大量节点更新过滤器,且新 Pod
启动可能必须等待规则传播完成,否则误丢包。
Cilium 的回答是:把安全与编址拆开。身份由(安全相关)标签集合导出,并分配集群范围唯一的数字 ID;同标签集合的 Pod 共享同一 Identity。新增同身份 Pod 时,主要工作是解析已有身份并更新本地解析缓存,而不是让所有 backend 节点重写 IP 列表。
数据面后果直接写进第 1 篇的不变量:BPF policy map
的键空间是 identity + port +
protocol(及方向),不是「每个源 IP
一条规则」。源码侧 pkg/maps/policymap 把
endpoint 专用 map 命名为
cilium_policy_v3_*,注释写明 v3 对应
policy identity aggregation
的语义变更——版本升级时 map
名变更用于强制重建,避免旧语义条目残留。
安全相关标签
并非 Pod 上每一个标签都进入身份。Terminology
要求配置有意义的标签前缀;历史默认叙事以
id. 前缀为例,Kubernetes 环境中实际还会纳入一组
agent
配置的相关标签(具体前缀以安装配置为准)。时间戳、构建号一类元数据若误入安全相关集合,会造成身份爆炸:每个唯一标签组合一个
Identity,policy map 与分配存储压力上升。
工程判断(与文档一致的方向):把「会改变信任边界的标签」留在安全相关集合,把「仅用于运维检索的标签」排除在外。排障时若看到 Identity 数量远高于「应用角色数」,先查标签基数,再查策略复杂度。
保留身份与 well-known 身份
文档给出的保留身份(节选)是排障高频锚点:
| Identity | Numeric ID | 含义(文档口径) |
|---|---|---|
reserved:unknown |
0 | 未能导出身份 |
reserved:host |
1 | 本地主机相关流量 |
reserved:world |
2 | 集群外端点 |
reserved:unmanaged |
3 | 非 Cilium 管理端点 |
reserved:health |
4 | cilium-health |
reserved:init |
5 | 身份尚未解析完成的引导阶段 |
reserved:remote-node |
6 | 远程节点主机集合 |
reserved:kube-apiserver |
7 | kube-apiserver 后端所在 |
reserved:ingress |
8 | Ingress 代理源地址侧 |
Well-known 身份(如 kube-dns / CoreDNS / cilium-operator
的固定数字
ID)用于不依赖外部分配存储即可引导关键系统流量——文档明确这是为了在依赖尚未就绪时仍能强制策略连通。源码侧
pkg/identity 将保留常量与 scope 位(全局 / 本地
CIDR / remote-node)编码在 numeric identity
的高位语义中;集群 ID 位宽与 ClusterMesh 相关,展开见后续第
11 篇。
reserved:init 尤其重要:当创建 Endpoint
时元数据尚不齐,文档写明可分配 init 身份。策略若未显式允许
init,引导窗口内流量可能被拒绝——这是设计上的过渡态,不是「随机丢包」。
三、生命周期:分配、共享、变更
Pod start / label sync
→ create Endpoint (node-local id)
→ select security-relevant labels
→ allocate or resolve Numeric Identity (cluster-wide)
→ populate ipcache / policy maps / endpoint programs
→ ready for L3/L4 enforcement
集群内协调:Terminology
描述通过分布式键值存储做「若未见过该标签集合则分配新
ID」的原子操作;现代部署亦常见 CRD
分配模式(以安装时
identity-allocation-mode
等配置为准)。无论存储后端是 kvstore 还是
CRD,语义目标相同:同标签集合 →
同一数字身份;跨节点共享。
共享身份的收益与代价成对出现:
- 收益:扩缩容同角色 Pod 不迫使策略键空间按 IP 线性膨胀;backend 节点不必为每个新 frontend IP 改规则(Identity-Based 文档的核心论证)。
- 代价:身份是集群级共享状态。分配存储抖动、CRD/kvstore 延迟、或节点本地缓存滞后,会表现为「Pod Running 但策略仍按旧身份或 init 执行」。
相对 IP 策略,Identity 消除的是「IP churn → 全量规则重写」这条放大路径;它不消除「标签集合变化 → 身份必须重解析」本身。下一节专门钉变更窗口。
四、标签变更:短暂拒绝与放行窗口
每当 Pod / workload 标签变化,Terminology 写明身份会 reconfirm and automatically modified as required。结合 init 身份与 map reconcile,工程上至少要区分三类窗口(机制方向有文档与源码支撑;具体时长依赖控制面与节点负载,本文不下未实测数字):
1. 引导拒绝窗口(init)
新 Endpoint 在标签未齐时可能处于
reserved:init。若策略默认拒绝且未允许
init,连接在身份解析完成前失败。表象:Pod 已
Running、DNS/业务偶发超时,稍后自愈。优先查身份是否仍停在
init,而不是先改应用探针。
2. 变更拒绝窗口(身份已切、策略未齐)
标签变更导致新 Identity 已生效,但各节点
policy map / ipcache
尚未收敛到「允许该新身份」的条目。在默认拒绝模型下,窗口内流量被
drop。表象:一次 kubectl label
或滚动更新伴随短促失败;Hubble 类信号上常接近 policy
deny(字段语义见后续 Hubble 篇)。
3. 变更放行窗口(旧身份残留)
相反方向:旧身份对应的允许条目尚未从 map 清除,而工作负载已贴上更严格标签意图。窗口内可能仍按旧允许关系放行。表象:以为已经收紧隔离,短时间内旧客户端仍能连上。这与「策略写错」不同,是收敛顺序问题;第 7 篇策略编译会回到 map 更新原子性。
| 窗口类型 | 典型触发 | 优先检查 |
|---|---|---|
| init 拒绝 | 冷启动、元数据延迟 | Endpoint 是否仍 init;分配存储是否健康 |
| 新身份拒绝 | 改标签、换 ServiceAccount 相关标签 | 新 Identity 是否已出现在策略允许集 |
| 旧身份放行 | 收紧标签 / 收紧 CNP | 旧 Identity 引用是否仍在 map |
排障口诀:把「偶发」翻译成哪一种窗口,再决定是等收敛、扩超时,还是改发布顺序(先扩允许集合、再切标签)。不要把三类窗口都写成「Cilium 不稳定」。
开放问题(系列级,本篇只立靶):标签风暴下身份分配延迟与 map 压力如何被可观测信号及时暴露——第 12–13 篇回收;学术/工程对照见文末研究讨论。
五、学术谱系、争论与开放问题
谱系:经典防火墙与 SDN ACL 以地址集合为策略主语;微服务编排把 churn 推高后,地址集合更新成为规模瓶颈。Cilium 文档中的 Identity-Based 模型是对该瓶颈的工程回答:策略主语改为标签导出的共享身份。可编程执行面则落在 eBPF map 查找(见 第 4 篇),而不是 netfilter 线性链——与 ebpf/ 中 map 作为状态原语的讨论同构。
争论:IP 策略简单性 vs Identity 一致性窗口
| 侧 | 主张 | 代价 |
|---|---|---|
| IP / CIDR 策略 | 心智模型贴近传统防火墙;无身份分配依赖 | Pod churn 下规则更新放大;易与 IP 复用/迁移纠缠 |
| Identity 策略 | 扩缩容同角色几乎不改策略键;跨节点共享身份 | 依赖分配存储与缓存收敛;标签变更引入 deny/allow 窗口 |
没有文献能宣布某一侧在所有集群规模下绝对更优。可检验的工程命题是:在你的 churn 与标签基数下,窗口故障是否可归因、是否可被发布流程吸收。若团队无法接受任何身份收敛窗口,却又要求秒级标签热修,应把预期改成「变更必须进入允许集合的两阶段发布」,而不是指望数据面消灭窗口。
开放问题:
- 标签高基数:安全相关标签是否被错误包含构建号 / Pod hash,导致 Identity 接近 Pod 数量——使 Identity 模型退化为「昂贵的 IP」。入口:官方 Terminology · Security Relevant Labels;对照本系列第 4、13 篇 map 压力。
- 多集群身份:ClusterMesh 下身份与集群 ID 编码如何避免冲突与陈旧缓存——第 11 篇展开。
- 与用户态身份:SPIFFE / 网格工作负载身份与 Cilium numeric Identity 的边界(L3/L4 vs L7)——第 10、14 篇对照 envoy/。
六、小结
- Endpoint 是节点局部网络实体;Numeric Identity 是集群范围策略键。
- 安全相关标签决定身份;保留身份(尤其 init)解释引导期行为。
- Identity 消除 IP churn 引发的规则风暴,不消除标签变更的重解析。
- 变更期至少区分 init 拒绝、新身份拒绝、旧身份放行 三类窗口。
- 下一轴是挂载:身份只有写进 hook 上的程序与 map 才成为数据面事实。
七、参考资料
规范 / 官方文档(A)
- Cilium v1.20 Terminology —
docs.cilium.io/en/v1.20/gettingstarted/terminology/(Endpoint、Identity、reserved、well-known)。 - Cilium v1.20 Identity-Based Security —
docs.cilium.io/en/v1.20/security/network/identity/。 - Cilium v1.20 Network Policy Overview —
docs.cilium.io/en/v1.20/security/policy/。
源码(A)
pkg/identity/(numeric identity、reserved、scope)@ v1.20.0pkg/maps/policymap(cilium_policy_v3_、identity aggregation 注释)@ v1.20.0
站内对照
实验台账
- 本篇无集群命令输出;窗口时长不做数字断言。
→ 上一篇:数据面全景 · 系列目录 · 下一篇:BPF 挂载
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Cilium / eBPF】策略编译:NetworkPolicy 到 BPF 与默认拒绝窗口
拆解 Cilium v1.20 如何把 Kubernetes NetworkPolicy / CiliumNetworkPolicy 经 selector→identity 蒸馏进 endpoint policy map;钉死按方向的 default-deny 切换、Deny 优先与 identity 漂移造成的短暂拒绝/放行窗口。
【Cilium / eBPF】排障坐标系:丢包、policy deny、identity 漂移、Service 黑洞与加密失败
按五轴映射 Cilium 东西向故障:通用丢包、Policy denied、identity 漂移窗口、Service/ClusterIP 黑洞、透明加密失败;每轴绑定 status/Hubble/map 层,一次否证一轴。
Cilium / eBPF 数据面内核:从 Identity 到包路径
补齐站内 Cilium 产品单篇与 eBPF 内核实现之上的数据面内核层:Endpoint/Identity、BPF 挂载与 Map、东西向包路径、kube-proxy 替代、策略编译、Hubble、加密与 Mesh/ClusterMesh 边界,并以排障与选型收束。
【Cilium / eBPF】数据面全景:五轴坐标系与 16 篇路线
相对 k8s-network/13、ebpf/ 与 Envoy/HAProxy 排除树,钉清 Cilium eBPF 数据面内核缺口;定义 Identity、BPF 挂载、Map 状态、包路径、策略与观测五条坐标系,给出 16 篇阅读路线。