Securing the New Operating System

Containers and Kubernetes have become the default way to run software, and they introduce a distinct security model. A container shares the host kernel, so a container escape is a host compromise. Kubernetes adds a control plane that, if misconfigured, can hand an attacker the entire cluster. Securing this environment spans the image, the runtime, the network, and the orchestrator.

Image Security

Everything starts with what is in the image:

  • Minimal base images: start from distroless or slim bases to reduce the attack surface and vulnerability count.
  • Scan images for known CVEs in CI (Trivy, Grype, Clair) and block builds that exceed a severity threshold.
  • Pin base images by digest, not by mutable tag, so a tampered upstream image cannot silently enter your build.
  • Sign images (Sigstore/Cosign) and verify signatures at admission time.
  • Never bake secrets into images. Anyone with the image can extract them. Layer history persists secrets even if later "deleted".
  • No latest tags in production; they are nondeterministic and undermine reproducibility.

Runtime Hardening

Containers should be locked down at runtime:

  • Run as non-root and set runAsNonRoot, a read-only root filesystem, and a non-root user in the Dockerfile.
  • Drop Linux capabilities (drop: ["ALL"], then add back only what is needed).
  • Disallow privileged containers and forbid mounting the Docker socket—both are effectively root on the host.
  • Apply seccomp and AppArmor profiles to restrict syscalls.
  • Set resource limits (CPU/memory) so a compromised pod cannot starve the node.

RBAC and the Control Plane

Kubernetes' role-based access control is the primary authorization boundary:

  • Follow least privilege: most workloads need no API access at all.
  • Never grant cluster-admin to application service accounts.
  • Audit who can create pods, read secrets, or exec into containers—these are cluster-takeover primitives.
  • Protect the API server: strong authentication, network isolation, audit logging, and no anonymous access.

Network Security

By default, Kubernetes pods can talk to each other freely. Network policies restrict east-west traffic to only the paths services actually need:

  • Default-deny ingress and egress per namespace.
  • Allow only specific service-to-service flows.
  • Encrypt in-transit traffic between services (mTLS, often via a service mesh).

This limits lateral movement dramatically: a compromised frontend cannot reach the database or the cloud metadata endpoint.

Secrets in Kubernetes

Native Kubernetes Secrets are only base64-encoded, not encrypted, unless encryption-at-rest is enabled and configured. Prefer an external secrets manager (Vault, cloud secret managers) integrated via the Secrets Store CSI driver, so secret material never lives in etcd. Restrict get/list on secrets with RBAC, since read access to secrets is often equivalent to full privilege.

Admission Control and Policy

Admission controllers are the enforcement point. Tools like OPA Gatekeeper and Kyverno reject workloads that violate policy: privileged containers, missing resource limits, unsigned images, hostPath mounts, or root users. Policies turn your security guidance from documentation into a hard gate that manifests cannot bypass.

The Hardening Checklist

Run as non-root; read-only filesystem; drop capabilities; no privileged/socket mounts; resource limits; signed, scanned, digest-pinned images; default-deny network policy; least-privilege RBAC; externalized secrets with encryption at rest; audit logging enabled; and admission policies that enforce it all. Containers are not inherently less secure than VMs—but their defaults are permissive, and security is something you must deliberately build in.