2. Kubernetes 准入控制基础

Kubernetes 准入控制(Admission Control)是 API Server 请求处理链中位于认证(Authentication)与鉴权(Authorization)之后、对象持久化(etcd 存储)之前的核心拦截层。它决定了哪些请求可以修改集群状态,是实施安全基线核验、策略强制和资源合规检查的关键位置。

2.1 准入控制器原理

准入控制器是一段拦截并处理 API Server 请求的代码插件。当用户或组件向 Kubernetes API 发送创建、更新、删除等变更请求时,请求会依次经过认证 → 鉴权 → 准入控制三个阶段。准入控制器可以验证请求内容、修改请求对象,甚至拒绝请求。

关键特性: 准入控制器仅在创建、更新、删除操作时生效,对读操作(Get、List、Watch)不生效。每个准入控制器可以同时实现 Mutating(变更)和 Validating(验证)两种语义,但推荐分离职责。
阶段 职责 是否可修改对象 执行顺序
认证 验证请求者身份(证书、、用户名/密码) 否 1
鉴权 判断请求者是否有权限执行操作(RBAC、ABAC) 否 2
准入控制 验证/修改请求对象,执行策略检查 是(Mutating) 3

Kubernetes 内置了约 30 个准入控制器(如 NamespaceLifecycle、LimitRanger、PodSecurity),同时支持通过 Webhook 扩展自定义逻辑。OPA Gatekeeper 正是利用 ValidatingAdmissionWebhook 和 MutatingAdmissionWebhook 两种机制实现策略注入。

Kubernetes API 请求处理流程(含准入控制) 用户/客户端 认证 鉴权 准入控制 Mutating Validating etcd 拒绝(Reject) 说明: Mutating 控制器先执行,可修改请求对象(如注入 Sidecar、设置默认值);Validating 控制器后执行, 只验证不修改,拒绝不合规请求。OPA Gatekeeper 主要工作在 Validating 阶段。

2.2 Mutating 与 Validating Webhook

Kubernetes 提供了两种 Webhook 准入控制器,允许集群管理员将自定义逻辑注册到 API Server 的请求处理链中:

  • MutatingAdmissionWebhook:拦截请求后,可以修改(Mutate)请求对象的内容。常用于注入默认值、添加注解、注入 Sidecar 容器等场景。
  • ValidatingAdmissionWebhook:拦截请求后,仅验证对象是否符合策略,不能修改对象。常用于安全策略检查、资源配额验证、合规性审计等场景。
最佳实践: 将变更逻辑与验证逻辑分离。Mutating Webhook 负责修改对象,Validating Webhook 负责策略检查。OPA Gatekeeper 默认使用 Validating Webhook 实现策略强制,但也可通过 Gatekeeper 的 Mutation 功能实现资源变更。
特性 Mutating Webhook Validating Webhook
执行顺序 先执行(在 Validating 之前) 后执行(在 Mutating 之后)
是否可修改对象 是 否
典型用途 注入 Sidecar、设置默认资源限制、添加标签 安全策略检查、合规性验证、资源配额校验
失败策略 Fail 或 Ignore Fail 或 Ignore
超时设置 默认 30 秒(可配置) 默认 30 秒(可配置)
OPA Gatekeeper 使用 可选(Mutation 功能) 主要(策略验证)

Webhook 的注册通过 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 资源对象完成。配置中需要指定 Webhook 服务器的 URL 或 Service 引用、匹配规则(哪些资源、哪些操作触发)、超时时间、失败策略等关键参数。

# ValidatingWebhookConfiguration 示例
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: "gatekeeper-validating-webhook"
webhooks:
- name: "validation.gatekeeper.sh"
  clientConfig:
    service:
      name: gatekeeper-webhook-service
      namespace: gatekeeper-system
      path: "/v1/admit"
    caBundle: <base64-encoded-ca-cert>
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: ["*"]
    apiVersions: ["*"]
    resources: ["pods", "deployments", "namespaces"]
  failurePolicy: Fail
  timeoutSeconds: 5
  admissionReviewVersions: ["v1", "v1beta1"]
  sideEffects: None

2.3 AdmissionReview 请求与响应结构

Kubernetes API Server 与 Webhook 服务器之间通过 AdmissionReview 对象进行通信。API Server 发送 AdmissionReview 请求,Webhook 服务器返回 AdmissionReview 响应。这是所有 Webhook 实现必须遵循的协议。

请求结构(AdmissionRequest)

API Server 构造的 AdmissionRequest 包含请求的完整上下文:

字段 类型 说明
uid string 请求的唯一标识符,用于关联请求与响应
kind GroupVersionKind 被操作资源的 GVK(Group/Version/Kind)
resource GroupVersionResource 被操作资源的 GVR
subResource string 子资源名称(如 status、scale)
operation string 操作类型:CREATE、UPDATE、DELETE、CONNECT
object runtime.Object 请求对象的完整 JSON 表示(DELETE 时可能为空)
oldObject runtime.Object 更新或删除前的旧对象(CREATE 时为空)
userInfo UserInfo 请求者的身份信息(用户名、UID、组列表)
namespace string 请求所在的命名空间(集群作用域资源为空)
dryRun bool 是否为 DryRun 模式

响应结构(AdmissionResponse)

Webhook 服务器必须在 AdmissionResponse 中返回以下关键字段:

字段 类型 说明
uid string 必须与请求中的 uid 一致,用于关联
allowed bool true 表示允许请求,false 表示拒绝
status Status 拒绝时返回的错误信息(code、message)
patch []byte Mutating Webhook 返回的 JSON Patch 操作(Base64 编码)
patchType string Patch 类型,目前仅支持 JSONPatch
warnings []string 警告信息列表(不会拒绝请求,但会展示给用户)
// AdmissionReview 请求示例(JSON 格式)
{
  "apiVersion": "admission.k8s.io/v1",
  "kind": "AdmissionReview",
  "request": {
    "uid": "12345678-1234-1234-1234-123456789abc",
    "kind": {"group": "", "version": "v1", "kind": "Pod"},
    "resource": {"group": "", "version": "v1", "resource": "pods"},
    "namespace": "default",
    "operation": "CREATE",
    "object": {
      "apiVersion": "v1",
      "kind": "Pod",
      "metadata": {
        "name": "nginx-pod",
        "labels": {"app": "nginx"}
      },
      "spec": {
        "containers": [{
          "name": "nginx",
          "image": "nginx:latest"
        }]
      }
    },
    "oldObject": null,
    "userInfo": {
      "username": "admin",
      "uid": "user-abc-123",
      "groups": ["system:masters"]
    },
    "dryRun": false
  }
}

// AdmissionReview 响应示例(拒绝)
{
  "apiVersion": "admission.k8s.io/v1",
  "kind": "AdmissionReview",
  "response": {
    "uid": "12345678-1234-1234-1234-123456789abc",
    "allowed": false,
    "status": {
      "code": 403,
      "message": "Pod 'nginx-pod' 违反了基线安全策略:容器镜像必须来自受信任的仓库"
    },
    "warnings": ["建议使用 'nginx:1.25' 替代 'nginx:latest'"]
  }
}
AdmissionReview 请求/响应交互流程 API Server 构造 AdmissionRequest HTTP POST AdmissionReview Webhook 服务器 解析 AdmissionRequest 执行策略逻辑 HTTP 200 AdmissionReview API Server 解析 AdmissionResponse allowed=true → 继续处理链 / allowed=false → 返回错误给客户端
注意事项:
  • Webhook 响应中的 uid 必须与请求中的 uid 完全一致,否则 API Server 会忽略响应。
  • Mutating Webhook 返回的 patch 必须是标准 JSON Patch 格式(RFC 6902),且需 Base64 编码。
  • Webhook 超时时间建议设置为 5-10 秒,避免长时间阻塞 API Server 请求处理链。
  • 生产环境中务必配置 failurePolicy: Fail,防止策略被绕过。

2.4 本章小结