3. 准入机制基础:准入控制器概念、Kubernetes 准入 Webhook、准入策略的作用域
准入机制是 Kubernetes 集群安全与策略执行的“守门员”。在灰度发布场景中,所有对集群资源的变更(如创建、更新、删除)都必须经过准入控制器的校验,才能决定是否允许该操作进入持久化存储(etcd)。本章将深入剖析准入控制器的核心概念、Webhook 实现机制以及策略作用域的划分,为后续的灰度发布准入移植适配奠定理论基础。
3.1 准入控制器概念与生命周期
准入控制器(Admission Controller)是一段拦截并处理 Kubernetes API Server 请求的代码插件。它在请求经过认证(Authentication)和鉴权(Authorization)之后、对象被持久化到 etcd 之前执行。根据其行为模式,准入控制器分为两类:
| 类型 | 执行时机 | 典型行为 | 示例 |
|---|---|---|---|
| Mutating(变更) | 先于 Validating 执行 | 修改请求对象(注入 Sidecar、设置默认值、修正标签) | MutatingAdmissionWebhook、PodNodeSelector |
| Validating(验证) | 后于 Mutating 执行 | 校验请求对象是否满足策略(资源配额、安全策略、合规检查) | ValidatingAdmissionWebhook、ResourceQuota |
整个请求生命周期可概括为:
- 认证:验证请求者身份(TLS 证书、、用户名/密码)。
- 鉴权:判断请求者是否有权限执行该操作(RBAC、ABAC)。
- Mutating 准入:执行所有 Mutating 控制器(包括 Webhook),可修改请求对象。
- Validating 准入:执行所有 Validating 控制器(包括 Webhook),校验最终对象。
- 持久化:通过准入的对象写入 etcd。
3.2 Kubernetes 准入 Webhook
Kubernetes 提供了两种内置的 Webhook 准入控制器,允许集群管理员通过外部 HTTP 回调(Webhook)扩展准入逻辑:
- MutatingAdmissionWebhook:用于实现自定义的变更逻辑,例如在灰度发布中自动为 Pod 注入灰度版本标签、调整资源请求/限制。
- ValidatingAdmissionWebhook:用于实现自定义的校验逻辑,例如验证灰度发布策略中的流量比例是否合法、检查 Deployment 的更新策略是否符合组织规范。
3.2.1 Webhook 配置核心字段
Webhook 通过 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration 资源进行配置。以下是一个典型的 Validating Webhook 配置示例:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "grayscale-validator.example.com"
webhooks:
- name: "grayscale-validator.example.com"
clientConfig:
service:
namespace: "grayscale-system"
name: "grayscale-webhook-service"
path: "/validate"
caBundle: "LS0tLS1CRUdJTiBDRV...==" # 签发 Webhook 服务端证书的 CA
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
scope: "Namespaced"
admissionReviewVersions: ["v1"]
sideEffects: None
timeoutSeconds: 5
failurePolicy: Fail
matchPolicy: Equivalent
namespaceSelector:
matchLabels:
grayscale-enabled: "true"
objectSelector:
matchLabels:
app.kubernetes.io/part-of: "grayscale-release"
failurePolicy: Fail:当 Webhook 不可用时,拒绝所有请求(安全优先);Ignore则允许请求通过(可用性优先)。namespaceSelector/objectSelector:用于缩小 Webhook 的拦截范围,避免不必要的性能开销。sideEffects: None:声明 Webhook 调用无副作用,允许 kube-apiserver 在 dry-run 模式下调用。
3.2.2 AdmissionReview 请求/响应结构
Webhook 服务端接收 AdmissionReview 请求,并返回 AdmissionReview 响应。核心字段如下:
| 字段 | 位置 | 说明 |
|---|---|---|
request.uid |
请求 | 唯一标识本次准入请求,用于日志追踪 |
request.object |
请求 | 被操作的 Kubernetes 对象(JSON 格式) |
request.oldObject |
请求 | 更新/删除操作前的旧对象(仅 UPDATE/DELETE 时存在) |
request.operation |
请求 | 操作类型:CREATE / UPDATE / DELETE / CONNECT |
response.allowed |
响应 | 布尔值,true 表示允许请求,false 表示拒绝 |
response.status.message |
响应 | 拒绝时的错误描述,会返回给 API 调用方 |
response.patch |
响应(仅 Mutating) | JSON Patch 格式的变更内容,用于修改请求对象 |
3.3 准入策略的作用域
准入策略的作用域决定了 Webhook 在集群中的生效范围。合理配置作用域可以精确控制灰度发布的策略粒度,避免全局影响。作用域分为三个层级:
3.3.1 集群级作用域(Cluster-Scoped)
通过 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration 的 rules 字段中的 scope: "*" 或 scope: "Cluster" 来匹配集群范围资源(如 Namespace、ClusterRole、PersistentVolume)。适用于全局灰度策略,例如:
- 禁止在非灰度 Namespace 中创建带有特定灰度标签的 Deployment。
- 强制所有灰度发布相关的 CRD 必须注册在指定的 API 组中。
3.3.2 命名空间级作用域(Namespaced-Scoped)
通过 namespaceSelector 和 objectSelector 实现细粒度控制。这是灰度发布中最常用的作用域:
| 选择器类型 | 匹配对象 | 灰度发布典型用法 |
|---|---|---|
namespaceSelector |
资源所在的 Namespace | 只拦截带有 grayscale-enabled: "true" 标签的 Namespace |
objectSelector |
资源自身的标签 | 只拦截带有 app.kubernetes.io/part-of: "grayscale-release" 标签的 Deployment |
matchLabels / matchExpressions |
标签选择器表达式 | 支持复杂逻辑:grayscale-version in (v2, v3) 且 tier notin (canary, stable) |
- 如果
namespaceSelector和objectSelector都未设置,Webhook 将拦截集群中所有符合条件的资源操作,可能引发严重的性能问题。 - 在灰度发布初期,建议先使用
namespaceSelector限定到测试 Namespace,验证 Webhook 逻辑无误后再逐步扩大范围。
3.3.3 操作类型作用域(Operation-Scoped)
通过 rules[].operations 字段指定 Webhook 拦截的操作类型。灰度发布场景下的典型配置:
- CREATE:拦截新 Deployment 的创建,注入灰度 Sidecar 或校验初始灰度比例。
- UPDATE:拦截灰度版本的滚动更新,校验新版本的副本数、流量比例是否在安全阈值内。
- DELETE:防止误删除正在运行灰度流量的关键资源(可选)。
# 示例:只拦截灰度 Deployment 的 CREATE 和 UPDATE 操作
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
scope: "Namespaced"
3.4 准入策略在灰度发布中的组合应用
在标准模板驱动的灰度发布框架中,准入策略通常采用“分层组合”的方式:
- 全局层:集群级 Validating Webhook,确保所有灰度发布资源符合基础安全规范(如禁止特权容器、强制资源限制)。
- 命名空间层:通过
namespaceSelector区分生产 Namespace 和测试 Namespace,不同 Namespace 应用不同的灰度策略模板。 - 资源层:通过
objectSelector精确匹配灰度发布模板生成的资源,避免影响普通工作负载。 - 操作层:仅拦截 CREATE 和 UPDATE 操作,DELETE 操作放行以支持快速回滚。
failurePolicy 设置为 Fail,并结合 timeoutSeconds: 5 和 sideEffects: None,在保证安全性的同时避免 Webhook 成为集群性能瓶颈。灰度发布初期建议开启 dry-run 模式(通过 --dry-run=server 参数)验证准入逻辑的正确性。