4. 准入策略评审机制:Kubernetes Admission Webhook 原理、Mutating 与 Validating Webhook 区别
在云原生配置管理准入策略评审中,Kubernetes Admission Webhook 是实现动态、可编程准入控制的核心机制。它允许集群管理员在资源被持久化存储之前,通过外部 Webhook 服务对请求进行拦截、修改或验证。本章将深入剖析 Admission Webhook 的工作原理,并详细对比 Mutating 与 Validating 两种 Webhook 的区别。
4.1 Admission Webhook 工作原理
Kubernetes API Server 在处理资源请求(如创建、更新、删除)时,会经过一系列内置的准入控制器(Admission Controller)。Admission Webhook 是一种特殊的准入控制器,它将决策逻辑委托给集群外部的 HTTP 回调服务(Webhook 服务)。
其核心工作流程如下:
- 请求到达 API Server:用户或客户端通过 kubectl、API 调用等方式向 API Server 发送资源请求。
- 认证与授权:API Server 首先对请求进行身份认证(Authentication)和授权检查(Authorization)。
- Mutating Admission 阶段:请求进入 Mutating Admission 链。API Server 根据配置的 MutatingWebhookConfiguration 资源,并行或串行调用注册的 Webhook 服务。Webhook 可以修改请求中的资源对象(如注入 Sidecar、设置默认值)。
- 对象 Schema 验证:经过 Mutating 阶段后,API Server 对修改后的对象进行结构化和 Schema 验证。
- Validating Admission 阶段:请求进入 Validating Admission 链。API Server 根据 ValidatingWebhookConfiguration 资源,调用注册的 Webhook 服务。Webhook 对请求进行验证,决定是否允许该请求。
- 持久化存储:如果所有准入控制器都通过,API Server 将资源对象写入 etcd 数据库。
4.2 Mutating 与 Validating Webhook 区别
虽然两者都是通过外部 HTTP 回调实现准入控制,但它们在职责、执行时机、返回结果和典型应用场景上存在显著差异。下表从多个维度进行了详细对比:
| 对比维度 | Mutating Webhook | Validating Webhook |
|---|---|---|
| 核心职责 | 修改(Mutate)请求中的资源对象 | 验证(Validate)请求中的资源对象 |
| 执行顺序 | 在 Validating Webhook 之前执行 | 在 Mutating Webhook 之后执行 |
| 返回结果 | 返回 JSON Patch 操作(如添加、替换、删除字段) | 返回允许(Allowed: true)或拒绝(Allowed: false) |
| 对对象的影响 | 可以修改请求对象的任何字段 | 不能修改对象,只能决定是否允许 |
| 幂等性要求 | 必须幂等,多次调用应产生相同结果 | 通常幂等,但非强制 |
| 典型应用场景 | Sidecar 注入、资源配额默认值、标签/注解自动添加 | 安全策略检查(如禁止特权容器)、资源命名规范验证、镜像来源校验 |
| 配置资源类型 | MutatingWebhookConfiguration | ValidatingWebhookConfiguration |
| 失败策略 | 可配置为 Fail 或 Ignore | 可配置为 Fail 或 Ignore |
4.3 Webhook 配置与通信细节
无论是 Mutating 还是 Validating Webhook,其配置结构是相似的。一个典型的 Webhook 配置包含以下关键字段:
- clientConfig:定义如何与 Webhook 服务通信,包括 URL 或 Service 引用、CA 证书(用于 TLS 验证)。
- rules:定义哪些资源操作(如 CREATE、UPDATE)会触发该 Webhook。支持按 API 组、API 版本、资源类型、操作类型、作用域(Cluster/Namespaced)进行匹配。
- failurePolicy:当 Webhook 服务不可达或返回错误时的处理策略,可选
Fail(拒绝请求)或Ignore(跳过该 Webhook)。 - matchPolicy:规则匹配策略,可选
Exact(精确匹配)或Equivalent(等效匹配,如 v1 和 v1beta1 视为等效)。 - sideEffects:声明 Webhook 是否有副作用,可选
None、NoneOnDryRun或Some。推荐设置为None以支持干运行(Dry Run)。 - timeoutSeconds:Webhook 调用的超时时间,默认 10 秒,最大 30 秒。
以下是一个 MutatingWebhookConfiguration 的配置示例:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: "example-mutating-webhook"
webhooks:
- name: "mutate.example.com"
clientConfig:
service:
namespace: "webhook-system"
name: "webhook-service"
path: "/mutate"
caBundle: "LS0tLS1CRUdJTiBDRV...==" # Base64 编码的 CA 证书
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
scope: "Namespaced"
failurePolicy: Fail
matchPolicy: Equivalent
sideEffects: None
timeoutSeconds: 10
admissionReviewVersions: ["v1", "v1beta1"]
reinvocationPolicy: IfNeeded # 仅 Mutating Webhook 支持
4.4 请求与响应格式:AdmissionReview
API Server 与 Webhook 服务之间通过 AdmissionReview 对象进行通信。API Server 发送 AdmissionReview 请求,Webhook 服务返回 AdmissionReview 响应。
请求(Request) 中包含以下关键字段:
- uid:请求的唯一标识符,用于关联请求和响应。
- object:被操作的资源对象(经过序列化的 JSON 格式)。
- oldObject:如果是 UPDATE 操作,包含更新前的对象。
- operation:操作类型,如 CREATE、UPDATE、DELETE。
- userInfo:发起请求的用户信息,用于基于身份的准入控制。
- dryRun:布尔值,指示是否为干运行请求。
响应(Response) 中包含以下关键字段:
- uid:必须与请求中的 uid 一致。
- allowed:布尔值,表示是否允许该请求。
- status:当 allowed 为 false 时,提供拒绝原因和错误信息。
- patchType:仅 Mutating Webhook 使用,指定补丁类型,目前仅支持
JSONPatch。 - patch:仅 Mutating Webhook 使用,Base64 编码的 JSON Patch 操作数组。
4.5 准入策略评审中的权限边界与日志拉取
在 SBOM 支撑的云原生配置管理场景中,Admission Webhook 是实施准入策略评审的关键执行点。理解其权限边界和日志拉取机制对于构建安全的配置管理流程至关重要。
- 权限边界:Webhook 服务本身需要访问 Kubernetes API 吗?通常不需要。Webhook 服务仅接收 API Server 发起的 HTTP 请求,并根据请求内容做出决策。它不需要直接调用 API Server。但是,Webhook 配置(MutatingWebhookConfiguration / ValidatingWebhookConfiguration)的创建和管理需要集群级别的 RBAC 权限。
- 日志拉取:Webhook 服务的日志是审计和调试准入策略的重要依据。建议将 Webhook 服务的日志结构化输出(如 JSON 格式),并包含以下关键信息:请求 UID、操作类型、资源类型、用户信息、决策结果(allowed / denied)、拒绝原因、处理耗时。这些日志可以通过 Fluentd、Logstash 等工具采集到集中式日志平台。