3. Kubernetes 准入控制机制:Admission Webhook(Mutating & Validating)、内置准入控制器
Kubernetes 准入控制(Admission Control)是 API Server 请求处理链中的关键安全与策略执行环节。所有对集群资源的创建、更新、删除操作,在通过认证(Authentication)和授权(Authorization)之后、对象持久化到 etcd 之前,都必须经过准入控制器的拦截与校验。理解这一机制,是后续将 Kustomize 资源合并结果与策略引擎(OPA/Gatekeeper、Kyverno)对接的前提。
3.1 准入控制请求处理流程
一个完整的 API 请求在 Kubernetes 控制平面中的处理顺序如下:
- 认证(Authentication):验证请求发起者的身份(客户端证书、、Basic Auth 等)。
- 授权(Authorization):基于 RBAC、ABAC 或 Node 授权判断请求者是否有权执行操作。
- 准入控制(Admission Control):对请求对象进行拦截、修改或校验,决定是否允许请求继续。
- 对象持久化(etcd):通过准入控制后,对象被写入 etcd 存储。
3.2 内置准入控制器
Kubernetes 内置了数十个准入控制器,它们以插件形式编译在 kube-apiserver 中,通过 --enable-admission-plugins 和 --disable-admission-plugins 参数控制启停。以下是与资源合并和策略执行最相关的内置控制器:
| 控制器名称 | 类型 | 核心功能 | 与 Kustomize 策略适配的关联 |
|---|---|---|---|
| NamespaceLifecycle | Validating | 确保命名空间存在且未被删除 | Kustomize 合并后的资源必须引用存在的命名空间 |
| MutatingAdmissionWebhook | Mutating | 调用外部 Webhook 修改请求对象 | Kyverno 等策略引擎通过此入口注入默认值 |
| ValidatingAdmissionWebhook | Validating | 调用外部 Webhook 校验请求对象 | OPA/Gatekeeper 通过此入口执行策略校验 |
| ResourceQuota | Validating | 校验资源配额是否超限 | Kustomize 合并后的资源总量需满足配额约束 |
| PodSecurity | Mutating + Validating | 实施 Pod 安全标准(PSS) | Kustomize 生成的 Pod 模板需符合安全基线 |
PodSecurity、NamespaceLifecycle)建立基础安全防线。内置控制器性能开销低,且不依赖外部服务可用性。
3.3 Admission Webhook:Mutating 与 Validating
Admission Webhook 是 Kubernetes 1.9+ 引入的动态准入扩展机制,允许集群管理员注册外部 HTTP 回调服务来处理准入请求。根据处理阶段不同,分为两类:
- MutatingAdmissionWebhook:在对象持久化之前,允许修改(Mutate)请求对象。常用于注入 sidecar、设置默认值、添加标签/注解等。多个 Mutating Webhook 按配置顺序链式执行。
- ValidatingAdmissionWebhook:在对象持久化之前,仅允许校验(Validate)请求对象,不可修改。常用于执行合规策略、安全检查、资源约束校验等。
两类 Webhook 的执行顺序为:所有 Mutating Webhook 先执行 → 对象被修改后 → 所有 Validating Webhook 再执行。这一顺序对 Kustomize 资源合并后的策略适配至关重要——策略引擎(如 Kyverno)通常同时注册 Mutating 和 Validating 两种 Webhook,先通过 Mutating 注入默认值,再通过 Validating 校验最终状态。
3.4 Webhook 配置核心要素
注册一个 Admission Webhook 需要创建 MutatingWebhookConfiguration 或 ValidatingWebhookConfiguration 资源。以下是一个 Validating Webhook 的配置示例:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "pod-policy.example.com"
webhooks:
- name: "pod-policy.example.com"
clientConfig:
service:
namespace: "gatekeeper-system"
name: "gatekeeper-webhook-service"
path: "/v1/admit"
caBundle: "LS0tLS1CRUdJTiBDRV...=="
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1"]
sideEffects: None
timeoutSeconds: 5
failurePolicy: Fail
matchPolicy: Equivalent
namespaceSelector:
matchLabels:
admission.gatekeeper.sh/ignore: "no"
| 配置字段 | 说明 | 对 Kustomize 策略适配的影响 |
|---|---|---|
| rules | 定义 Webhook 拦截的资源类型、操作、API 组 | 需确保 Kustomize 合并后的资源类型在规则范围内 |
| failurePolicy | Webhook 不可用时的行为:Fail(拒绝请求)或 Ignore(允许请求) | 生产环境建议 Fail,避免策略绕过 |
| namespaceSelector | 按命名空间标签过滤请求 | 可用于排除系统命名空间,减少 Kustomize 合并后的误拦截 |
| timeoutSeconds | Webhook 调用超时时间(默认 10s,最大 30s) | Kustomize 合并复杂资源时需考虑 Webhook 处理延迟 |
| sideEffects | Webhook 是否产生副作用(None / NoneOnDryRun) | 必须设置为 None,否则 dry-run 模式下会跳过 |
failurePolicy 设置为 Fail 时,如果 Webhook 服务不可用(如部署期间重启),整个集群的写入操作将被阻塞。建议在 Webhook 部署初期使用 Ignore,待服务稳定后再切换为 Fail。Kustomize 的 patches 和 replacements 操作可能生成大量临时资源,需确保 Webhook 的 timeoutSeconds 足够处理这些请求。
3.5 内置控制器与 Webhook 的协同关系
在实际集群中,内置控制器和动态 Webhook 共同构成多层准入防线。以下表格对比了两类控制器的典型分工:
| 维度 | 内置准入控制器 | Admission Webhook |
|---|---|---|
| 部署方式 | kube-apiserver 启动参数 | 独立的 Webhook 服务(Pod + Service) |
| 扩展性 | 固定功能,不可自定义 | 完全可编程,支持任意策略逻辑 |
| 性能开销 | 低(进程内调用) | 中高(网络调用 + 序列化/反序列化) |
| 典型场景 | 资源配额、命名空间管理、Pod 安全标准 | 合规策略、安全扫描、自定义默认值注入 |
| 与 Kustomize 的交互 | 对 Kustomize 合并结果透明 | 需关注 Webhook 对合并后资源的校验逻辑 |