2. Kubernetes 准入控制基础
Kubernetes 准入控制(Admission Control)是 API Server 请求处理链中位于认证(Authentication)与鉴权(Authorization)之后、对象持久化(etcd 存储)之前的核心拦截层。它决定了哪些请求可以修改集群状态,是实施安全基线核验、策略强制和资源合规检查的关键位置。
2.1 准入控制器原理
准入控制器是一段拦截并处理 API Server 请求的代码插件。当用户或组件向 Kubernetes API 发送创建、更新、删除等变更请求时,请求会依次经过认证 → 鉴权 → 准入控制三个阶段。准入控制器可以验证请求内容、修改请求对象,甚至拒绝请求。
| 阶段 | 职责 | 是否可修改对象 | 执行顺序 |
|---|---|---|---|
| 认证 | 验证请求者身份(证书、、用户名/密码) | 否 | 1 |
| 鉴权 | 判断请求者是否有权限执行操作(RBAC、ABAC) | 否 | 2 |
| 准入控制 | 验证/修改请求对象,执行策略检查 | 是(Mutating) | 3 |
Kubernetes 内置了约 30 个准入控制器(如 NamespaceLifecycle、LimitRanger、PodSecurity),同时支持通过 Webhook 扩展自定义逻辑。OPA Gatekeeper 正是利用 ValidatingAdmissionWebhook 和 MutatingAdmissionWebhook 两种机制实现策略注入。
2.2 Mutating 与 Validating Webhook
Kubernetes 提供了两种 Webhook 准入控制器,允许集群管理员将自定义逻辑注册到 API Server 的请求处理链中:
- MutatingAdmissionWebhook:拦截请求后,可以修改(Mutate)请求对象的内容。常用于注入默认值、添加注解、注入 Sidecar 容器等场景。
- ValidatingAdmissionWebhook:拦截请求后,仅验证对象是否符合策略,不能修改对象。常用于安全策略检查、资源配额验证、合规性审计等场景。
| 特性 | 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'"]
}
}
- Webhook 响应中的
uid必须与请求中的uid完全一致,否则 API Server 会忽略响应。 - Mutating Webhook 返回的
patch必须是标准 JSON Patch 格式(RFC 6902),且需 Base64 编码。 - Webhook 超时时间建议设置为 5-10 秒,避免长时间阻塞 API Server 请求处理链。
- 生产环境中务必配置
failurePolicy: Fail,防止策略被绕过。