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.

Container Security: Hardening Docker and Kubernetes Environments

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: USER and runAsNonRoot: 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

ToolLayerWhat it does
TrivyImage, configScans images, filesystems, IaC and manifests; generates SBOMs
Grype + SyftImageSBOM with Syft, vulnerability scan with Grype
Cosign (Sigstore)Supply chainImage signing and verification
Kyverno / OPA GatekeeperClusterPolicy engine that blocks unsigned or root workloads
kube-benchClusterAudits against the CIS Kubernetes Benchmark
KubescapeCluster, configRisk scanning against NSA/CISA and MITRE frameworks
FalcoRuntimeSyscall-based anomaly detection
Where to start

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

  1. Develop: IDE plugins and pre-commit checks.
  2. CI: image and IaC scanning, SBOM, signing.
  3. Admission: policy engine rejects non-compliant workloads.
  4. Runtime: behaviour monitoring, central logs and alerts.
  5. 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.

  • #docker
  • #kubernetes
  • #konteyner güvenliği
  • #devsecops
  • #trivy
  • #falco

Are your systems truly secure?

Message us today for a free initial consultation. Let's assess your needs together.

Get a Quote

Related posts