Pod Security 准入怎么用?baseline 和 restricted 各拒绝什么?warn / audit / enforce 有什么区别?为什么 Deployment 创建成功但 Pod 起不来?给已有命名空间加标签会误杀吗?这篇在 5 个命名空间里把这些情形逐个跑出来。
普通 Pod(什么都不设):退出码 0;['pod/ok created'] privileged: true:退出码 1;['Error from server (Forbidden): error when creating "STDIN": pods "priv" is forbidden: violates PodSecurity "baseline:latest": privileged (container "c" must not set securityContext.privileged=true)'] hostNetwork: true:退出码 1;['Error from server (Forbidden): error when creating "STDIN": pods "hostnet" is forbidden: violates PodSecurity "baseline:latest": host namespaces (hostNetwork=true)'] hostPath 卷:退出码 1;['Error from server (Forbidden): error when creating "STDIN": pods "hostpath" is forbidden: violates PodSecurity "baseline:latest": hostPath volumes (volume "h")'] add NET_ADMIN:退出码 1;['Error from server (Forbidden): error when creating "STDIN": pods "caps" is forbidden: violates PodSecurity "baseline:latest": non-default capabilities (container "c" must not include "NET_ADMIN" in securityContext.capabilities.add)'] add NET_BIND_SERVICE(baseline 允许的少数能力之一):退出码 0;['pod/caps2 created']
命名空间 ps-base 带 pod-security.kubernetes.io/enforce=baseline:什么都不设的普通 Pod 通过;privileged: true 被拒(violates PodSecurity "baseline:latest": privileged (container "c" must not set securityContext.privileged=true));hostNetwork 被拒(host namespaces (hostNetwork=true));hostPath 卷被拒;add: [NET_ADMIN] 被拒(non-default capabilities);add: [NET_BIND_SERVICE] 却能通过——baseline 允许少数默认之外的能力。
普通 Pod:退出码 1
Error from server (Forbidden): error when creating "STDIN": pods "plain" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "c" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "c" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "c" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "c" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
补齐 allowPrivilegeEscalation=false / drop ALL / runAsNonRoot / seccomp RuntimeDefault:退出码 0;['pod/good created']
去掉 runAsUser(镜像是 root,但 runAsNonRoot=true 声明了):退出码 0(准入只看字段,不看镜像;运行时 kubelet 才会拒绝)enforce=restricted 下同一个普通 Pod 一次被指出 4 条:allowPrivilegeEscalation != false、unrestricted capabilities(要 drop ALL)、runAsNonRoot != true、seccompProfile(要 RuntimeDefault 或 Localhost)。补齐这 4 项后创建成功。去掉 runAsUser 但保留 runAsNonRoot: true(镜像其实是 root)也通过:准入只看字段,不看镜像,真正的拒绝要等 kubelet(CreateContainerConfigError,见上一篇)。
warn=restricted + enforce=baseline,创建普通 Pod:退出码 0;
pod/w1 created
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "c" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "c" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "c" must set securityContext.runAs
enforce=restricted 的命名空间里创建不合规的 Deployment:退出码 0;['deployment.apps/dep created', 'Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "c" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "c" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "c" must set securityContext.runAs']
Deployment 本身创建成功,但 readyReplicas=0;ReplicaSet 的 conditions:[('ReplicaFailure', 'FailedCreate', 'pods "dep-7798578f69-49jdw" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "c" must set security')]
事件:['5s Warning FailedCreate replicaset/dep-7798578f69 Error creating: pods "dep-7798578f69-xq4rv" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "c" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "c" must set securityContext.capabil']warn=restricted + enforce=baseline 的命名空间创建普通 Pod:退出码 0、pod/w1 created,同时返回 Warning: would violate PodSecurity "restricted:latest": …。在 enforce=restricted 的命名空间创建不合规的 Deployment:Deployment 本身创建成功(只带 Warning),但 readyReplicas=0,ReplicaSet 的 ReplicaFailure=FailedCreate,事件是 pods "dep-…" is forbidden: violates PodSecurity "restricted:latest"——拒绝发生在 ReplicaSet 创建 Pod 的那一刻,要去 ReplicaSet 的事件里找。
--dry-run=server 加 enforce=baseline:退出码 0;['namespace/ps-late labeled (server dry run)', 'Warning: existing pods in namespace "ps-late" violate the new PodSecurity enforce level "baseline:latest"', 'Warning: old: privileged'] 真正加上标签:退出码 0;['namespace/ps-late labeled', 'Warning: existing pods in namespace "ps-late" violate the new PodSecurity enforce level "baseline:latest"'] 已经在运行的 privileged Pod 老 old:phase=Running(不受影响,只对之后创建/更新 Pod 的请求检查) 再创建一个 privileged 的 new:退出码 1;['Error from server (Forbidden): error when creating "STDIN": pods "new" is forbidden: violates PodSecurity "baseline:latest": privileged (container "c" must not set securityContext.privileged=true)']
先在 ps-late 里创建 privileged 的 Pod old,再加 enforce=baseline:--dry-run=server 会输出 Warning: existing pods in namespace "ps-late" violate the new PodSecurity enforce level "baseline:latest" 并列出 old: privileged;真正加上标签也只给 Warning,old 仍是 Running;之后再创建 privileged 的 new 才被拒。所以推广 Pod Security 的稳妥顺序是:先 dry-run 看存量违规,再 warn / audit,最后 enforce。