3. 内置准入控制器详解:常用内置准入控制器列表、功能说明
Kubernetes 内置了数十个准入控制器,它们被编译进 kube-apiserver 二进制文件中,无需额外安装即可启用。本章聚焦于与资源配额、命名空间隔离、安全策略及资源限制密切相关的核心内置控制器,帮助您理解其工作原理与配置方式。
3.1 常用内置准入控制器一览
下表列出了生产集群中最常启用且与策略即代码(Policy-as-Code)及资源配额模型集成最紧密的 6 个内置准入控制器。每个控制器在 API 请求处理链中扮演特定角色,按执行顺序排列。
| 控制器名称 | 类型 | 核心职责 | 影响资源 | 默认启用状态 |
|---|---|---|---|---|
| NamespaceLifecycle | Mutating + Validating | 防止在删除中的命名空间创建资源;拒绝不存在的命名空间请求 | 所有命名空间资源 | ✅ 是 |
| LimitRanger | Mutating + Validating | 为未设置资源限制的 Pod 注入默认资源请求/限制;验证 Pod 资源不超出最小值/最大值 | Pod、Container | ✅ 是 |
| ResourceQuota | Validating | 验证命名空间内资源总量不超过配额;拒绝超出配额的创建/更新请求 | Pod、Service、PVC、ConfigMap 等 | ✅ 是 |
| PodSecurity | Validating | 根据 Pod Security Standards(基线/受限/特权)验证 Pod 安全上下文 | Pod | ✅ 是(v1.25+) |
| NodeRestriction | Validating | 限制 kubelet 只能修改自身节点及绑定到该节点的 Pod 对象 | Node、Pod | ✅ 是 |
| MutatingAdmissionWebhook | Mutating | 调用外部 Webhook 对资源进行修改(注入 sidecar、设置标签等) | 所有资源 | ✅ 是 |
3.2 核心控制器功能详解
3.2.1 NamespaceLifecycle
该控制器确保命名空间的生命周期状态与资源创建操作一致。当命名空间处于 Terminating 状态时,所有创建新资源的请求都会被拒绝。同时,它也会验证请求中引用的命名空间是否真实存在,防止因命名空间不存在导致的悬空资源。
- Mutating 行为: 无(仅验证)。
- Validating 行为: 检查
namespace.spec.finalizers与namespace.status.phase。 - 典型场景: 配合 ResourceQuota 实现租户隔离,确保删除命名空间时不会产生孤儿资源。
3.2.2 LimitRanger
LimitRanger 在 Pod 创建或更新时,为未显式设置资源请求(requests)或限制(limits)的容器注入默认值。它同时验证容器资源是否在命名空间定义的 min/max 范围内。
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- max:
cpu: "2"
memory: "2Gi"
min:
cpu: "100m"
memory: "128Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
type: Container
- Mutating 行为: 为未设置
resources.requests或resources.limits的容器注入默认值。 - Validating 行为: 验证容器资源不超出
max且不低于min。 - 与 ResourceQuota 的关系: LimitRanger 控制单个 Pod 的资源边界,ResourceQuota 控制命名空间内所有 Pod 的聚合资源总量。
3.2.3 ResourceQuota
ResourceQuota 是资源配额模型的核心执行者。它定义命名空间内可消耗的计算资源(CPU、内存)和对象数量(Pod、Service、PVC 等)的上限。当请求导致命名空间内任何资源总量超过配额时,API Server 会拒绝该请求。
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "50"
services: "10"
persistentvolumeclaims: "5"
- Validating 行为: 在请求处理链的后期(LimitRanger 之后)执行,确保聚合资源不超配额。
- 作用域: 支持
BestEffort、NotBestEffort、Terminating、NotTerminating等作用域,实现精细化的配额控制。 - 与策略即代码的集成: ResourceQuota 是静态配额,而策略引擎(如 Gatekeeper)可以动态生成或覆盖配额约束,实现更灵活的配额模型。
3.2.4 PodSecurity
PodSecurity 控制器(自 Kubernetes v1.23 起 GA)替代了废弃的 PodSecurityPolicy。它根据预定义的 Pod Security Standards(Privileged、Baseline、Restricted)验证 Pod 的安全上下文,包括特权容器、主机网络、卷类型、Seccomp 配置等。
apiVersion: v1
kind: Namespace
metadata:
name: secure-ns
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: baseline
pod-security.kubernetes.io/warn: baseline
- Validating 行为: 根据命名空间标签
pod-security.kubernetes.io/enforce定义的级别执行强制验证。 - 三种模式:
enforce(拒绝不符合的 Pod)、audit(记录审计日志但不拒绝)、warn(返回警告但不拒绝)。 - 与资源配额的关系: PodSecurity 控制 Pod 的安全合规性,ResourceQuota 控制资源消耗量,两者共同构成安全与资源的双重准入防线。
3.3 内置准入控制器执行流程
下图展示了在 Pod 创建请求中,上述核心内置控制器的执行顺序与交互关系。注意 Mutating 控制器先于 Validating 控制器执行,且 ResourceQuota 在 LimitRanger 之后执行以获取准确的资源数值。
3.4 控制器之间的依赖与冲突
在集成资源配额模型时,必须理解控制器之间的隐式依赖关系,否则可能导致策略失效或意外拒绝。
| 依赖关系 | 说明 | 潜在问题 |
|---|---|---|
| LimitRanger → ResourceQuota | LimitRanger 先注入默认资源值,ResourceQuota 再基于注入后的值进行总量验证 | 若 LimitRanger 未启用,未设置资源限制的 Pod 可能绕过配额验证 |
| NamespaceLifecycle → ResourceQuota | NamespaceLifecycle 确保命名空间可用后,ResourceQuota 才执行 | 若 NamespaceLifecycle 被禁用,可能在 Terminating 命名空间中创建资源导致配额混乱 |
| PodSecurity → ResourceQuota | PodSecurity 先验证安全合规性,ResourceQuota 后验证资源总量 | 安全合规的 Pod 仍可能因资源不足被拒绝,需在配额中预留安全 Pod 的资源空间 |
resources.requests 的 Pod,ResourceQuota 无法准确计算该 Pod 的资源消耗,可能导致配额验证失效。最佳实践是始终同时启用 LimitRanger 与 ResourceQuota。
3.5 内置控制器与策略即代码的协作模式
内置控制器提供基础准入能力,而策略即代码引擎(如 OPA/Gatekeeper、Kyverno)通过 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 扩展准入能力。下图展示了这种分层协作架构。
3.6 生产环境启用建议
- 始终启用核心控制器: NamespaceLifecycle、LimitRanger、ResourceQuota、PodSecurity 应作为生产集群的强制启用项,不要轻易关闭。
- 控制器顺序不可更改: 内置控制器的执行顺序由 API Server 内部硬编码,无法通过配置调整。设计策略时需假设 LimitRanger 在 ResourceQuota 之前执行。
- Webhook 超时处理: 动态准入 Webhook 可能因网络或策略引擎故障导致超时。建议为 Webhook 设置合理的
timeoutSeconds(默认 30s),并配置failurePolicy: Fail或failurePolicy: Ignore以控制故障行为。 - 审计与监控: 启用
--audit-log-path记录所有准入决策,配合kube-apiserver的指标apiserver_admission_webhook_rejection_count监控 Webhook 拒绝率。