4、租户隔离模型:Kubernetes网络策略、CNI插件隔离机制、租户标识符(UID/GID/NetworkNamespace)

在多租户Kubernetes集群中,网络隔离是保障租户安全的第一道防线。本章深入剖析三层隔离模型:Kubernetes原生NetworkPolicy、CNI插件底层隔离机制以及租户标识符体系。理解这三层如何协同工作,是构建可迁移、可对账的eBPF网络观测蓝图的基础。

4.1 三层隔离模型总览

租户网络隔离并非单一技术实现,而是从控制面到数据面的分层协作。下表对比了三层模型的核心职责与作用范围:

隔离层级 实现主体 作用范围 核心机制 对账关注点
策略层 Kubernetes NetworkPolicy Namespace / Pod 级别 标签选择器 + 入/出规则 策略是否生效、规则是否漂移
数据面层 CNI 插件 (Calico/Cilium/Flannel) 节点 / 容器接口级别 iptables / eBPF / VXLAN 隧道 底层规则与策略是否一致
标识层 Linux 内核 + kubelet 进程 / 网络命名空间级别 UID/GID + NetNS + cgroup 标识符映射是否完整
对账关键洞察: 跨环境迁移时,策略层(NetworkPolicy YAML)最容易迁移,但数据面层(CNI规则)和标识层(NetNS/UID)往往因内核版本或CNI实现差异而产生偏差。eBPF观测点应部署在数据面与标识层的交汇处。

4.2 Kubernetes NetworkPolicy:策略层的隔离契约

NetworkPolicy 是 Kubernetes 原生的网络访问控制资源,通过标签选择器定义 Pod 之间的通信规则。其核心隔离模型基于“白名单”机制:一旦 Namespace 中存在任何 NetworkPolicy,未显式允许的流量将被拒绝。

4.2.1 策略规则结构

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: tenant-a-isolation
  namespace: tenant-a
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          tenant: tenant-a
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/8
        except:
        - 10.96.0.0/12
    ports:
    - protocol: TCP
      port: 443

4.2.2 策略对账的常见偏差

  • Namespace 标签丢失: 迁移后目标集群未正确打上 tenant: tenant-a 标签,导致 namespaceSelector 失效。
  • Pod 标签不一致: 源集群使用 app: frontend-v1,目标集群使用 app: frontend,策略无法匹配。
  • ipBlock 地址池变化: 跨环境迁移时 Service CIDR 或 Pod CIDR 可能不同,硬编码的 ipBlock 规则需要重新计算。
避坑提示: 不要依赖 NetworkPolicy 的默认拒绝行为来验证隔离效果。eBPF 观测应直接捕获数据面的包过滤决策,而非仅检查策略资源是否存在。

4.3 CNI插件隔离机制:数据面的执行引擎

CNI 插件负责将 NetworkPolicy 翻译为底层网络规则。不同 CNI 的实现路径差异巨大,直接影响 eBPF 观测点的部署策略。

4.3.1 主流CNI隔离机制对比

CNI 插件 隔离实现方式 eBPF 支持 对账复杂度 典型场景
Calico iptables / eBPF (Felix) 原生支持 (XDP/TC) 中 大规模多租户、网络策略复杂
Cilium eBPF (直接替代 kube-proxy) 全链路 eBPF 低(统一数据面) 高性能、安全敏感、eBPF 原生
Flannel VXLAN / host-gw (无策略引擎) 需额外部署策略插件 高(需配合第三方) 简单网络、不要求原生隔离
Antrea OpenFlow / eBPF (可选) 部分支持 中 VMware 生态、混合部署

4.3.2 CNI数据面隔离的eBPF观测点

无论 CNI 实现如何,eBPF 程序都可以在以下内核挂载点捕获隔离决策:

  • TC (Traffic Control) ingress/egress: 捕获容器 veth 对上的原始网络包,适用于所有 CNI。
  • XDP (eXpress Data Path): 在网卡驱动层捕获包,性能最高,但需要 CNI 支持(Calico/Cilium)。
  • kprobe/kretprobe: 挂载关键内核函数(如 nf_hook_slow、ip_local_deliver),追踪 iptables 或 eBPF 策略的判决结果。
对账最佳实践: 在跨环境迁移时,优先在 TC 层部署 eBPF 观测程序。TC 层不依赖特定 CNI 实现,且能同时捕获 iptables 和 eBPF 两种数据面的流量,提供统一的观测基线。

4.4 租户标识符:UID/GID/NetworkNamespace

租户隔离的最终执行单元是 Linux 内核的进程级隔离机制。Kubernetes Pod 本质上是一组共享同一 Network Namespace 的容器集合,而 UID/GID 则用于文件系统和进程权限的隔离。

4.4.1 标识符体系与隔离映射

标识符类型 作用域 Kubernetes 映射 eBPF 观测方式 迁移对账要点
Network Namespace (NetNS) 网络栈隔离 每个 Pod 一个独立 NetNS skc_net / net_ns inode NetNS inode 在迁移后是否重建
User ID (UID) 进程权限隔离 securityContext.runAsUser task_struct->cred->uid UID 范围是否与宿主机冲突
Group ID (GID) 文件/资源组权限 securityContext.runAsGroup task_struct->cred->gid GID 在共享存储场景下的一致性
cgroup v2 资源隔离 + 容器边界 Pod QoS 类 / 资源限制 cgroup_id (bpf_get_current_cgroup_id) cgroup 路径在迁移后是否一致

4.4.2 标识符在eBPF观测中的关键作用

eBPF 程序可以通过 bpf_get_current_cgroup_id() 和 bpf_skc_to_netns() 等辅助函数,在数据包处理路径中获取当前进程的租户标识符。这使得 eBPF 能够将网络流量精确关联到特定租户,而无需依赖 Kubernetes API 的标签查询。

// eBPF 伪代码:在 TC 入口点获取租户标识
struct __sk_buff *skb = ctx;
u64 cgroup_id = bpf_get_current_cgroup_id();
u32 netns_inode = skb->sk->__sk_common.skc_net->ns.inum;

// 通过 cgroup_id 查找租户映射表
struct tenant_info *info = bpf_map_lookup_elem(&tenant_map, &cgroup_id);
if (info) {
    // 记录流量到租户对账仪表盘
    bpf_perf_event_output(skb, &events, BPF_F_CURRENT_CPU,
                          &(struct event){.cgroup_id = cgroup_id,
                                          .netns_inode = netns_inode,
                                          .tenant_id = info->tenant_id});
}
对账设计建议: 在仪表盘对账中,使用 (cgroup_id, netns_inode) 二元组作为租户的唯一标识键。cgroup_id 在 Pod 生命周期内稳定,netns_inode 在跨节点迁移后会变化,但两者组合可以唯一确定一个 Pod 实例,避免因 Pod 重建导致的对账混淆。

4.5 三层隔离模型的协同工作流

下图展示了从用户创建 NetworkPolicy 到内核执行隔离决策的完整数据流,以及 eBPF 观测点的部署位置:

三层隔离模型协同工作流与eBPF观测点 三层隔离模型协同工作流与 eBPF 观测点 策略层:Kubernetes NetworkPolicy 用户定义 → API Server 存储 → Controller Watch → 下发至 CNI 对账点:策略 YAML 与 API Server 中的资源是否一致 数据面层:CNI 插件隔离机制 Calico (iptables/eBPF) | Cilium (eBPF) | Flannel (VXLAN) 对账点:CNI 生成的底层规则与 NetworkPolicy 语义是否等价 🔍 eBPF 观测点 (TC/XDP) 捕获数据面隔离决策 标识层:UID / GID / Network Namespace 每个 Pod 独立 NetNS + 进程 UID/GID + cgroup v2 对账点:标识符映射是否完整、迁移后 NetNS inode 是否重建 🔍 eBPF 观测点 (kprobe) 捕获标识符与流量关联 内核执行:包过滤 / 转发 / 拒绝

4.6 跨环境迁移中的对账策略

基于三层隔离模型,跨环境迁移时的对账应遵循以下步骤:

  1. 策略层对账: 使用 kubectl diff 或 kubectl-neat 对比源/目标集群的 NetworkPolicy 资源,确保标签选择器和规则完全一致。
  2. 数据面对账: 在目标集群部署 eBPF 观测程序,捕获 CNI 实际生成的过滤规则(如 iptables dump 或 eBPF map 内容),与源集群的基线进行对比。
  3. 标识层对账: 通过 eBPF 程序采集每个 Pod 的 (cgroup_id, netns_inode, uid) 三元组,构建租户标识映射表,验证迁移后标识符体系是否完整。
  4. 端到端验证: 构造跨租户的测试流量,通过 eBPF 观测点验证隔离策略是否按预期执行,并将结果写入对账仪表盘。