Container Security
Secure container workloads - minimal base images, non-root containers, Kubernetes RBAC, Pod Security Standards, network policies, and image scanning.
skill: Container Security category: DevOps tags: [Container Security, Docker, Kubernetes, RBAC, Image Scanning] readingTime: 5
Container security is defense in depth: secure the image (minimal, non-root, no secrets baked in), secure the Kubernetes configuration (RBAC, Pod Security Standards, NetworkPolicy), and monitor runtime behavior (Falco, Sysdig). Any layer alone is insufficient - attackers who break the application need to find hardened infrastructure beneath.
Workflow
- Build secure minimal Docker imagesLarge images (Ubuntu base) have more attack surface - unused packages with known CVEs. Distroless images contain only the application and runtime, nothing else.
- Scan images for vulnerabilitiesContainer images inherit vulnerabilities from base images and dependencies. Scan every image in CI and block deployment of images with critical CVEs.
- Configure Kubernetes Pod Security StandardsKubernetes Pod Security Standards restrict what pods can do - preventing privilege escalation, host namespace access, and dangerous capabilities.
- Implement RBAC and least privilegeKubernetes RBAC controls what every service account can do. Applications should not have cluster-admin - they need only the permissions to call the specific APIs they use.
- Apply NetworkPolicy for pod isolationBy default, all pods can reach all other pods in Kubernetes. NetworkPolicy implements firewall rules at the pod level - only explicitly allowed traffic is permitted.
Output Format
Container security: distroless non-root image, Trivy scanning in CI, Pod Security Standards restricted, minimal RBAC per service account, and NetworkPolicy default-deny.
Dockerfile: distroless + USER nonroot + no secrets
CI: trivy image --exit-code 1 --severity CRITICAL
Namespace: pod-security.kubernetes.io/enforce=restricted
RBAC: ServiceAccount + Role (minimal) + RoleBinding
NetworkPolicy: default-deny + explicit allow rulesExamples
Edge Cases & Gotchas
- init containers and security contexts - init containers run before app containers. If init containers need root (e.g., to set volume permissions), set runAsUser: 0 on the init container only, not the app container.
- NetworkPolicy CNI requirement - NetworkPolicy requires a CNI plugin that supports it (Calico, Cilium, Weave). The default kubenet CNI ignores NetworkPolicy - verify your cluster's CNI before relying on network policies.
- Privileged containers in monitoring - Some monitoring agents (Falco, Datadog node-agent) need privileged access to the host. Use a separate namespace with relaxed Pod Security Standards for these agents.
- Image signature verification - Sign container images with Cosign (Sigstore) and use Kubernetes admission controllers (Kyverno, OPA Gatekeeper) to reject unsigned images in production.
When to Break These Rules
- Use managed security services (AWS Security Hub, GCP Security Command Center) instead of operating Trivy/Falco yourself when your team lacks security expertise to interpret findings.
- Skip distroless images for development environments - the lack of a shell makes debugging painful. Use distroless only for production images.
Reference Files
https://kubernetes.io/docs/concepts/security/https://trivy.dev/