深色模式
SecurityContext 安全上下文
摘要:本文面向需要为容器设置最小权限、阻止容器逃逸的 SRE / 应用工程师。覆盖 Pod 级与 Container 级安全上下文字段、默认值陷阱、与 PSA
restricted的映射,以及 supplementalGroupsPolicy 等新特性。适用版本:Kubernetes v1.28+(部分字段 v1.33 Beta)。
适用版本与前提
- Kubernetes:v1.28+(基础字段 GA;
supplementalGroupsPolicyBeta v1.33) - 需理解 Linux UID/GID、capabilities、seccomp 基本概念
- 与 Pod Security Admission 配合强制基线
Pod 级 vs Container 级
securityContext 可同时出现在 Pod spec 和 Container spec。Pod 级设置对整个 Pod 所有容器生效;Container 级可覆盖。二者字段集合不同:
- Pod 级(
PodSecurityContext):runAsUser、runAsGroup、fsGroup、supplementalGroups、fsGroupChangePolicy、seLinuxOptions、supplementalGroupsPolicy等。 - Container 级(
SecurityContext):runAsUser、runAsNonRoot、privileged、capabilities、allowPrivilegeEscalation、readOnlyRootFilesystem、seccompProfile等。
字段不可跨级混用
例如 readOnlyRootFilesystem 只能在 Container 级设置,不能放 Pod 级;fsGroup 只能放 Pod 级。写错位置会导致 apply 失败(unknown field)。
关键字段逐一拆解
runAsUser / runAsGroup / runAsNonRoot
yaml
securityContext:
runAsUser: 1000
runAsGroup: 3000
runAsNonRoot: true1
2
3
4
2
3
4
runAsNonRoot: true要求 UID 非 0;若镜像以 root 运行则 Pod 被拒(配合 PSA restricted 必需)。- 若省略
runAsGroup,进程主组为 root(0),可访问 root 组文件——这是安全隐含风险。
allowPrivilegeEscalation
默认值陷阱
官方文档明确:allowPrivilegeEscalation 若未显式设置,默认为 true。它直接控制 no_new_privs 标志(值取反)。为禁用 setuid 提权,必须显式设为 false。注意:allowPrivilegeEscalation: false 与 privileged: true 或 CAP_SYS_ADMIN 互斥,不能同时设置。
capabilities:默认集合与最小化
容器默认获得一组 Linux capabilities(如 CHOWN、NET_RAW、DAC_OVERRIDE 等)。生产建议显式 drop 全部再按需 add:
yaml
securityContext:
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]1
2
3
4
2
3
4
NET_RAW 常被 drop 以禁止原始套接字(缓解 spoofing/scanning)。NET_BIND_SERVICE 允许绑定 1024 以下端口。
readOnlyRootFilesystem
readOnlyRootFilesystem: true 把根文件系统挂只读,极大增加篡改难度。需配合 emptyDir 或 volume 供临时写。PSA restricted 要求此字段为 true。
seccompProfile
seccomp 过滤进程系统调用。type 可取 RuntimeDefault(运行时默认 profile,推荐)、Unconfined、Localhost。
yaml
securityContext:
seccompProfile:
type: RuntimeDefault1
2
3
2
3
PSA restricted 要求 seccompProfile.type 为 RuntimeDefault 或 Localhost。
完整生产示例(满足 restricted)
yaml
apiVersion: v1
kind: Pod
metadata:
name: hardened
namespace: prod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginx:1.27
securityContext:
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
该配置满足 PSA restricted:runAsNonRoot、allowPrivilegeEscalation:false、privileged:false、capabilities drop ALL、seccompProfile RuntimeDefault、readOnlyRootFilesystem:true。
supplementalGroupsPolicy(v1.33 Beta)
默认 kubelet 会把容器内 /etc/group 里主用户的组成员合并进容器进程附加组,可能导致意外权限(社区 issue kubernetes/kubernetes#112879)。supplementalGroupsPolicy: Strict 只取 fsGroup/supplementalGroups/runAsGroup 中声明的组,不合并 /etc/group。
版本相关
SupplementalGroupsPolicy 为 Beta(v1.33 默认开启),需 kubelet 与 kube-apiserver 同时开启 feature gate。低于 v1.33 不生效,落地前请确认目标版本。[未实测:Strict 模式的交互需在生产前验证]
故障排查
| 现象 | 原因 | 处置 |
|---|---|---|
Pod 被 PSA 拒:must not set securityContext.privileged=true | 用了特权容器 | 去掉 privileged 或改用具体 capability |
container has runAsNonRoot and image has non-numeric user | 镜像 USER 为非数字名 | 镜像内建数字 UID 或显式 runAsUser |
| 应用写文件失败 | readOnlyRootFilesystem + 无可写卷 | 挂载 emptyDir 供写 |
capabilities add SYS_ADMIN 被拒 | 与 allowPrivilegeEscalation:false 冲突 | 重新审视是否真需要,或调整策略 |
回滚与清理
灰度策略
先在命名空间用 PSA warn/audit 收集哪些 workload 不符合 restricted,再逐个修复 SecurityContext,最后切 enforce。不要一次性对存量集群全量 enforce=restricted,会大面积拒绝创建。
参考资料
- Kubernetes 官方文档 - Configure a Security Context for a Pod or Container,访问日期:2026-10-08。
- Kubernetes 官方文档 - Pod Security Standards,访问日期:2026-10-08。
- Kubernetes API 参考 - SecurityContext,访问日期:2026-10-08。
- Linux Capabilities 说明(kernel),访问日期:2026-10-08。