4. 准入控制类型:Mutating 与 Validating Admission Controller 的区别
在 Kubernetes 准入控制体系中,根据对请求资源的修改与验证时机,准入控制器被划分为两种核心类型:Mutating(变更型)与 Validating(验证型)。理解两者的区别,是设计 Deployment 滚动更新策略时正确编排准入控制链的前提。
核心要点:Mutating 控制器先执行,用于注入、修改或规范化资源;Validating 控制器后执行,用于校验最终状态的合法性。两者共同构成“先变更、后验证”的准入控制流水线。
4.1 执行顺序与生命周期
Kubernetes API Server 在处理一个资源请求(如创建或更新 Deployment)时,会按以下顺序调用准入控制器:
- Mutating Admission Controllers — 按配置顺序依次执行,允许修改请求对象。
- 对象模式验证(Schema Validation) — 内置的 OpenAPI 结构校验。
- Validating Admission Controllers — 按配置顺序依次执行,仅允许通过或拒绝,不可修改对象。
实践提示:在 Deployment 滚动更新场景中,Mutating 控制器常用于注入 Sidecar 容器、设置默认资源限制或添加 Pod 安全标签;Validating 控制器则用于检查更新策略是否违反集群安全策略或资源配额。
4.2 核心区别对比
| 对比维度 | Mutating Admission Controller | Validating Admission Controller |
|---|---|---|
| 主要功能 | 修改(注入、替换、删除)请求资源字段 | 校验资源字段是否满足策略规则 |
| 执行时机 | 先执行(在 Validating 之前) | 后执行(在 Mutating 和 Schema 校验之后) |
| 对请求对象的影响 | 可以修改请求对象的内容 | 只能通过或拒绝,不可修改 |
| 典型应用场景 | 注入 Sidecar、设置默认值、规范化标签 | 检查镜像来源、验证资源配额、校验安全上下文 |
| Webhook 类型 | MutatingWebhookConfiguration |
ValidatingWebhookConfiguration |
| 失败策略 | 可配置 Fail 或 Ignore |
可配置 Fail 或 Ignore |
| 对滚动更新的影响 | 可动态调整 Pod 模板(如注入日志代理) | 可阻止不符合策略的更新(如禁止特权容器) |
4.3 工作流程示意图
下图展示了 Mutating 与 Validating Admission Controller 在 Deployment 滚动更新请求处理中的协作流程:
4.4 在 Deployment 滚动更新中的典型组合
在实际的滚动更新场景中,Mutating 与 Validating 控制器通常配合使用,形成完整的准入控制策略:
- Mutating 控制器示例:
- 自动注入 Istio/Envoy Sidecar 代理
- 为未指定资源限制的容器设置默认 CPU/内存请求
- 添加 Pod 安全标准标签(如
pod-security.kubernetes.io/enforce) - 将镜像标签从
latest转换为具体版本号
- Validating 控制器示例:
- 检查更新后的 Deployment 是否仍满足 Pod 安全策略
- 验证新副本集的副本数是否超过集群资源上限
- 确保滚动更新配置(如
maxSurge、maxUnavailable)在允许范围内 - 拒绝使用来自非信任镜像仓库的容器镜像
注意:如果 Validating 控制器在 Mutating 控制器之前执行(配置顺序错误),它将校验一个尚未被修改的原始对象,可能导致策略误判。务必确保 MutatingWebhookConfiguration 的
reinvocationPolicy 和 ValidatingWebhookConfiguration 的 matchPolicy 配置正确。
4.5 配置示例:MutatingWebhookConfiguration 与 ValidatingWebhookConfiguration
以下是一个典型的 MutatingWebhookConfiguration 定义,用于在 Deployment 滚动更新时注入 Sidecar:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: sidecar-injector.example.com
webhooks:
- name: sidecar-injector.example.com
clientConfig:
service:
name: sidecar-injector
namespace: kube-system
path: /mutate
caBundle: <base64-encoded-ca-cert>
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
admissionReviewVersions: ["v1"]
sideEffects: None
reinvocationPolicy: IfNeeded
failurePolicy: Fail
objectSelector:
matchLabels:
sidecar-inject: "enabled"
对应的 ValidatingWebhookConfiguration 示例,用于校验更新后的 Deployment 是否满足安全策略:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: deployment-validator.example.com
webhooks:
- name: deployment-validator.example.com
clientConfig:
service:
name: deployment-validator
namespace: kube-system
path: /validate
caBundle: <base64-encoded-ca-cert>
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail
matchPolicy: Equivalent
namespaceSelector:
matchLabels:
security-tier: "production"
关键配置说明:
reinvocationPolicy: IfNeeded— 允许在后续 Mutating 控制器修改后再次调用当前 Webhook,确保最终状态正确。matchPolicy: Equivalent— 确保 Validating 控制器能匹配到资源的所有等效 API 版本。failurePolicy: Fail— 在滚动更新场景中建议使用 Fail,避免因 Webhook 不可用而绕过安全校验。
4.6 选择建议
在设计 Deployment 滚动更新的准入控制策略时,遵循以下原则:
- 优先使用 Mutating 控制器处理所有需要自动修正或注入的逻辑,减少运维手动配置。
- 使用 Validating 控制器实施不可协商的安全边界和资源约束。
- 避免在 Validating 控制器中执行修改操作,这违反了 Kubernetes 准入控制的设计原则,可能导致不可预测的行为。
- 测试准入控制链时,先单独测试 Mutating 控制器的输出,再测试 Validating 控制器的校验逻辑。