Kubernetes的默认设计 philosophy 是“集群内高度互信”,任何拿到创建Pod权限的用户,理论上都可以提交一个特权Pod,直接挂载宿主机根目录、以root身份执行任意命令。在多人共享集群或者对外提供服务的场景下,这种自由度就是安全隐患。PodSecurityPolicy(简称PSP)曾是官方给出的答案,但从1.21版本开始废弃,并在1.25版本中被正式移除,取而代之的是内置的准入控制器Pod Security Admission(简称PSA)。本文围绕这套新机制,讲清楚它的分级模型、配置方式和落地策略。

一、为什么PSP被淘汰,PSA取而代之
PSP的问题不在理念,而在实现。它本质上是一种复杂的准入控制器,策略对象字段多达几十个,且生效行为充满陷阱:创建了PSP但用户没有use权限时,Pod反而会被全部拒绝,授权模型的细微差别经常让运维排查到深夜。更麻烦的是PSP是“许可性默认”,没有显式策略覆盖的Pod不受任何约束,管理员很难确定集群实际执行了什么策略。
Pod Security Admission走了一条完全不同的路线:它不再依赖独立的策略对象,而是把安全要求抽象成三个标准化级别,内置在kube-apiserver中(1.23起默认启用),通过Namespace标签声明即可生效。整个机制没有授权环节,没有策略匹配问题,行为完全可预测。代价是灵活性下降,它无法表达“只允许张三的Pod使用hostNetwork”这类细粒度规则,这类需求需要交给OPA Gatekeeper或Kyverno这类策略引擎来补充。
这个取舍体现了社区的判断:绝大多数集群需要的是一套开箱即用、认知统一的安全基线,而不是一个万能策略引擎。基线交给PSA,复杂策略交给外部引擎,两者分层配合。
二、三个安全级别的具体含义
PSA定义了三个级别,从严到宽分别是privileged、baseline和restricted。理解每个级别禁止什么,是配置的基础。
privileged是最宽松的级别,不做任何限制,等价于关闭Pod安全检查,适用于系统组件所在的Namespace,比如kube-system。如果对kube-system强行应用restricted,很多控制面组件会因为需要特权而无法启动。
baseline目标是阻止已知的明显提权手段,同时不影响常规业务容器。它禁止的能力包括:特权容器(privileged=true)、宿主机命名空间共享(hostNetwork、hostPID、hostIPC)、不受限制的宿主机文件系统挂载(如挂载/proc、/sys的路径)、以及其他危险能力(如CAP_SYS_ADMIN之外再添加SYS_BOOT等)。大部分无状态业务Pod都能通过baseline检查。
restricted是最严格的级别,在baseline基础上进一步要求:容器必须以非root运行(runAsNonRoot=true)、seccompProfile必须设置为RuntimeDefault或Localhost、必须删除所有Linux capabilities只保留必要的NET_BIND_SERVICE,且不允许设置allowPrivilegeEscalation=true。这个级别与主流安全基线(如CIS Benchmark)对齐,适合运行不可信或对外暴露的工作负载。
各级别对常用字段的要求可以简单对比:
| 字段 | privileged | baseline | restricted |
|---|---|---|---|
| 特权容器 | 允许 | 禁止 | 禁止 |
| hostNetwork/hostPID | 允许 | 禁止 | 禁止 |
| runAsNonRoot | 不要求 | 不要求 | 必须为true |
| allowPrivilegeEscalation | 允许 | 不限制 | 必须为false |
| seccompProfile | 不要求 | 不要求 | 必须设置 |
三、通过Namespace标签配置PSA
PSA的配置完全通过Namespace标签完成,核心标签有两组:pod-security.kubernetes.io/enforce控制违反策略时直接拒绝;pod-security.kubernetes.io/audit违反时只记录审计事件;pod-security.kubernetes.io/warn违反时在API响应中返回警告。三种模式可以同时启用,还可以用后缀-version锁定策略版本,避免升级集群时基线悄悄变化。
一个典型的生产配置示例如下,对业务Namespace强制restricted,但锁定到较老的基线版本以减少升级冲击:
apiVersion: v1
kind: Namespace
metadata:
name: production-app
labels:
# 违反时直接拒绝创建,锁定基线版本
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.29
# 违反时记录到审计日志,便于排查存量工作负载
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
# 违反时在kubectl返回信息中给出警告
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
如果需要在集群层面设置所有Namespace的默认值(包括新建Namespace),可以配置kube-apiserver的 admission configuration 文件:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: baseline
enforce-version: latest
audit: restricted
audit-version: latest
warn: restricted
warn-version: latest
exemptions:
usernames: []
runtimeClasses: []
namespaces: [kube-system]
配置完成后可以用一个故意违规的Pod做验证,比如在restricted的Namespace里提交一个root运行的容器,API Server会直接返回明确的拒绝信息,指出违反了哪条规则,这种错误提示的友好程度是当年PSP完全不具备的。
四、渐进式落地与常见坑
直接对存量集群全量开启enforce几乎必然引发故障,大量老旧镜像本身以root身份启动,改造需要时间。推荐的做法是三步走:第一步全集群默认开warn和audit模式,收集一到两周的审计数据,摸清哪些Namespace存在违规;第二步针对违规工作负载逐个改造镜像,添加securityContext配置;第三步才在业务Namespace上切换enforce,并锁定版本。
改造老旧应用时,securityContext的写法值得注意。一个符合restricted标准的示例如下:
apiVersion: v1
kind: Pod
metadata:
name: safe-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: main
image: registry.ipipp.com/apps/web:1.4
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
实际操作中还有几个坑容易踩。其一,DaemonSet和CNI插件通常需要特权,应把这类组件隔离到单独的Namespace并只应用privileged或干脆豁免;其二,如果使用AdmissionConfiguration做了全局豁免,豁免的Namespace将完全绕过检查,等于开了后门,列表必须严格管控;其三,runAsNonRoot=true配合数字UID的镜像才能通过校验,如果镜像是root用户且只在Pod层设置runAsUser,某些场景下kubelet仍可能校验失败,最稳妥的做法是在镜像构建阶段就切换到非root用户。
五、PSA的能力边界与补充方案
PSA本质上是“级别声明”而非“策略引擎”,它回答不了这些问题:某个Namespace只允许特定团队提交特权Pod、限制镜像仓库来源、强制资源配额或拓扑约束。这些需求应该交给ValidatingAdmissionPolicy或Kyverno、OPA Gatekeeper等工具,让它们与PSA形成互补——PSA负责通用基线,策略引擎负责差异化规则。
这种分层设计的好处是职责清晰:安全团队维护统一的基线标签规范,业务团队在应用交付流水线中提前自检Pod清单是否满足目标级别,CI阶段就能发现问题,而不是等到部署时被API Server拒绝。配合Flux或ArgoCD做GitOps时,还可以在CI里直接调用PSA的评估逻辑做本地校验,实现左移。
总结来看,Pod Security Admission用极低的配置成本提供了可预期的Pod安全基线,是PSP之后最务实的默认选择。正确姿势是:系统Namespace豁免、业务Namespace渐进收紧到restricted、复杂规则交给专用策略引擎,三管齐下才能构建既安全又不影响交付效率的集群环境。
Kubernetes Pod安全策略Pod Security Admission容器安全修改时间:2026-09-03 03:38:47