Kubernetes 准入控制基础:概念、工作流程与控制器类型

准入控制(Admission Control)是 Kubernetes API Server 请求链路上的关键安全与策略执行关卡。所有对集群资源进行创建、更新、删除操作的请求,在通过认证(Authentication)和授权(Authorization)之后、对象被持久化到 etcd 之前,都必须经过准入控制器的拦截与处理。本章将深入剖析准入控制器的核心概念、完整工作流程,以及 Mutating 与 Validating 两类控制器的本质区别。

2.1 准入控制器的概念与定位

准入控制器是一段拦截并处理 API Server 请求的代码插件,它在请求被认证和授权之后、对象被持久化存储之前运行。准入控制器可以修改请求对象(Mutating)、验证请求对象(Validating),或同时执行两种操作。

核心定位:准入控制器是 Kubernetes 策略执行的“最后一公里”——在对象写入 etcd 之前,确保其符合集群的安全基线、合规要求和运维规范。

准入控制器的主要职责包括:

  • 策略执行:强制实施资源配额、Pod 安全标准、网络策略等集群级规则。
  • 默认值注入:为未显式设置的字段填充合理的默认配置(如资源限制、标签、亲和性规则)。
  • 安全加固:禁止特权容器、限制宿主机路径挂载、强制只读根文件系统等。
  • 合规审计:确保所有资源对象满足组织合规要求(如镜像签名验证、敏感信息脱敏)。

2.2 准入控制工作流程

一个完整的 API 请求在 Kubernetes API Server 中的处理流程如下:

  1. 认证(Authentication):验证请求发起者的身份(证书、、用户名/密码)。
  2. 授权(Authorization):检查请求者是否拥有执行该操作的权限(RBAC、ABAC、Node 授权)。
  3. 准入控制(Admission Control):依次经过 Mutating 控制器链 → 对象模式验证 → Validating 控制器链。
  4. 持久化(Persist to etcd):通过所有准入检查后,对象被写入 etcd 存储。
关键时序:Mutating 控制器 先于 Validating 控制器执行。这意味着 Validating 控制器看到的是经过 Mutating 控制器修改后的最终对象版本,从而可以基于完整的对象状态进行验证。
Kubernetes API 请求处理流程(含准入控制) 客户端请求 认证 授权 准入控制 Mutating 控制器链 对象模式验证 Validating 控制器链 etcd 持久化 拒绝请求 说明: Mutating 控制器先执行(注入默认值/修改对象)→ 对象模式验证 → Validating 控制器后执行(校验最终对象)。 任何阶段拒绝请求,对象都不会被持久化到 etcd。

2.3 Mutating 与 Validating 控制器的区别

Kubernetes 将准入控制器分为两大类:Mutating(变更)和 Validating(验证)。两者在功能、执行时机和设计目标上存在本质差异。

对比维度 Mutating 控制器 Validating 控制器
核心功能 修改(注入/变更)请求对象 验证(拒绝/通过)请求对象
执行顺序 先执行(在 Validating 之前) 后执行(在 Mutating 之后)
操作类型 添加默认值、注入 Sidecar、修正字段 检查合规性、验证约束、拒绝非法请求
副作用 允许产生副作用(如修改对象) 不应产生副作用(只读检查)
失败行为 拒绝请求,不执行后续控制器 拒绝请求,不持久化对象
典型示例 MutatingAdmissionWebhook、DefaultStorageClass、PodNodeSelector ValidatingAdmissionWebhook、PodSecurity、ResourceQuota
重要原则:Mutating 控制器应保持幂等性——多次执行应产生相同结果。如果 Mutating 控制器非幂等,可能导致 Validating 控制器看到不一致的对象状态,引发难以排查的故障。

2.4 内置准入控制器分类速览

Kubernetes 内置了数十个准入控制器,按功能领域可划分为以下几类:

类别 控制器名称 类型 主要作用
安全策略 PodSecurity Validating 实施 Pod 安全标准(Privileged/Baseline/Restricted)
SecurityContextDeny Validating 拒绝违反安全上下文的 Pod(已弃用,由 PodSecurity 替代)
资源管理 ResourceQuota Validating 确保命名空间资源使用不超过配额
LimitRanger Mutating + Validating 为未设置资源限制的 Pod 注入默认值,并验证限制范围
存储管理 DefaultStorageClass Mutating 为未指定 StorageClass 的 PVC 注入默认存储类
StorageObjectInUseProtection Validating 防止正在使用的 PV/PVC 被误删除
网络策略 NodeRestriction Validating 限制 kubelet 只能修改自身节点和 Pod 对象
AlwaysPullImages Mutating 强制所有 Pod 使用 imagePullPolicy: Always
通用扩展 MutatingAdmissionWebhook Mutating 调用外部 Webhook 服务修改请求对象
ValidatingAdmissionWebhook Validating 调用外部 Webhook 服务验证请求对象

2.5 动态准入控制:Webhook 扩展机制

Kubernetes 1.9+ 引入了 动态准入控制(Dynamic Admission Control),允许集群管理员通过 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 两种资源对象,将自定义的准入逻辑注册到 API Server 的请求链中。

Webhook 的工作机制如下:

  1. 管理员创建 ValidatingWebhookConfiguration 或 MutatingWebhookConfiguration 资源,指定匹配规则(resources、operations、apiGroups)和 Webhook 服务端点。
  2. API Server 在请求处理过程中,根据规则匹配到对应的 Webhook,发送 AdmissionReview 请求到外部 HTTPS 服务。
  3. 外部服务处理请求后,返回 AdmissionReview 响应,包含 allowed(是否允许)和 patch(仅 Mutating 需要)字段。
  4. API Server 根据响应决定继续处理或拒绝请求。
生产建议:Webhook 服务必须部署高可用(至少 2 副本),并配置合理的 failurePolicy(Fail 或 Ignore)。对于关键策略(如安全基线),建议使用 failurePolicy: Fail;对于非关键策略(如审计日志),可使用 failurePolicy: Ignore 避免 Webhook 故障影响集群可用性。
动态准入控制 Webhook 架构 API Server AdmissionReview 请求 Webhook 配置 Webhook 服务 HTTPS 端点 策略引擎 OPA / Kyverno / 自定义 返回 AdmissionReview 响应(allowed + patch) 关键配置字段: clientConfig.service → Webhook 服务地址 | rules → 匹配资源/操作规则 | failurePolicy → Fail/Ignore | timeoutSeconds → 超时时间(默认 10s) sideEffects → None/NoneOnDryRun | admissionReviewVersions → v1/v1beta1

2.6 准入控制器配置与启用

Kubernetes API Server 通过启动参数 --enable-admission-plugins 和 --disable-admission-plugins 控制准入控制器的启用状态。在 v1.10+ 版本中,推荐使用的准入控制器列表已包含默认启用的集合。

查看当前 API Server 启用的准入控制器:

# 通过 kube-apiserver 进程参数查看
ps aux | grep kube-apiserver | grep --enable-admission-plugins

# 或通过 kubectl 查看集群信息(部分版本支持)
kubectl get --raw /livez?verbose | grep admission

在 kubeadm 部署的集群中,可通过修改 /etc/kubernetes/manifests/kube-apiserver.yaml 静态 Pod 清单来调整准入控制器配置:

spec:
  containers:
  - command:
    - kube-apiserver
    - --enable-admission-plugins=NodeRestriction,PodSecurity,DefaultStorageClass
    - --disable-admission-plugins=SecurityContextDeny
最佳实践:在生产集群中,建议至少启用以下准入控制器组合:
NamespaceLifecycle, LimitRanger, ServiceAccount, NodeRestriction, PodSecurity, DefaultStorageClass, ResourceQuota, MutatingAdmissionWebhook, ValidatingAdmissionWebhook

2.7 本章小结