4. 准入控制基础:Kubernetes Admission Controller 原理、Mutating 与 Validating Webhook 的区别、动态准入控制流程
4.1 什么是 Kubernetes 准入控制?
Kubernetes API Server 在处理任何资源请求(创建、更新、删除)时,会在请求被持久化到 etcd 之前,依次通过一系列称为 Admission Controller(准入控制器)的插件。这些插件可以拦截 API 请求,并根据预定义的策略对请求进行修改或验证。
准入控制是 Kubernetes 实现安全策略、资源配额、默认值注入等功能的最后一道防线。它位于认证(Authentication)和授权(Authorization)之后,确保只有符合集群规范的请求才能被持久化。
关键位置: 认证 → 授权 → 准入控制 → etcd
4.2 Admission Controller 的工作原理
Kubernetes 内置了多种 Admission Controller(如 NamespaceLifecycle、LimitRanger、PodSecurity 等),它们以插件形式注册在 API Server 中。当请求到达时,API Server 会按顺序执行以下步骤:
- 解析请求:将 HTTP 请求反序列化为内部对象。
- 执行 Mutating 准入控制器:允许修改请求对象(如注入 Sidecar、设置默认值)。
- 执行对象模式验证:对修改后的对象进行基本的 Schema 校验。
- 执行 Validating 准入控制器:验证对象是否符合业务策略(如禁止特权容器)。
- 持久化到 etcd:只有通过所有准入控制器的请求才会被写入存储。
4.3 Mutating 与 Validating Webhook 的区别
Kubernetes 允许通过 Dynamic Admission Control(动态准入控制) 注册外部 Webhook 服务。这些 Webhook 分为两类:
| 特性 | MutatingAdmissionWebhook | ValidatingAdmissionWebhook |
|---|---|---|
| 核心功能 | 修改(Mutate)请求对象 | 验证(Validate)请求对象 |
| 执行顺序 | 先执行 | 后执行 |
| 典型场景 | 注入 Sidecar、设置默认标签、修改 Pod 安全上下文 | 检查镜像来源、禁止特权容器、验证资源配额 |
| 返回结果 | allowed: true + 修改后的 JSON Patch |
allowed: true/false + 拒绝原因 |
| 幂等性要求 | 必须幂等(可能被多次调用) | 无特殊要求 |
| 失败策略 | Fail 或 Ignore |
Fail 或 Ignore |
最佳实践: 对于同一个资源对象,建议先注册 Mutating Webhook 完成默认值注入和对象修改,再注册 Validating Webhook 进行策略校验。这样可以避免因缺少默认值而导致的误判。
4.4 动态准入控制流程详解
动态准入控制通过 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 两种资源对象来配置。当 API Server 收到请求时,会执行以下详细流程:
- 匹配规则:API Server 根据 Webhook 配置中的
rules字段(API 组、资源、操作)判断当前请求是否命中该 Webhook。 - 对象序列化:将请求对象序列化为 JSON,并通过 HTTPS 发送到 Webhook 服务。
- Webhook 处理:外部服务解析 AdmissionReview 请求,执行业务逻辑。
- 返回响应:Webhook 返回 AdmissionReview 响应,包含
allowed字段和可选的patch(仅 Mutating)。 - 合并结果:API Server 收集所有 Webhook 的响应,按顺序应用 Patch,并最终决定是否放行。
4.5 Webhook 配置示例
以下是一个典型的 ValidatingWebhookConfiguration 示例,用于验证 Pod 是否使用了允许的镜像仓库:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "pod-image-validator.example.com"
webhooks:
- name: "pod-image-validator.example.com"
clientConfig:
service:
namespace: "webhook-system"
name: "pod-image-validator"
path: "/validate"
caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
scope: "Namespaced"
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
timeoutSeconds: 5
failurePolicy: Fail
安全注意事项:
- Webhook 服务必须使用 HTTPS,且证书由受信任的 CA 签发。
failurePolicy设置为Fail时,如果 Webhook 服务不可用,整个集群的写入操作将被阻塞。- 建议为 Webhook 设置合理的
timeoutSeconds(通常 5-10 秒),避免长时间阻塞 API Server。 - 使用
objectSelector和namespaceSelector缩小 Webhook 的生效范围,减少不必要的调用。
4.6 与 Cilium 的协同点
在租户隔离场景中,Admission Controller 与 Cilium 的协同主要体现在以下方面:
| 协同层面 | Admission Controller 职责 | Cilium 职责 |
|---|---|---|
| 网络策略注入 | 通过 Mutating Webhook 为 Pod 自动注入网络策略标签 | 根据标签执行 CiliumNetworkPolicy 规则 |
| 安全基线校验 | 通过 Validating Webhook 禁止 Pod 使用 hostNetwork 或特权模式 | 通过 L7 策略限制应用层访问 |
| 租户标识绑定 | 在 Pod 创建时注入租户 ID 标签 | 基于标签实现租户间的网络隔离 |
| 策略冲突检测 | 在 Validating Webhook 中预检 CiliumNetworkPolicy 语法 | 执行最终的策略生效与冲突解决 |
架构建议: 将 Cilium 相关的策略校验逻辑封装为一个独立的 Validating Webhook 服务,部署在集群中。该 Webhook 可以预检 CiliumNetworkPolicy 的 CIDR 格式、标签选择器语法等,避免无效策略被提交到集群。