Container Security: Hardening Docker and Kubernetes Environments
Containers speed you up, but left on defaults they speed attackers up too. We cover hardening across four layers, from image to runtime, and compare the open source tools for each.
Containers package an app with its dependencies so it runs the same everywhere, and Kubernetes has become the standard for running them at scale. But on default settings, speed builds security debt: containers running as root, base images with hundreds of known vulnerabilities, pods talking to each other freely.
Four layers make the work clear: image, configuration, cluster and runtime.
Layer 1: Image security
Use minimal base images
Every package is a potential vulnerability. Prefer alpine, distroless or slim variants, and use multi-stage builds so build tools never reach the final image.
# Multi-stage build: no build tools in the final image
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/api
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]
Scan images
# Fail CI on critical or high vulnerabilities
trivy image --severity CRITICAL,HIGH --exit-code 1 company/api:1.4.2
Scan in CI and periodically in the registry for newly published vulnerabilities.
Sign images
Signing with Sigstore cosign and admitting only signed images is a strong defence against supply chain attacks.
Layer 2: Container configuration
- Don't run as root:
USERandrunAsNonRoot: true. - Read-only root filesystem, with volumes where writes are needed.
- Drop all capabilities and add back only what's needed.
allowPrivilegeEscalation: false.- Never
privileged: true; it's effectively root on the host. - Set resource limits.
apiVersion: v1
kind: Pod
metadata:
name: api
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: company/api:1.4.2@sha256:...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits: { cpu: "500m", memory: "256Mi" }
Layer 3: Cluster security
Pod Security Standards
Pod Security Admission offers privileged, baseline and restricted profiles per namespace. Aim for restricted in application namespaces.
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted
Least privilege with RBAC
Reserve cluster-admin; scope service accounts tightly; set automountServiceAccountToken: false where the API isn't needed.
Network policies
By default every pod can reach every pod. Apply default-deny and allow only required traffic to limit lateral movement.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: production
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
Secrets
Kubernetes Secrets are only base64-encoded by default. Enable encryption at rest in etcd or use an external vault with External Secrets Operator.
Layer 4: Runtime security
A shell suddenly spawning in a web container, or /etc/shadow being read, almost always signals an attack. Tools like Falco watch kernel syscalls and raise rule-based alerts.
Open source tool comparison
| Tool | Layer | What it does |
|---|---|---|
| Trivy | Image, config | Scans images, filesystems, IaC and manifests; generates SBOMs |
| Grype + Syft | Image | SBOM with Syft, vulnerability scan with Grype |
| Cosign (Sigstore) | Supply chain | Image signing and verification |
| Kyverno / OPA Gatekeeper | Cluster | Policy engine that blocks unsigned or root workloads |
| kube-bench | Cluster | Audits against the CIS Kubernetes Benchmark |
| Kubescape | Cluster, config | Risk scanning against NSA/CISA and MITRE frameworks |
| Falco | Runtime | Syscall-based anomaly detection |
Small team? Add Trivy to CI, enforce restricted Pod Security in app namespaces and write a default-deny network policy. Those three steps cut most of the risk within days.
Container security in a DevSecOps flow
- Develop: IDE plugins and pre-commit checks.
- CI: image and IaC scanning, SBOM, signing.
- Admission: policy engine rejects non-compliant workloads.
- Runtime: behaviour monitoring, central logs and alerts.
- Continuous: periodic rescans of registry images.
Conclusion
No single tool solves container security; each layer catches what the last missed. Most tools are open source and slot into CI/CD easily. For a Kubernetes security review or DevSecOps setup, see our software and cyber security services.
Are your systems truly secure?
Message us today for a free initial consultation. Let's assess your needs together.