Scope
Not a separate resource: fields on Pod/Deployment template.
Pod level vs container level
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
runAsNonRoot: true
fsGroup: 2000
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
Key fields
seccompProfile
securityContext:
seccompProfile:
type: RuntimeDefault
RuntimeDefault: required for restricted PSSUnconfined: blocked by restricted PSS
Pod Security Standards (PSS)
Namespace-level policy via Pod Security admission (replaced PodSecurityPolicy in 1.25).
Restricted-compliant container
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: bitnami/nginx:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache/nginx
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
kubectl get ns production --show-labels | grep pod-security
Exam gotchas
- Hardening pattern:
runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities.drop: [ALL] runAsNonRoot: true + nginx image → CreateContainerConfigError (runs as root); use bitnami/nginx or set runAsUser- Container-level wins over pod-level for same attribute
violates PodSecurity "restricted" → add seccompProfile: RuntimeDefault and drop capabilitiesprivileged: true fails on baseline and restricted namespaces