Container security
A container shares the host kernel, so a breakout turns a compromised app into a compromised node. What an attacker reaches for after landing is privilege and a place to write, so the job is to take both away before they ever get there.
Method
- Build from a minimal base. Prefer distroless, alpine, or scratch over a full OS image: fewer packages mean fewer CVEs and no shell to pivot from. Scan the final image with Trivy or Grype and fail the build on fixable High or Critical findings.
- Run as a non-root user. Add a
USERdirective with a fixed non-zero uid and setrunAsNonRoot: truewith an explicitrunAsUserin the Kubernetes securityContext. A process running as uid 0 in the container is uid 0 against any kernel bug. - Mount the root filesystem read-only. Set
readOnlyRootFilesystem: trueand grant writable tmpfs or volumes only for the paths that truly need writes (/tmp, a cache dir). An attacker who cannot write cannot drop a binary to run. - Drop all Linux capabilities and add none back by default. Use
capabilities: drop: [ALL]in the securityContext. Most services need zero; add one back only with a written reason, such asNET_BIND_SERVICEfor a port below 1024. - Forbid privilege escalation and privileged mode. Set
allowPrivilegeEscalation: falseandprivileged: false, and refusehostPID,hostNetwork, andhostPathunless a specific need is reviewed. A privileged container is effectively root on the host. - Set CPU and memory limits per container. A compromised or runaway workload with no limit can starve every neighbor on the node. Unbounded resources are a denial-of-service condition waiting for a trigger.
- Keep secrets out of the image. Mount them as files from the
orchestrator's secret store, never bake them into layers or plain
environment variables. Anything
COPYed in ships to everyone who can pull the image.
Checks
- Does
docker historyor a layer scan turn up a shell, package manager, or secret in the final image? - Does the container run as non-root with a read-only root filesystem in production?
- Are all capabilities dropped, with each one added back individually justified?
Boundaries
This hardens the container and its runtime spec. Dockerfile build hygiene and layer caching belong to containerization; cluster-wide enforcement (admission controllers, Pod Security Standards, network policy) is a platform concern this skill feeds rather than owns.