03
18 min read · 5 briefings

Containers & Kubernetes

Ship the app and its whole world in a box — then learn every seam in that box an attacker can pry open.

01 Images, layers, and baked-in secrets

A container image is a packaged filesystem plus metadata that runs as an isolated process on a shared kernel. Images are built in layers: each instruction in a Dockerfile (install a package, copy a file) adds a stacked, cached, read-only layer. This makes builds fast and images shareable — but it has a sharp security edge.

First, base images inherit vulnerabilities. If you build on an old ubuntu or node tag, you inherit every unpatched CVE in it. Bloated base images also mean more installed software, more attack surface, and more to patch — which is why minimal bases (distroless, Alpine, scratch) are favored for production.

Second, and more insidious, layers are forever. If you COPY a secret into an image and delete it in a later instruction, the secret still lives in the earlier layer and can be extracted by anyone who pulls the image. Credentials, private keys, and .env files baked into layers are a classic leak.

Watch out Deleting a file in a later layer does not remove it from the image — the earlier layer that added it remains. Never COPY secrets into a build; inject them at runtime and use multi-stage builds so build-time credentials never reach the final image.

02 The Docker daemon and socket

Traditional Docker runs a privileged background service, the Docker daemon (dockerd), typically as root. Everything you do with the docker CLI is a request to this daemon over a socket, usually /var/run/docker.sock. That architecture creates one of the most abused footholds in container security.

Access to the Docker socket is effectively root on the host. Anyone who can talk to it can start a new container that mounts the host's entire filesystem and runs as root — trivially escaping any notion of isolation. So mounting the socket into a container (a tempting shortcut for build agents and monitoring tools) hands that container full control of the host.

Mounting /var/run/docker.sock into a container is equivalent to giving that container root on the host. Treat it as a last resort, never a default.

This risk drove the industry toward safer designs: rootless containers, and daemonless tools like Podman that run containers as an unprivileged user without a central root daemon. Kubernetes, meanwhile, has moved off Docker entirely to lighter runtimes (containerd, CRI-O) via the Container Runtime Interface.

Pro tip Run containers as a non-root user (USER in the Dockerfile), drop Linux capabilities you do not need, and never expose the Docker socket to untrusted workloads.

03 Kubernetes architecture

Kubernetes (K8s) orchestrates containers across a fleet of machines. Understanding its anatomy is prerequisite to securing it. A cluster has two halves.

The control plane is the brain:

  • API server — the single front door; every action and component talks to it. It is the crown jewel and the primary attack target.
  • etcd — the cluster's database of all state and configuration, including, by default, its Secrets.
  • scheduler and controller manager — decide where workloads run and reconcile desired vs. actual state.

The worker nodes run your workloads. Each node runs a kubelet (the node agent that talks to the API server) and a container runtime. The unit of deployment is the pod: one or more containers that share a network namespace and can share storage.

Watch out By default, Kubernetes Secrets are only base64-encoded, not encrypted, in etcd. Enable encryption-at-rest for etcd, lock down access to it, and prefer an external secrets manager — anyone who reads etcd reads every secret.

04 RBAC, namespaces, and admission control

Kubernetes ships with strong authorization primitives, but they must be configured — clusters are not secure by default. Three controls do the heavy lifting.

RBAC (Role-Based Access Control) governs who (users, groups, and pod service accounts) can perform which verbs (get, list, create, delete) on which resources. Roles are namespaced; ClusterRoles are cluster-wide. The cardinal sin is binding cluster-admin broadly, or leaving pods with the default service-account token mounted and over-privileged — a compromised pod then inherits real cluster power.

Namespaces partition a cluster into virtual sub-clusters for organization and scoping. They are a soft boundary — useful for applying RBAC, resource quotas, and network policy per team or environment — but note that namespaces alone do not provide strong tenant isolation, since all pods still share one kernel.

Admission controllers are the policy gate: they intercept requests to the API server after authentication and authorization but before objects are persisted, and can validate or mutate them. Policy engines like OPA/Gatekeeper and Kyverno use this hook to enforce rules — reject privileged containers, require signed images, mandate resource limits, block host mounts — cluster-wide and automatically.

Pro tip Pair RBAC with network policies. By default all pods can reach all other pods; a default-deny NetworkPolicy that only allows required flows is the container-world equivalent of network segmentation.

05 Supply-chain risk and image provenance

Containers turned the software supply chain into a first-class attack surface. You are not just running your code; you are running your base image, every package it pulls, and every third-party image you deploy. A malicious or compromised link anywhere in that chain runs in your cluster.

Real-world vectors include typosquatted or backdoored public images on registries, dependency-confusion attacks, and compromised build pipelines that inject malware during the build. The defensive discipline mirrors frameworks like SLSA and the push for a Software Bill of Materials (SBOM) — knowing exactly what is inside what you ship.

The core practices:

  • Scan images for known CVEs before and after deployment (Trivy, Grype, Clair).
  • Pin by digest, not by mutable tags like latest, so you deploy the exact bytes you tested.
  • Sign and verify images with tools like Sigstore/cosign, and enforce at admission that only signed images from trusted registries can run.
  • Use trusted, minimal base images and rebuild regularly to absorb upstream patches.
Insight Image signing answers a question scanning cannot: not just "is this image known to be vulnerable?" but "is this image actually the one my pipeline built, from the source I trust?" Provenance is the backbone of a defensible supply chain.

Field Glossary

Container image layers
The stacked, cached, read-only filesystem layers that make up an image. Because earlier layers persist, a secret copied in and later deleted remains extractable from the image.
Docker socket
The endpoint (/var/run/docker.sock) through which the CLI commands the root Docker daemon. Access to it is effectively root on the host, making it a dangerous thing to expose to containers.
Kubernetes control plane
The cluster's management components — API server, etcd, scheduler, controller manager. The API server is the single front door and etcd holds all state, including secrets.
Pod
Kubernetes' smallest deployable unit: one or more containers that share a network namespace and can share storage, scheduled together onto a node.
RBAC
Role-Based Access Control — Kubernetes authorization mapping subjects (users, groups, service accounts) to verbs on resources via Roles/ClusterRoles and bindings.
Admission controller
A hook that intercepts API requests after authentication/authorization but before persistence, able to validate or mutate objects; policy engines like OPA/Gatekeeper and Kyverno enforce rules here.
Image provenance / signing
Cryptographically attesting and verifying that an image is the exact artifact built from trusted source (e.g., Sigstore/cosign), a core defense against supply-chain tampering.

Knowledge Check

Field Assessment

0 / 3

01 You COPY an API key into a Docker image, then delete the file in a later Dockerfile instruction. Is the key safe?

02 Why is mounting /var/run/docker.sock into a container considered so dangerous?

03 By default, how are Kubernetes Secrets stored in etcd?

ESC
↑↓ navigate jack in