3、Pod安全策略(PSP)基础:PodSecurityPolicy资源定义、策略模式(Privileged、Baseline、Restricted)、初始策略组配置
3.1 PodSecurityPolicy 概述与资源定义
PodSecurityPolicy(PSP)是 Kubernetes 中一种集群级别的安全资源,用于控制 Pod 在安全敏感维度上的行为规范。PSP 通过准入控制器(PodSecurityPolicy Admission Controller)在 Pod 创建或更新时进行校验,确保 Pod 的 SecurityContext 与预设策略匹配。
关键概念:PSP 并非直接修改 Pod 的配置,而是作为准入控制器拒绝不符合策略的 Pod 请求。在 Kubernetes v1.21 中已被弃用,并在 v1.25 中移除,但其安全设计理念对后续的 Pod Security Standards(PSS)和 Pod Security Admission(PSA)影响深远。
一个标准的 PodSecurityPolicy 资源定义包含以下核心字段:
| 字段路径 | 作用域 | 说明 |
|---|---|---|
privileged |
容器 | 是否允许运行特权容器 |
hostPID / hostIPC / hostNetwork |
Pod | 是否允许使用主机命名空间 |
allowedHostPaths |
卷 | 允许挂载的主机路径白名单 |
runAsUser / runAsGroup / supplementalGroups |
安全上下文 | 用户/组 ID 策略(MustRunAs、MustRunAsNonRoot 等) |
seLinux |
安全上下文 | SELinux 上下文策略 |
fsGroup |
卷 | 卷的 fsGroup 策略 |
readOnlyRootFilesystem |
容器 | 是否强制只读根文件系统 |
allowedCapabilities / defaultAddCapabilities / requiredDropCapabilities |
容器 | Linux Capabilities 控制 |
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted-psp
spec:
privileged: false
seLinux:
rule: RunAsAny
runAsUser:
rule: MustRunAsNonRoot
runAsGroup:
rule: MustRunAs
ranges:
- min: 1000
max: 65535
fsGroup:
rule: MustRunAs
ranges:
- min: 1000
max: 65535
supplementalGroups:
rule: MustRunAs
ranges:
- min: 1000
max: 65535
readOnlyRootFilesystem: true
requiredDropCapabilities:
- ALL
allowPrivilegeEscalation: false
volumes:
- configMap
- emptyDir
- projected
- secret
- downwardAPI
- persistentVolumeClaim
3.2 策略模式:Privileged、Baseline、Restricted
Kubernetes 官方将 Pod 安全策略归纳为三种标准模式,覆盖从宽松到严格的安全等级。这三种模式构成了 Pod Security Standards(PSS)的核心框架。
| 策略模式 | 安全等级 | 适用场景 | 关键限制 |
|---|---|---|---|
| Privileged | 最低 | 系统级组件、监控代理、网络插件 | 无限制,允许特权容器、主机命名空间、任意 Capabilities |
| Baseline | 中等 | 大多数通用工作负载 | 禁止特权容器、禁止 hostPID/hostIPC、禁止 NET_RAW Capability、限制主机端口 |
| Restricted | 最高 | 多租户环境、金融/医疗合规场景 | 强制非 root 用户、只读根文件系统、禁止特权提升、仅允许必要卷类型 |
策略模式对比要点:
- Privileged 模式通常只授予集群基础设施组件,如
kube-proxy、calico-node、ingress-nginx。 - Baseline 模式是生产环境的默认起点,平衡安全性与兼容性。
- Restricted 模式要求应用必须遵循“最小权限”原则,通常需要改造镜像以支持非 root 运行。
3.3 初始策略组配置
在集群中启用 PSP 需要完成以下步骤:准入控制器启用、策略资源创建、RBAC 授权、默认策略绑定。初始策略组通常采用“默认拒绝 + 白名单”模式。
3.3.1 启用 PodSecurityPolicy 准入控制器
# 在 kube-apiserver 启动参数中添加
--enable-admission-plugins=NodeRestriction,PodSecurityPolicy
# 或修改 /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --enable-admission-plugins=NodeRestriction,PodSecurityPolicy
重要提示:启用 PSP 准入控制器后,如果集群中没有创建任何 PSP 资源且未绑定 ServiceAccount,所有 Pod 创建请求都将被拒绝。建议先创建策略并授权,再启用准入控制器。
3.3.2 初始策略组推荐配置
初始策略组应包含三个层级的策略,并通过 RBAC 绑定到不同的主体:
| 策略名称 | 模式 | 绑定主体 | 说明 |
|---|---|---|---|
privileged-psp |
Privileged | 系统组件 ServiceAccount(kube-system) | 仅限集群基础设施使用 |
baseline-psp |
Baseline | 默认 ServiceAccount(default) | 通用工作负载默认策略 |
restricted-psp |
Restricted | 特定命名空间 ServiceAccount | 高安全需求工作负载 |
# 创建 ClusterRole 允许使用特定 PSP
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: psp-restricted
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
resourceNames: ['restricted-psp']
verbs: ['use']
---
# 绑定到特定命名空间的 ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: psp-restricted-binding
namespace: production
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: psp-restricted
subjects:
- kind: ServiceAccount
name: default
namespace: production
3.3.3 策略组配置流程
- 评估现有工作负载:使用
kubectl auth can-i或 PSP 审计工具检查当前 Pod 的安全上下文。 - 创建 Baseline 策略:作为默认策略,覆盖 80% 以上的工作负载。
- 创建 Privileged 策略:仅授予 kube-system 和特定系统组件。
- 创建 Restricted 策略:针对需要合规审计的命名空间。
- 配置 RBAC 绑定:使用 ClusterRole + RoleBinding 实现细粒度授权。
- 启用准入控制器:在确认策略和授权无误后启用。
- 监控与审计:通过 API Server 审计日志捕获被拒绝的 Pod 创建请求。
3.4 策略生效验证与排错
配置完成后,使用以下方法验证 PSP 是否按预期生效:
# 验证策略是否存在
kubectl get psp
# 测试 Pod 创建是否被允许
kubectl create deployment nginx --image=nginx --replicas=1
# 查看被拒绝的请求(API Server 审计日志)
kubectl logs -n kube-system kube-apiserver-<node> | grep "PodSecurityPolicy"
# 使用 kubectl auth can-i 验证 ServiceAccount 权限
kubectl auth can-i use podsecuritypolicy/restricted-psp \
--as system:serviceaccount:production:default
排错建议:如果 Pod 创建被拒绝,检查以下常见原因:
1. PSP 资源未创建或名称拼写错误。
2. ServiceAccount 未绑定到正确的 ClusterRole。
3. Pod 的 SecurityContext 与 PSP 规则冲突(如容器要求特权但 PSP 禁止)。
4. 多个 PSP 同时匹配时,Kubernetes 会选择最宽松的策略。
1. PSP 资源未创建或名称拼写错误。
2. ServiceAccount 未绑定到正确的 ClusterRole。
3. Pod 的 SecurityContext 与 PSP 规则冲突(如容器要求特权但 PSP 禁止)。
4. 多个 PSP 同时匹配时,Kubernetes 会选择最宽松的策略。