Understanding Pod-Level vs Container-Level Security Settings
k8s/labs/security/security-context.yaml — Pod and container securityContext fields (users, groups, capabilities, hardening).Applied to all containers in the Pod (spec.securityContext)
Applied to specific containers (containers[].securityContext)
runAsUser), the Container-level setting always wins. This allows per-container customization while maintaining Pod-wide defaults.
| Setting | Pod-Level | Container-Level | Override Behavior |
|---|---|---|---|
runAsUser |
✓ Applies to all | ✓ Per-container | Container Overrides |
runAsGroup |
✓ Applies to all | ✓ Per-container | Container Overrides |
runAsNonRoot |
✓ Enforced on all | ✓ Per-container | Container Overrides |
fsGroup |
✓ Volume ownership | ✗ Not available | Pod-level only |
supplementalGroups |
✓ Additional GIDs | ✗ Not available | Pod-level only |
sysctls |
✓ Kernel parameters | ✗ Not available | Pod-level only |
capabilities |
✗ Not available | ✓ Add/drop caps | Container-level only |
privileged |
✗ Not available | ✓ Privileged mode | Container-level only |
allowPrivilegeEscalation |
✗ Not available | ✓ Control escalation | Container-level only |
readOnlyRootFilesystem |
✗ Not available | ✓ Read-only root | Container-level only |
seccompProfile |
✓ Pod-wide profile | ✓ Per-container | Container Overrides |
seLinuxOptions |
✓ Pod-wide SELinux | ✓ Per-container | Container Overrides |
fsGroup and capabilities are exclusive to their respective levels. You cannot set fsGroup at the container level or capabilities at the pod level.
Result: The container runs as UID 1000, GID 3000, with supplemental group 4000. Files in /data are owned by GID 2000. Privilege escalation is disabled.
Result: The "app" container runs as UID 1000 (from Pod), while "sidecar" runs as UID 2000 (override). Both share fsGroup 2000 for volumes. Each has distinct capability and privilege settings.
Key Insight: Container settings always override Pod settings for the same field. Some settings (fsGroup, sysctls) are Pod-only; others (capabilities, privileged) are Container-only.
Validation: Use kubectl exec pod-name -- id to verify user/group IDs are applied correctly.
Security Tip: Always start with drop: [ALL] and add only required capabilities. Never use privileged: true unless absolutely necessary.
runAsUser: 1000, fsGroup: 2000) that apply to all containers. Override only when specific containers need different settings.
allowPrivilegeEscalation: false at the container level unless absolutely required. This prevents processes from gaining more privileges than their parent.
runAsNonRoot: true to enforce non-root execution. Combine with runAsUser to specify a non-root UID (e.g., 1000). Kubernetes will refuse to start containers that violate this policy.
capabilities.drop: [ALL] and selectively add only required capabilities (e.g., NET_BIND_SERVICE). This reduces the attack surface significantly.
kubectl exec <pod> -- id - Check user/group IDskubectl exec <pod> -- ls -l /path - Verify file ownershipkubectl describe pod <pod> - Review applied security context