准入控制器基础:Kubernetes 准入控制机制
Kubernetes 准入控制(Admission Control)是 API Server 请求处理链中的关键安全闸门。所有对集群资源的创建、更新、删除操作,在通过认证(Authentication)和授权(Authorization)之后,都会进入准入控制阶段。准入控制器可以拦截请求、修改请求对象(Mutating),或验证请求对象是否符合集群策略(Validating),从而在对象被持久化到 etcd 之前实施安全控制。
准入控制请求处理流程
下图展示了 Kubernetes API 请求从客户端到 etcd 存储的完整处理链路,其中准入控制阶段位于认证与授权之后、对象持久化之前。
MutatingAdmissionWebhook 与 ValidatingAdmissionWebhook 的区别
动态准入控制(Dynamic Admission Control)通过 Webhook 机制将决策逻辑外置到独立的 HTTP 服务中。Kubernetes 支持两种类型的准入 Webhook:MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。两者在功能、执行顺序和典型用途上存在显著差异。
| 对比维度 | MutatingAdmissionWebhook | ValidatingAdmissionWebhook |
|---|---|---|
| 核心功能 | 修改(Patch)请求对象,注入默认值或 Sidecar | 验证(Validate)请求对象,拒绝不符合策略的请求 |
| 执行顺序 | 先执行(在 API Server 内部序列中排在 Validating 之前) | 后执行(接收 Mutating 修改后的最终对象) |
| 典型用途 | 注入镜像签名校验注解、设置默认安全上下文、注入 Sidecar 代理 | 校验镜像来源是否可信、检查容器是否以 root 运行、验证资源配额 |
| 响应要求 | 必须返回 JSON Patch 或 JSON Merge Patch | 返回 allowed: true/false 及拒绝原因 |
| 幂等性要求 | 必须幂等,多次修改同一对象应产生相同结果 | 无修改操作,天然幂等 |
| 失败策略 | 可配置 Fail 或 Ignore(影响集群可用性) | 可配置 Fail 或 Ignore(影响安全策略执行) |
动态准入控制的工作原理
动态准入控制的核心是 AdmissionReview 请求/响应模型。当 API Server 收到资源请求时,会构造一个 AdmissionReview 对象,通过 HTTPS 发送给注册的 Webhook 服务。Webhook 服务处理完毕后,返回包含修改或验证结果的 AdmissionReview 响应。
Webhook 配置示例
以下是一个 ValidatingAdmissionWebhook 配置示例,用于校验 Pod 镜像是否来自可信仓库:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "image-validator.example.com"
webhooks:
- name: "image-validator.example.com"
clientConfig:
service:
namespace: "admission-system"
name: "image-validator-service"
path: "/validate"
caBundle: "LS0tLS1CRUdJTiBDRV...=="
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
scope: "Namespaced"
admissionReviewVersions: ["v1"]
sideEffects: None
timeoutSeconds: 10
failurePolicy: Fail
matchPolicy: Equivalent
objectSelector:
matchLabels:
security-tier: "critical"
failurePolicy: Fail— 当 Webhook 不可用时,拒绝所有请求,确保安全策略不因服务故障而失效sideEffects: None— 声明 Webhook 无副作用,允许 API Server 在 dry-run 模式下调用objectSelector— 通过标签选择器缩小 Webhook 作用范围,仅对关键安全级别的 Pod 生效
Webhook 服务端处理逻辑
Webhook 服务端需要解析 AdmissionReview 请求,提取待校验的对象,执行策略检查,并返回 AdmissionReview 响应。以下是一个简化的 Go 语言处理函数示例:
func handleValidate(w http.ResponseWriter, r *http.Request) {
var review admissionv1.AdmissionReview
if err := json.NewDecoder(r.Body).Decode(&review); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
req := review.Request
var pod corev1.Pod
if err := json.Unmarshal(req.Object.Raw, &pod); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
allowed := true
message := ""
for _, container := range pod.Spec.Containers {
if !strings.HasPrefix(container.Image, "trusted-registry.io/") {
allowed = false
message = "镜像 " + container.Image + " 来自非可信仓库"
break
}
}
review.Response = &admissionv1.AdmissionResponse{
UID: req.UID,
Allowed: allowed,
Result: &metav1.Status{Message: message},
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(review)
}
Mutating 与 Validating 的协作模式
在镜像安全场景中,Mutating 和 Validating Webhook 通常协同工作:
- Mutating 阶段:自动注入镜像签名注解、添加镜像拉取密钥、设置镜像拉取策略
- Validating 阶段:校验镜像签名是否有效、镜像来源是否在白名单中、镜像是否通过漏洞扫描
这种协作模式确保在对象被持久化之前,既完成了必要的修改,又执行了严格的安全验证。
动态准入控制的安全考量
| 安全风险 | 影响 | 缓解措施 |
|---|---|---|
| Webhook 服务不可用 | 集群创建/更新操作被阻塞(failurePolicy=Fail) | 部署多副本 Webhook 服务,配置健康检查与自动恢复 |
| Webhook 证书过期 | API Server 无法建立 TLS 连接,请求失败 | 使用 cert-manager 自动管理证书生命周期 |
| Webhook 响应超时 | 请求处理延迟增加,影响集群响应速度 | 优化 Webhook 处理逻辑,设置合理的 timeoutSeconds |
| Webhook 绕过风险 | 攻击者可能通过直接操作 etcd 绕过准入控制 | 启用 RBAC 限制 etcd 访问,审计所有 API 操作 |