Managing Security Context
1. Setting runAsUser
securityContext:
runAsUser: 1000
| Scope | Field |
| Pod-level | spec.securityContext |
| Container-level | spec.containers[].securityContext (overrides pod) |
2. Setting runAsGroup
securityContext:
runAsGroup: 3000
supplementalGroups: [4000, 5000]
3. Setting fsGroup
| Field | Detail |
| fsGroup | chown mounted volumes recursively |
| fsGroupChangePolicy | OnRootMismatch (avoids slow recursion) |
4. Running as Non-Root
securityContext:
runAsNonRoot: true
runAsUser: 10001
Note: With runAsNonRoot: true, kubelet rejects images whose USER is 0 at start.
5. Setting Read-Only Root Filesystem
securityContext: { readOnlyRootFilesystem: true }
volumeMounts:
- { name: tmp, mountPath: /tmp }
volumes:
- { name: tmp, emptyDir: {} }
6. Adding Capabilities
| Capability | Use |
NET_BIND_SERVICE | Bind ports < 1024 |
NET_ADMIN | Network config (CNI) |
SYS_TIME | Adjust system clock |
7. Dropping Capabilities
securityContext:
capabilities:
drop: [ALL]
add: [NET_BIND_SERVICE]
Note: Required by Restricted Pod Security Standard.
8. Using Privileged Mode
Warning: privileged: true grants all capabilities + host device access — equivalent to root on host. Avoid except for CNI/CSI agents.
9. Setting SELinux Options
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
10. Configuring Seccomp Profiles
securityContext:
seccompProfile:
type: RuntimeDefault # or Localhost / Unconfined
| type | Behavior |
| RuntimeDefault | Container runtime default profile |
| Localhost | Custom profile at localhostProfile path |
| Unconfined | No filtering (avoid) |
11. Setting AppArmor Profiles
securityContext:
appArmorProfile:
type: RuntimeDefault # 1.30+ stable; replaces deprecated annotation