准入控制(Admission Control)是 Kubernetes API 请求处理流程中的关键环节,用于在请求通过认证(Authentication)和鉴权(Authorization)后,对请求进行验证(Validation)或修改(Mutation)。它是集群安全、资源管理和合规性的最后一道防线。
01 准入控制作用和应用场景
1. 作用
验证(Validating):检查请求是否符合集群策略(如禁止特权容器、资源限制)。
修改(Mutating):动态修改请求内容(如注入 Sidecar 容器、添加默认标签)。
拦截非法请求:在请求持久化到 etcd 前拦截违规操作。
2. 应用场景
安全加固:
a. 禁止特权容器(privileged: true)。
b. 要求 Pod 以非 root 用户运行。
资源管理:
a. 为命名空间设置默认资源配额。
b. 自动注入 Sidecar 容器(如 Istio Envoy)。
合规性:
a. 确保镜像来自受信任仓库。
b. 审计敏感操作(如创建 ClusterRoleBinding)。
02 准入控制流程
API HTTP handler:用户发起请求(如创建pod等)到K8S API服务器。
Authentication/Authorization:身份认证和鉴权。
Mutating admission:变更准入控制器。支持根据被其接受的请求更改相关对象,调用变更性webhook。
Object Schema Validation:验证准入策略
Validating admission:验证控制器,调用验证webhook。
Persisted to etcd:写入etcd
03 准入控制类型
1. 静态准入控制
静态准入控制器是k8s内置的控制器,用于在 K8S API 服务器处理请求的过程中(资源被持久化前)对请求进行拦截、验证或修改。
常见的静态准入控制器如下:
(更多控制器信息见官网资料:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controllers/)
类型 |
名称 |
作用 |
变更 |
DefaultStorageClass |
此准入控制器监测没有请求任何特定存储类的 PersistentVolumeClaim 对象的创建请求, 并自动向其添加默认存储类。 这样,没有任何特殊存储类需求的用户根本不需要关心它们,它们将被设置为使用默认存储类。 当默认的 StorageClass 不存在时,此准入控制器不执行任何操作。如果将多个存储类标记为默认存储类, 而且你之后在未设置 storageClassName 的情况下创建 PersistentVolumeClaim, Kubernetes 将使用最近创建的默认 StorageClass。 当使用指定的 volumeName 创建 PersistentVolumeClaim 时,如果在应用任意默认的 StorageClass 之后, 静态卷的 storageClassName 与 PersistentVolumeClaim 上的 storageClassName 不匹配, 则 PersistentVolumeClaim 保持在 Pending 状态。 此准入控制器会忽略所有 PersistentVolumeClaim 更新操作,仅处理创建操作 |
DefaultIngressClass |
该准入控制器监测没有请求任何特定 Ingress 类的 Ingress 对象创建请求,并自动向其添加默认 Ingress 类。 这样,没有任何特殊 Ingress 类需求的用户根本不需要关心它们,他们将被设置为默认 Ingress 类。 当未配置默认 Ingress 类时,此准入控制器不执行任何操作。如果有多个 Ingress 类被标记为默认 Ingress 类, 此控制器将拒绝所有创建 Ingress 的操作,并返回错误信息。 要修复此错误,管理员必须重新检查其 IngressClass 对象,并仅将其中一个标记为默认 (通过注解 "ingressclass.kubernetes.io/is-default-class")。 此准入控制器会忽略所有 Ingress 更新操作,仅处理创建操作 |
|
DefaultTolerationSeconds |
此准入控制器基于 k8s-apiserver 的输入参数 default-not-ready-toleration-seconds 和 default-unreachable-toleration-seconds 为 Pod 设置默认的容忍度,以容忍 notready:NoExecute 和 unreachable:NoExecute 污点 (如果 Pod 尚未容忍 node.kubernetes.io/not-ready:NoExecute 和 node.kubernetes.io/unreachable:NoExecute 污点的话)。 default-not-ready-toleration-seconds 和 default-unreachable-toleration-seconds 的默认值是 5 分钟 |
|
PodTopologyLabels |
PodTopologyLabels 准入控制器变更所有绑定到节点的 pod 的 pods/binding 子资源, 添加与所绑定节点相匹配的拓扑标签。 这使得节点拓扑标签可以作为 Pod 标签使用,并且可以通过 Downward API 提供给运行中的容器。 由于此控制器而可用的标签是 topology.kubernetes.io/region 和 topology.kubernetes.io/zone 标签 |
|
MutatingAdmissionWebhook |
此准入控制器调用任何与请求匹配的变更(Mutating) Webhook。匹配的 Webhook 将被顺序调用。 每一个 Webhook 都可以自由修改对象。 MutatingAdmissionWebhook,顾名思义,仅在变更阶段运行。 如果由此准入控制器调用的 Webhook 有副作用(如:减少配额), 则它 必须 具有协调系统,因为不能保证后续的 Webhook 和验证准入控制器都会允许完成请求。 如果你禁用了 MutatingAdmissionWebhook,那么还必须使用 --runtime-config 标志禁止 admissionregistration.k8s.io/v1 组/版本中的 MutatingWebhookConfiguration, 二者都是默认启用的 |
|
NamespaceAutoProvision |
此准入控制器会检查针对名字空间域资源的所有传入请求,并检查所引用的名字空间是否确实存在。 如果找不到所引用的名字空间,控制器将创建一个名字空间。 此准入控制器对于不想要求名字空间必须先创建后使用的集群部署很有用 |
|
StorageObjectInUseProtection |
StorageObjectInUseProtection 插件将 kubernetes.io/pvc-protection 或 kubernetes.io/pv-protection 终结器(finalizers)添加到新创建的持久卷申领(PVC) 或持久卷(PV)中。如果用户尝试删除 PVC/PV,除非 PVC/PV 的保护控制器移除终结器, 否则 PVC/PV 不会被删除 |
|
TaintNodesByCondition |
该准入控制器为新创建的节点添加 NotReady 和 NoSchedule 污点。 这些污点能够避免一些竞态条件的发生,而这类竞态条件可能导致 Pod 在更新节点污点以准确反映其所报告状况之前,就被调度到新节点上 |
|
验证 |
CertificateApproval |
此准入控制器获取审批 CertificateSigningRequest 资源的请求并执行额外的鉴权检查, 以确保针对设置了 spec.signerName 的 CertificateSigningRequest 资源而言, 审批请求的用户有权限对证书请求执行 审批 操作 |
CertificateSigning |
此准入控制器监视对 CertificateSigningRequest 资源的 status.certificate 字段的更新请求, 并执行额外的鉴权检查,以确保针对设置了 spec.signerName 的 CertificateSigningRequest 资源而言, 签发证书的用户有权限对证书请求执行 签发 操作 |
|
CertificateSubjectRestriction |
此准入控制器监视 spec.signerName 被设置为 kubernetes.io/kube-apiserver-client 的 CertificateSigningRequest 资源创建请求,并拒绝所有将 “group”(或 “organization attribute”) 设置为 system:masters 的请求 |
|
NamespaceExists |
此准入控制器检查针对名字空间作用域的资源(除 Namespace 自身)的所有请求。 如果请求引用的名字空间不存在,则拒绝该请求 |
|
NamespaceLifecycle |
该准入控制器禁止在一个正在被终止的 Namespace 中创建新对象,并确保针对不存在的 Namespace 的请求被拒绝。该准入控制器还会禁止删除三个系统保留的名字空间,即 default、 kube-system 和 kube-public。 Namespace 的删除操作会触发一系列删除该名字空间中所有对象(Pod、Service 等)的操作。 为了确保这个过程的完整性,我们强烈建议启用这个准入控制器 |
|
PersistentVolumeClaimResize |
此准入控制器检查传入的 PersistentVolumeClaim 调整大小请求,对其执行额外的验证检查操作。 建议启用 PersistentVolumeClaimResize 准入控制器。除非 PVC 的 StorageClass 明确地将 allowVolumeExpansion 设置为 true 来显式启用调整大小。 否则,默认情况下该准入控制器会阻止所有对 PVC 大小的调整。 |
|
PodSecurity |
PodSecurity 准入控制器在新 Pod 被准入之前对其进行检查, 根据请求的安全上下文和 Pod 所在名字空间允许的 Pod 安全性标准的限制来确定新 Pod 是否应该被准入 |
|
ResourceQuota |
此准入控制器会监测传入的请求,并确保它不违反任何一个 Namespace 中的 ResourceQuota 对象中列举的约束。如果你在 Kubernetes 部署中使用了 ResourceQuota, 则必须使用这个准入控制器来强制执行配额限制 |
|
变更和验证 |
LimitRanger |
此准入控制器会监测传入的请求,并确保请求不会违反 Namespace 中 LimitRange 对象所设置的任何约束。 如果你在 Kubernetes 部署中使用了 LimitRange 对象,则必须使用此准入控制器来执行这些约束。 LimitRanger 还可以用于将默认资源请求应用到没有设定资源约束的 Pod; 当前,默认的 LimitRanger 对 default 名字空间中的所有 Pod 都设置 0.1 CPU 的需求 |
PodTolerationRestriction |
准入控制器 PodTolerationRestriction 检查 Pod 的容忍度与其名字空间的容忍度之间是否存在冲突。 如果存在冲突,则拒绝 Pod 请求。 控制器接下来会将名字空间的容忍度合并到 Pod 的容忍度中, 根据名字空间的容忍度白名单检查所得到的容忍度结果。 如果检查成功,则将接受 Pod 请求,否则拒绝该请求。 如果 Pod 的名字空间没有任何关联的默认容忍度或容忍度白名单, 则使用集群级别的默认容忍度或容忍度白名单(如果有的话)。 名字空间的容忍度通过注解键 scheduler.alpha.kubernetes.io/defaultTolerations 来设置。可接受的容忍度可以通过 scheduler.alpha.kubernetes.io/tolerationsWhitelist 注解键来添加 |
|
优先级 |
优先级准入控制器使用 priorityClassName 字段并用整型值填充优先级。 如果找不到优先级,则拒绝 Pod |
|
RuntimeClass |
如果你所定义的 RuntimeClass 包含 Pod 开销, 这个准入控制器会检查新的 Pod。 被启用后,此准入控制器会拒绝所有已经设置了 overhead 字段的 Pod 创建请求。 对于配置了 RuntimeClass 并在其 .spec 中选定 RuntimeClass 的 Pod, 此准入控制器会根据相应 RuntimeClass 中定义的值为 Pod 设置 .spec.overhead |
|
ServiceAccount |
此准入控制器实现了 ServiceAccount 的自动化。强烈推荐为 Kubernetes 项目启用此准入控制器。 如果你打算使用 Kubernetes 的 ServiceAccount 对象,你应启用这个准入控制器 |
2. 动态准入控制
动态准入控制器通过 Webhook 机制扩展准入控制逻辑,实现自定义策略。
动态准入控制器分为两类:
a. Mutating Webhook:修改请求。
b. Validating Webhook:验证请求。
核心步骤:
a. 开发 Webhook 服务:接收准入请求,返回决策结果。
b. 配置 Webhook:通过 MutatingWebhookConfiguration 或 ValidatingWebhookConfiguration 注册服务。
c. API Server 调用 Webhook:根据配置触发自定义逻辑。
常用动态准入控制工具
a. Open Policy Agent (OPA):通过 Rego 策略语言定义复杂规则(需配合 Gatekeeper)。
b. Kyverno:声明式策略引擎,支持 YAML 编写策略,无需编码。
c. Cert-Manager:自动管理 TLS 证书,依赖 Webhook 准入控制。
往期回顾:

