4. 准入控制机制概述:Kubernetes准入控制器与eBPF的结合点

在租户隔离蓝图中,资源模型定义了“应该隔离什么”,而准入控制机制决定了“如何强制隔离”。Kubernetes 原生提供的 准入控制器(Admission Controller) 在 API 请求持久化之前进行拦截与校验,但其校验范围局限于控制面语义。eBPF 则能在数据面提供实时、不可绕过的执行强制。两者的结合,构成了从声明式策略到运行时强制的完整闭环。

4.1 Kubernetes准入控制器的工作模型

Kubernetes 准入控制器位于 API Server 的请求处理链中,在对象被认证、授权之后,但在持久化到 etcd 之前执行。其工作模型分为两类:

  • Mutating(变更):通过 MutatingAdmissionWebhook 修改请求对象(如注入 Sidecar、设置默认标签)。
  • Validating(验证):通过 ValidatingAdmissionWebhook 校验请求对象是否满足策略(如检查 Pod 是否使用了允许的 SecurityContext)。

两种 Webhook 均以外部 HTTP 回调方式运行,由集群管理员注册。下图展示了准入控制器在 API 请求链中的位置:

Kubernetes 准入控制器请求处理链 kubectl / Client API Server 认证 / 授权 准入控制器 etcd MutatingWebhook 先执行 ValidatingWebhook 后执行
关键认知: 准入控制器只能拦截通过 API Server 的请求。如果攻击者绕过 API Server 直接操作节点上的容器运行时(如 containerd),准入策略将完全失效。这正是 eBPF 需要介入的根本原因。

4.2 原生准入控制的局限性

在租户隔离场景下,Kubernetes 原生准入控制器存在三个无法回避的短板:

局限性 具体表现 对租户隔离的影响
控制面局限 只能校验 YAML 语义,无法感知运行时行为 恶意 Pod 可在启动后修改网络命名空间或加载内核模块
绕过风险 节点级操作(如 systemd 启动容器)不经过 API Server 特权用户可直接在节点上创建容器,绕过所有准入策略
性能开销 每个 Webhook 调用增加 API 请求延迟 5-50ms 大规模集群下,频繁的 Pod 创建会导致 API Server 过载

4.3 eBPF 在数据面提供的补充能力

eBPF 程序挂载在 Linux 内核的钩子点(如 sys_enter、sk_alloc、cgroup_skb),能够以极低开销观测和干预系统调用与网络事件。与准入控制器相比,eBPF 提供了三个不可替代的能力:

  • 运行时强制:即使 Pod 已通过准入检查,eBPF 仍可在每次系统调用或网络包处理时执行策略。
  • 不可绕过性:eBPF 程序由内核验证并执行,用户态进程无法卸载或篡改(除非有 CAP_BPF 权限)。
  • 细粒度上下文:eBPF 可以获取 cgroup ID、PID、网络命名空间等内核级标识,实现精确的租户关联。

4.4 结合点:从声明式策略到内核级执行

将 Kubernetes 准入控制器与 eBPF 结合,本质上是构建一条从控制面声明到数据面执行的策略传递链路。其核心架构如下:

准入控制器与 eBPF 协同架构 控制面(Kubernetes API Server) ValidatingWebhook 策略翻译器 eBPF Map 写入器 数据面(Linux 内核 + eBPF) eBPF Map (策略规则存储) eBPF 程序 (网络 / 系统调用钩子) 内核事件 (允许/拒绝)

上图展示了完整的协同流程:

  1. ValidatingWebhook 拦截 Pod 创建请求,校验租户标签、网络策略声明等元数据。
  2. 策略翻译器 将准入策略(如“租户 A 的 Pod 不能访问租户 B 的 Service”)转换为 eBPF Map 中的键值规则。
  3. eBPF Map 写入器 通过 bpf() 系统调用将规则下发到内核中的 eBPF Map。
  4. eBPF 程序 在每次网络包处理或系统调用时查询 Map,实时执行允许/拒绝决策。
设计要点: 策略翻译器是关键组件。它需要将 Kubernetes 的 NetworkPolicy、PodSecurityPolicy 等高层抽象,映射为 eBPF 可理解的五元组规则、cgroup 白名单或系统调用过滤条件。这一层决定了协同方案的通用性和性能。

4.5 典型结合场景对比

场景 准入控制器角色 eBPF 角色 协同效果
Pod 网络隔离 校验 Pod 是否绑定了正确的租户网络策略 在 TC 或 XDP 钩子处执行包过滤 防止 Pod 启动后修改网络策略
容器逃逸防护 拒绝特权容器或危险 mount 请求 监控 clone()、mount() 系统调用 即使准入被绕过,eBPF 仍可阻断逃逸
租户资源配额 校验 Pod 资源请求是否超出租户配额 监控 cgroup 统计,限制实际内存/CPU 使用 防止超卖和资源抢占
DNS 策略强制 校验 Pod 是否允许访问外部域名 在 connect() 系统调用处拦截 DNS 查询 实现比 CoreDNS 更底层的 DNS 隔离

4.6 实现路径与挑战

在实际落地中,准入控制器与 eBPF 的结合需要解决以下工程问题:

  • 策略同步一致性:当准入控制器批准一个 Pod 后,eBPF Map 中的规则必须原子性更新。如果更新失败,需要回滚 Pod 创建或进入降级模式。
  • Map 容量管理:eBPF Map 有大小限制(通常 1M 条目以内),大规模集群下需要设计规则压缩和淘汰策略。
  • 多租户身份传递:eBPF 程序需要从内核上下文(如 cgroup ID、netns)反推出 Kubernetes 租户身份,这要求用户态组件维护一个映射表。
  • 安全隔离:eBPF 程序本身需要防止被恶意租户滥用(如通过 BPF 辅助函数读取其他租户的 Map 数据)。
避坑提示: 不要试图用 eBPF 完全替代准入控制器。准入控制器在控制面提供语义校验和审计日志,eBPF 在数据面提供运行时强制。两者是互补关系,而非替代关系。缺少任何一环,租户隔离都会出现盲区。

4.7 小结