Kubernetes PodSecurityPolicy 完全指南:Pod 安全准入控制核心
一、PodSecurityPolicy(PSP)核心定义
PodSecurityPolicy(PSP)是 Kubernetes 中的集群级安全资源,用于控制 Pod 的运行行为和访问权限。其核心作用是:
定义 Pod 必须满足的安全条件,确保 Pod 按系统可接受的安全标准运行;
通过准入控制机制,拒绝不符合安全策略的 Pod 创建请求;
间接影响 Pod 和容器的
SecurityContext配置,强化集群安全边界。
注意:PSP 是集群级资源,而非命名空间级,一旦启用,将对全集群的 Pod 创建生效。
二、PSP 核心控制维度
PSP 覆盖 Pod 安全的关键领域,通过下表中的字段精准控制 Pod 权限:
| 控制方向 | 对应字段 / 说明 |
|---|---|
| 容器特权模式 | priv``ileged(布尔值,控制是否允许特权容器) |
| 容器能力管理 | defaultAddCapabilities(默认添加的能力)、requiredDropCapabilities(必须移除的能力)、allowedCapabilities(允许请求的能力) |
| 卷类型限制 | volumes(白名单机制,指定允许使用的卷类型,如secret、emptyDir等) |
| 主机资源访问 | hostNetwork(主机网络)、hostPorts(主机端口范围)、hostPID(主机 PID 命名空间)、hostIPC(主机 IPC 命名空间) |
| 主机路径访问 | allowedHostPaths(允许的主机路径前缀白名单) |
| 安全上下文配置 | seLinux(SELinux 上下文)、runAsUser(运行用户 ID)、supplementalGroups(补充组)、fsGroup(数据卷权限组) |
| 根文件系统权限 | readOnlyRootFilesystem(是否强制只读根文件系统) |
三、PSP 策略规则类型
PSP 的控制规则分为三类,适配不同安全需求:
布尔型控制:默认取最严格值(如
privileged: false禁止特权容器);允许值集合控制:仅允许指定范围内的值(如
hostPorts: [{min:8000, max:8080}]限制主机端口);策略型控制:通过规则生成或验证值,确保符合安全要求(核心应用于用户 ID、SELinux 等字段)。
核心策略型控制字段详解
| 字段 | 支持的策略规则 |
|---|---|
runAsUser | -MustRunAs:必须使用指定 ID 范围,默认取第一个值;MustRunAsNonRoot:禁止root用户(runAsUser≠0或镜像指定USER);>-RunAsAny`:允许任意用户 ID |
seLinux | -MustRunAs:必须使用指定 SELinux 上下文;>-RunAsAny:允许任意 SELinux 配置 |
supplementalGroups | -MustRunAs:必须使用指定组 ID 范围;-RunAsAny:允许任意补充组 |
fsGroup | -MustRunAs:必须使用指定数据卷权限组范围;RunAsAny`:允许任意组 |
四、常用卷类型白名单推荐
新创建 PSP 时,推荐允许的最小卷类型集合(兼顾安全与实用性):
configMap、downwardAPI、emptyDir、persistentVolumeClaim、secret、projected
如需允许所有卷类型,可配置volumes: ["*"](生产环境不推荐)。
五、PSP 工作流程(许可机制)
PSP 通过准入控制实现 Pod 安全校验,流程如下:
当用户创建 Pod 时,Kubernetes 检索所有可用的 PSP 资源;
对 Pod 未指定的安全上下文字段,按 PSP 规则生成默认值;
验证 Pod 的最终安全配置是否符合至少一个 PSP 的规则;
符合规则则允许 Pod 创建,否则拒绝(返回校验失败信息)。
六、PSP 实操命令(核心操作)
1. 创建 PSP
示例:创建一个允许所有配置的宽松策略(仅用于测试)
# psp-permissive.yaml apiVersion: extensions/v1beta1 kind: PodSecurityPolicy metadata: name: permissive spec: seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny hostPorts: \- min: 8000 max: 8080 volumes: \- '\*' # 允许所有卷类型执行创建命令:
kubectl create -f psp-permissive.yaml2. 查看 PSP 列表
kubectl get psp # 输出示例(PRIV=是否允许特权容器,VOLUMES=允许的卷类型) NAME PRIV CAPS SELINUX RUNASUSER FSGROUP VOLUMES permissive false \[] RunAsAny RunAsAny RunAsAny \[\*] restricted false \[] RunAsAny MustRunAsNonRoot RunAsAny \[emptyDir secret downwardAPI configMap persistentVolumeClaim projected]3. 编辑 PSP
kubectl edit psp permissive # 进入编辑器修改策略(如添加 requiredDropCapabilities: \["NET\_RAW"] 移除网络原始能力)4. 删除 PSP
kubectl delete psp permissive七、启用 PSP 的前提条件
要在集群中使用 PSP,必须完成以下配置:
启用 API 类型:Kubernetes 1.6 及以上版本默认启用
extensions/v1beta1/podsecuritypolicy(1.6 前需手动启用);启用准入控制器:在 API Server 启动参数中添加
--enable-admission-plugins=PodSecurityPolicy(关键步骤,否则 PSP 不生效);定义 PSP 策略:创建符合业务需求的 PSP 资源(如严格策略、宽松策略);
配置 RBAC 权限:通过 Role/ClusterRole 授权用户 / 服务账户使用 PSP(例如:允许
default服务账户使用restricted策略)。
注意:如果使用 Deployment、ReplicaSet 等控制器创建 Pod,需确保 Controller Manager 基于安全 API 端口运行,且无超级用户权限,否则无法实现细粒度权限控制。
八、核心安全最佳实践
遵循最小权限原则:禁止不必要的特权(
privileged: false)、移除危险能力(如NET_RAW)、限制主机资源访问;强制非 root 用户:配置
runAsUser: {rule: MustRunAsNonRoot},避免 Pod 以 root 身份运行;严格限制卷类型:仅允许必需的卷类型,禁止
hostPath(或仅允许特定路径);启用只读根文件系统:对无写入需求的容器设置
readOnlyRootFilesystem: true;细粒度 RBAC 授权:不同用户 / 服务账户分配不同 PSP 权限(如开发环境用宽松策略,生产环境用严格策略)。