4、内置准入控制器详解:NamespaceLifecycle、LimitRanger、ResourceQuota、PodSecurityPolicy
Kubernetes 内置了数十个准入控制器(Admission Controller),它们在 API 请求经过认证和授权之后、对象被持久化到 etcd 之前,对请求进行拦截、修改或校验。本章聚焦于四个与集群安全、资源管控和命名空间生命周期密切相关的内置控制器:NamespaceLifecycle、LimitRanger、ResourceQuota 和 PodSecurityPolicy(PSP)。理解它们的工作原理与配置方式,是构建安全、稳定的多租户集群的基础。
--enable-admission-plugins 中启用。
4.1 NamespaceLifecycle:命名空间生命周期保护
NamespaceLifecycle 是一个 Mutating 准入控制器,主要职责是防止在处于 Terminating 状态的命名空间中创建新的资源对象。当集群管理员删除一个命名空间时,该命名空间会进入 Terminating 状态,此时 API Server 会拒绝所有在该命名空间下创建新资源的请求,直到命名空间内的所有资源被清理完毕。
- 拒绝在
Terminating状态的 Namespace 中创建 Pod、Service、Deployment 等任何资源。 - 允许读取、更新和删除操作,以便清理资源。
- 自动拒绝创建系统保留的命名空间(如
default、kube-system、kube-public)的删除请求。
典型场景: 当集群管理员执行 kubectl delete namespace test-ns 后,该命名空间进入 Terminating 状态。如果此时有自动化脚本尝试在该命名空间中创建新的 Pod,NamespaceLifecycle 会立即返回 403 Forbidden,避免资源泄漏或状态不一致。
4.2 LimitRanger:默认资源限制注入
LimitRanger 是一个 Mutating 准入控制器,它在 Pod 创建或更新时,为那些没有显式设置 resources.requests 或 resources.limits 的容器注入默认值。LimitRanger 通过 LimitRange 资源对象定义默认值和最小/最大值约束。
| LimitRange 字段 | 类型 | 说明 |
|---|---|---|
default |
ResourceList | 容器的默认 resource limits(上限) |
defaultRequest |
ResourceList | 容器的默认 resource requests(请求量) |
max |
ResourceList | 容器允许的最大 resource limits |
min |
ResourceList | 容器允许的最小 resource requests |
maxLimitRequestRatio |
ResourceList | limits 与 requests 的最大比例 |
配置示例:
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-mem-limit-range
namespace: default
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
max:
cpu: "2"
memory: "2Gi"
min:
cpu: "50m"
memory: "64Mi"
type: Container
requests 或 limits,LimitRanger 不会覆盖它们。此外,LimitRanger 的校验逻辑会检查容器设置的值是否在 min 和 max 范围内,超出范围则拒绝创建。
4.3 ResourceQuota:命名空间资源配额
ResourceQuota 是一个 Validating 准入控制器,用于限制命名空间内所有资源对象的总量。它通过 ResourceQuota 资源对象定义配额,包括 CPU/内存总量、Pod 数量、PVC 数量、ConfigMap 数量等。
常见配额维度:
- 计算资源:
requests.cpu、requests.memory、limits.cpu、limits.memory - 存储资源:
requests.storage、persistentvolumeclaims - 对象数量:
pods、services、configmaps、secrets、replicationcontrollers等
配置示例:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-a
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "20"
persistentvolumeclaims: "10"
configmaps: "30"
hard 中定义的上限,则拒绝该请求。ResourceQuota 是集群资源隔离和多租户场景的核心组件。
4.4 PodSecurityPolicy:Pod 安全策略
PodSecurityPolicy(PSP) 是一个 Validating 准入控制器,用于控制 Pod 的安全敏感属性。它定义了 Pod 必须满足的安全条件,包括是否允许特权容器、允许挂载哪些卷类型、允许使用哪些 Linux Capabilities、运行用户 ID 范围等。
PSP 核心字段:
| 字段 | 说明 |
|---|---|
privileged |
是否允许特权容器(false 为禁止) |
hostPID / hostIPC |
是否允许使用主机 PID/IPC 命名空间 |
allowedCapabilities |
允许添加的 Linux Capabilities 列表 |
requiredDropCapabilities |
必须删除的 Linux Capabilities 列表 |
runAsUser |
运行用户 ID 的策略(MustRunAs、MustRunAsNonRoot 等) |
seLinux |
SELinux 上下文策略 |
volumes |
允许使用的卷类型白名单 |
PSP 配置示例:
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted-psp
spec:
privileged: false
hostPID: false
hostIPC: false
hostNetwork: false
allowedCapabilities: []
requiredDropCapabilities:
- ALL
runAsUser:
rule: MustRunAsNonRoot
seLinux:
rule: RunAsAny
supplementalGroups:
rule: MustRunAs
ranges:
- min: 1
max: 65535
fsGroup:
rule: MustRunAs
ranges:
- min: 1
max: 65535
volumes:
- configMap
- emptyDir
- projected
- secret
- downwardAPI
- persistentVolumeClaim
4.5 四个控制器的协同与对比
在实际集群中,这四个控制器通常同时启用,形成多层次的防护体系:
| 控制器 | 类型 | 作用范围 | 主要防护目标 |
|---|---|---|---|
| NamespaceLifecycle | Mutating | 命名空间 | 防止在删除中的命名空间创建资源 |
| LimitRanger | Mutating | Pod 容器 | 注入默认资源限制,防止资源争抢 |
| ResourceQuota | Validating | 命名空间 | 限制命名空间资源总量,防止资源滥用 |
| PodSecurityPolicy | Validating | Pod 安全上下文 | 强制 Pod 安全基线,防止特权逃逸 |
- 始终启用 NamespaceLifecycle,它是集群稳定性的基础保障。
- 为每个命名空间创建 LimitRange 和 ResourceQuota,尤其是多租户场景。
- 对于 PSP(或 PSA),建议从 restricted 策略开始,逐步放宽到 baseline 或 privileged,避免直接使用宽松策略。
- 使用
kubectl describe quota和kubectl describe limitrange定期检查资源使用情况。
通过合理配置这四个内置准入控制器,集群管理员可以在命名空间生命周期管理、资源配额控制和 Pod 安全策略三个维度上构建起坚固的安全防线,为集群节点扩容和日常运维提供可靠的准入控制保障。