4. 租户隔离蓝图设计:基于Cilium的NetworkPolicy与基于eBPF的租户标识(Security ID)映射
在灰度批次与多租户共存的网络观测场景中,隔离策略的落地依赖于两层核心机制:Cilium NetworkPolicy 提供声明式的准入控制规则,而 eBPF Security ID 则在数据平面为每个网络包打上不可篡改的租户身份标签。本章详细阐述两者的映射关系与蓝图设计。
4.1 双层隔离模型:策略层与标识层
租户隔离不能仅依赖单一维度。Cilium 将 Kubernetes NetworkPolicy 的能力下沉到 eBPF 层,同时引入 Security Identity (SecID) 作为内核级的租户标识。其核心架构分为两层:
- 策略层(Cilium NetworkPolicy):基于标签选择器(Label Selector)定义允许/拒绝的通信规则,支持 L3/L4/L7 策略。
- 标识层(eBPF Security ID):每个 Kubernetes 端点(Pod)在 Cilium Agent 启动时被分配一个 24-bit 的 Security ID,该 ID 与端点的标签集合(Label Set)进行哈希绑定,并注入到 eBPF Map 中。
4.2 Security ID 的生成与映射机制
Security ID 的生成遵循确定性哈希算法,确保相同标签集合的端点获得相同的 ID。映射关系存储在 Cilium 的全局 Identity Map 中,该 Map 由 Cilium Operator 维护,并通过 BPF Map 同步到每个节点。
| 组件 | 职责 | 数据存储 |
|---|---|---|
| Cilium Operator | 全局 Identity 分配与冲突检测 | etcd / CRD (ciliumidentities) |
| Cilium Agent (本地) | 本地 Identity 缓存与 BPF Map 更新 | BPF_MAP_TYPE_HASH (cilium_identity) |
| eBPF 程序 (TC/XDP) | 运行时根据源/目的 IP 查找 Identity | BPF_MAP_TYPE_LPM_TRIE (cilium_ipcache) |
映射流程如下:
- Pod 创建时,Kubernetes API Server 将 Pod 标签推送至 Cilium Operator。
- Operator 计算标签哈希,分配或复用 Security ID,并写入 CRD。
- Agent 监听 CRD 变化,将
Pod IP → Security ID的映射写入本地的cilium_ipcacheBPF Map。 - eBPF 程序在数据包处理时,通过
bpf_map_lookup_elem获取源/目的 Security ID,并与策略规则中的 ID 列表进行比对。
4.3 NetworkPolicy 到 Security ID 的编译过程
Cilium Agent 在接收到 NetworkPolicy 资源后,会执行一次策略编译(Policy Compilation),将基于标签的规则转换为基于 Security ID 的规则集合。
// 伪代码:策略编译核心逻辑
func compilePolicy(rule NetworkPolicyRule, identityCache map[LabelSet]uint32) []PolicyEntry {
var entries []PolicyEntry
for _, selector := range rule.ToEndpoints {
// 将标签选择器匹配到的所有 Security ID 展开
matchedIDs := identityCache.Match(selector)
for _, id := range matchedIDs {
entries = append(entries, PolicyEntry{
RemoteIdentity: id,
Ports: rule.ToPorts,
Action: rule.Action,
})
}
}
return entries
}
编译后的策略条目被写入 BPF Map(cilium_policy),eBPF 程序在运行时直接查询该 Map,无需再次进行标签匹配,极大提升了数据路径的性能。
4.4 租户隔离蓝图中的映射关系
在灰度批次场景中,每个租户(Tenant)可能对应多个命名空间(Namespace)或一组特定的标签。蓝图设计需要建立 Tenant → Label Set → Security ID 的映射链。
tenant=alpha、tenant=beta。Cilium 会自动为每个标签组合生成独立的 Security ID。在 NetworkPolicy 中,直接引用该标签即可实现租户级别的隔离。
以下是一个典型的租户隔离策略示例:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: tenant-isolation
spec:
endpointSelector:
matchLabels:
tenant: alpha
ingress:
- fromEndpoints:
- matchLabels:
tenant: alpha
egress:
- toEndpoints:
- matchLabels:
tenant: alpha
该策略编译后,eBPF 程序只会允许源 Security ID 属于 tenant=alpha 的流量进入,其他租户的流量即使 IP 可达,也会被直接丢弃。
4.5 映射关系可视化:从标签到 Security ID 的转换
下图展示了从 Pod 标签到 Security ID,再到策略匹配的完整映射链路。
4.6 灰度批次中的租户标识冲突与规避
在灰度批次场景中,同一租户的不同批次(如 stable 与 gray)可能拥有不同的标签组合,导致生成不同的 Security ID。这要求策略设计必须考虑批次的包容性。
batch=gray-v2),而 NetworkPolicy 只引用了 tenant=alpha,则灰度批次与稳定批次之间的流量会被策略允许,因为两者都属于同一租户。但如果策略同时要求 env=stable,则灰度批次将被隔离。务必根据实际隔离粒度设计标签选择器。
下表总结了不同标签设计下的隔离效果:
| 标签设计 | Security ID 数量 | 隔离粒度 | 灰度批次影响 |
|---|---|---|---|
仅使用 tenant 标签 |
1 个 ID / 租户 | 租户级 | 灰度与稳定批次互通 |
使用 tenant + env 标签 |
N 个 ID / 租户 | 环境级 | 灰度与稳定批次隔离 |
使用 tenant + batch 标签 |
M 个 ID / 租户 | 批次级 | 每个批次完全隔离 |
4.7 蓝图设计总结
租户隔离蓝图的成功实施依赖于对 Security ID 映射机制的深入理解。核心要点包括:
- 标签即身份:Security ID 是标签集合的哈希摘要,标签设计直接决定隔离边界。
- 策略编译:NetworkPolicy 在控制平面被编译为基于 ID 的规则,数据平面只做整数匹配。
- 灰度兼容:在灰度批次中,通过调整标签选择器的范围,可以实现从完全隔离到部分互通的灵活控制。
下一层设计将聚焦于如何利用 eBPF 的观测能力,实时捕获这些 Security ID 的匹配情况,并生成可视化的拓扑留痕数据。