3. 安全上下文与Pod安全策略:Pod Security Context、Pod Security Standards、PSP迁移到OPA
3.1 安全上下文(Security Context)
安全上下文定义了Pod或容器的权限和访问控制设置。在Kubernetes中,安全上下文可以在Pod级别或容器级别进行配置,两者之间存在继承与覆盖的关系。
核心原则: 容器级别的安全上下文设置会覆盖Pod级别的设置。始终遵循最小权限原则,仅授予工作负载运行所必需的权限。
3.1.1 安全上下文配置维度
| 配置维度 | Pod级别 | 容器级别 | 典型场景 |
|---|---|---|---|
| 用户/组ID | runAsUser, runAsGroup | 同左(覆盖Pod) | 禁止以root(UID 0)运行 |
| Seccomp配置 | seccompProfile | 同左(覆盖Pod) | 限制系统调用,降低内核攻击面 |
| Capabilities | 不支持 | capabilities.add/drop | 丢弃NET_RAW,防止ARP欺骗 |
| 只读根文件系统 | 不支持 | readOnlyRootFilesystem | 防止恶意写入二进制文件 |
| 特权模式 | privileged | 同左(覆盖Pod) | 仅系统级组件(如CNI插件)使用 |
3.1.2 安全上下文配置示例
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext: # Pod级别
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginx:1.25
securityContext: # 容器级别(覆盖Pod)
runAsUser: 1001
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
常见错误: 在容器级别设置
runAsUser: 0 会覆盖Pod级别的非root设置。务必使用 securityContext.runAsNonRoot: true 作为强制校验。
3.2 Pod安全标准(Pod Security Standards)
Pod安全标准(PSS)是Kubernetes原生提供的三种安全策略基线,用于替代已废弃的PodSecurityPolicy(PSP)。PSS通过准入控制器(Pod Security Admission)在命名空间级别强制执行。
3.2.1 三种策略等级对比
| 等级 | 安全强度 | 适用场景 | 关键限制 |
|---|---|---|---|
| Privileged | 低 | 系统组件、特权DaemonSet | 无限制,允许所有权限 |
| Baseline | 中 | 通用工作负载 | 禁止特权容器、hostPID、hostNetwork;限制Capabilities |
| Restricted | 高 | 多租户、高安全环境 | 强制非root、只读根文件系统、Seccomp RuntimeDefault |
3.2.2 命名空间标签配置
# 为命名空间设置Pod安全标准
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted # 强制模式
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: baseline # 审计模式
pod-security.kubernetes.io/warn: baseline # 警告模式
迁移建议: 先使用
audit 和 warn 模式观察现有工作负载的违规情况,确认无影响后再切换到 enforce 模式。
3.3 PSP迁移到OPA/Gatekeeper
PodSecurityPolicy(PSP)自Kubernetes v1.21起被弃用,v1.25后完全移除。OPA/Gatekeeper作为策略引擎,提供了比PSP更灵活、更强大的策略管理能力。
3.3.1 迁移路径对比
| 维度 | PSP(已弃用) | OPA/Gatekeeper | Pod Security Admission |
|---|---|---|---|
| 策略语言 | YAML声明式 | Rego(图灵完备) | YAML标签 |
| 策略粒度 | 集群级别 | 命名空间/集群/资源级别 | 命名空间级别 |
| 自定义逻辑 | 不支持 | 支持复杂条件判断 | 不支持 |
| 审计与干运行 | 有限 | 支持模拟(dry-run) | 支持审计模式 |
| 性能开销 | 低 | 中(需优化Rego规则) | 低 |
3.3.2 OPA/Gatekeeper策略示例
以下Rego策略实现与PSP中 MustRunAsNonRoot 相同的功能:
# constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sMustRunAsNonRoot
metadata:
name: require-nonroot
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
parameters: {}
---
# template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8smustrunasnonroot
spec:
crd:
spec:
names:
kind: K8sMustRunAsNonRoot
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8smustrunasnonroot
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf("Container %v must set runAsNonRoot=true", [container.name])
}
3.3.3 迁移步骤清单
- 审计现有PSP: 导出所有PSP资源,记录每个PSP绑定的ServiceAccount和命名空间。
- 安装Gatekeeper: 使用Helm或Operator部署Gatekeeper v3.x。
- 转换策略: 将PSP规则逐条转换为Rego约束模板(ConstraintTemplate)。
- 灰度验证: 使用
--dry-run=server模式测试约束,确认无意外拒绝。 - 启用强制执行: 移除PSP,启用Gatekeeper约束的
enforcementAction: deny。 - 监控与优化: 通过Gatekeeper审计日志持续监控违规事件,优化Rego规则性能。
关键风险: 直接删除PSP而不先部署Gatekeeper约束,会导致集群失去安全防护。建议在迁移期间同时运行PSP和Gatekeeper,确认Gatekeeper覆盖所有PSP规则后再移除PSP。
3.4 安全上下文与策略协同架构
下图展示了安全上下文、Pod安全标准与OPA/Gatekeeper在Kubernetes集群中的协同工作流程:
3.5 最佳实践与避坑指南
- 分层防御: 同时使用Pod Security Admission(基础防护)和OPA/Gatekeeper(自定义策略),不要依赖单一机制。
- 最小Capabilities: 始终使用
drop: ["ALL"]然后按需添加,而非反向操作。 - Seccomp默认启用: 在Kubernetes v1.27+中,
RuntimeDefault已成为默认Seccomp配置,但仍建议显式声明。 - 避免特权容器: 除网络插件、存储驱动等系统组件外,禁止使用
privileged: true。 - Rego性能优化: 避免在OPA策略中使用
every和嵌套迭代,优先使用input.review.object.spec.containers[_]模式匹配。 - 审计日志监控: 启用Kubernetes审计日志和Gatekeeper审计日志,定期审查违规事件。
生产建议: 在命名空间上同时设置
pod-security.kubernetes.io/enforce: restricted 和 pod-security.kubernetes.io/warn: restricted,前者强制拦截,后者在kubectl中输出警告,帮助开发者快速定位问题。