- Containers are not a security boundary. A compromised container can attack the host kernel and other containers if misconfigured.
- Image scanning in the CI/CD pipeline is the first line of defense. Use only trusted base images and scan every image for vulnerabilities before deployment.
- Containers should never run as root. Use non-root users, read-only filesystems, and security contexts to minimize the attack surface.
- Kubernetes network policies are the container equivalent of network segmentation. Without them, every pod can communicate with every other pod.
- Secrets do not belong in container images or environment variables. Use Kubernetes Secrets (encrypted) or external vault systems (HashiCorp Vault, AWS Secrets Manager).
Containers and Security: The Fundamentals
Containers have fundamentally changed software development and IT operations. Applications are packaged into standardized, portable units that run identically everywhere: on the developer's laptop, in the CI/CD system, and in production. Docker popularized the technology, and Kubernetes standardized orchestration at a higher level.
What often gets overlooked amid the enthusiasm for the benefits (portability, scalability, reproducibility) is that containers bring their own security risks that differ from traditional server deployments. A container is not a VM. It shares the kernel with the host system and other containers. The isolation is a software abstraction (namespaces, cgroups), not a hardware boundary.
This does not mean containers are insecure. It means you need to understand and address the specific risks.
The Attack Surface of Containers
The container attack surface can be divided into several layers.
Container Image
The image is the foundation. It contains the operating system, the runtime environment, and the application. If the base image contains vulnerable software versions, every container created from it inherits those vulnerabilities. If confidential data (API keys, passwords, SSH keys) is included in the image, anyone with access to the image can extract that data. A well-designed secrets management approach prevents this problem from the start.
Common issues: Outdated base images (e.g., ubuntu:20.04 with unpatched vulnerabilities), unnecessary packages in the image (build tools, compilers, debug utilities that are not needed in production), secrets in image layers (even if you delete a file in a later layer, it remains in previous layers and is extractable).
Container Runtime
The runtime (Docker Engine, containerd, CRI-O) is the software layer that starts and manages containers. A vulnerability in the runtime can lead to a container escape — breaking out of the container onto the host system. Container escapes are rare, but when they occur, they have catastrophic consequences because the attacker suddenly has root access to the host.
Common issues: Docker socket mounted (-v /var/run/docker.sock:/var/run/docker.sock), which gives the container full access to the Docker API and thus to all other containers and the host. Privileged containers (--privileged), which effectively disable all security mechanisms. Outdated runtime versions with known vulnerabilities.
Container Orchestration (Kubernetes)
Kubernetes adds another layer of complexity. The API server, etcd (the Kubernetes database), Kubelet, and various controllers all present attack surfaces. The default configuration of Kubernetes is designed for usability, not security.
Common issues: Unprotected API server (no authentication or overly broad RBAC permissions), no NetworkPolicy (every pod can communicate with every other pod in the cluster), secrets stored unencrypted in etcd (by default, Kubernetes Secrets are only Base64-encoded, not encrypted), oversized service accounts with cluster-admin privileges.
Supply Chain
Container images are pulled from public registries (Docker Hub, GitHub Container Registry). If an image in the registry is compromised, all dependent images inherit the malware. Supply chain attacks on container images are a growing problem.
Securing Docker: The Key Measures
Use Secure Base Images
Use minimal base images. Instead of ubuntu:22.04 (77 MB, hundreds of packages), use ubuntu:22.04-minimal or, better yet, distroless images from Google (only the runtime environment, no shell, no package manager) or Alpine-based images (5 MB, minimal package selection).
The less software contained in the image, the smaller the attack surface. A container that has no shell cannot be exploited by an attacker for an interactive session.
Always use specific image tags (e.g., node:20.11.1-alpine) and never latest. The latest tag can change at any time, and you won't know which version you have in production.
Multi-Stage Builds
Multi-stage builds separate the build environment from the runtime environment. In the first stage, you compile the code with all necessary build tools. In the second stage, you copy only the finished artifact into a minimal runtime image. The build tools, source code, and all intermediate products remain in the build stage and are not included in the final image.
This significantly reduces the image size and eliminates an entire class of security risks: an attacker who penetrates the container will find no compilers, no build tools, and no source code.
Never Run Containers as Root
By default, processes in Docker containers run as root (UID 0). If an attacker escapes the container process, they may also be root on the host (depending on user namespace configuration).
Create a dedicated user in your Dockerfile and switch to that user with the USER directive. Example: RUN addgroup --system app && adduser --system --ingroup app app followed by USER app. Test whether the application works as a non-root user. Sometimes applications bind to privileged ports (below 1024) or write to directories that require root privileges. In those cases, adjust the application configuration (change the port, modify the write directory).
Read-Only Filesystem
Set the container filesystem to read-only (docker run --read-only). This prevents an attacker from modifying files in the container or downloading and executing malware. If the application needs to write temporary files, mount a tmpfs volume for the required directory.
Image Scanning
Scan every container image for known vulnerabilities before deployment. The most common tools are Trivy (open source, by Aqua Security, very fast, supports OS packages and language packages), Grype (open source, by Anchore, good integration with Syft for SBOM generation), and Snyk Container (commercial, good IDE integration, prioritizes vulnerabilities by reachability).
Integrate scanning into your CI/CD pipeline as part of the Secure Development Lifecycle. Define a policy: e.g., "no deployment if critical or high vulnerabilities are found in the image." Scan not only at build time but also regularly scan running images, because new vulnerabilities can be discovered at any time.
Never Mount the Docker Socket
Mounting the Docker socket into a container is a common anti-pattern used for CI/CD runners (Jenkins, GitLab Runner) or monitoring tools. It gives the container full control over the Docker engine and thus over all other containers and the host.
Use rootless Docker, kaniko (for container builds in the CI/CD pipeline without Docker socket), or podman (daemonless, no central socket) instead.
Securing Kubernetes: The Key Measures
Configure RBAC Properly
Kubernetes Role-Based Access Control (RBAC) controls who can do what in the cluster. The most common mistakes are overly broad ClusterRoles (e.g., cluster-admin for a service account that only needs to read pods in a namespace), default service accounts with too many permissions, and missing namespace isolation (workloads from different teams or environments in the same namespace).
Create a dedicated service account with minimal permissions for each application. Use Roles (namespace-scoped) instead of ClusterRoles where possible. Disable automatic mounting of the service account token if the application does not need access to the Kubernetes API: automountServiceAccountToken: false.
Network Policies
Without network policies, every pod in the Kubernetes cluster can communicate with every other pod. This is the equivalent of a flat network without segmentation: if a pod is compromised, the attacker can attack all other pods in the cluster.
Network policies define which traffic between pods is allowed — the container counterpart to network segmentation. Start with a default-deny policy for each namespace (blocks all incoming traffic) and then selectively open the required connections.
Example: Your frontend pod may only communicate with the backend pod on port 8080. The backend pod may only communicate with the database pod on port 5432. The database pod may not be accessed by anyone except the backend pod.
Network policies require a CNI plugin that supports them (e.g., Calico, Cilium, Weave Net). The default CNI in many managed Kubernetes services (e.g., AWS VPC CNI without Calico addon) does not support network policies.
Pod Security Standards
Kubernetes Pod Security Standards (PSS) define three security levels for pods.
Privileged: No restrictions. For system components and infrastructure workloads.
Baseline: Prevents the most obvious security risks. Blocks privileged containers, host namespace access, and dangerous capabilities. Suitable for most applications.
Restricted: Strict security requirements. Non-root, read-only root filesystem, no additional capabilities, seccomp profiles. Suitable for security-critical applications.
Configure Pod Security Standards at the namespace level. For production namespaces, you should use at least "Baseline," preferably "Restricted."
Manage Secrets Securely
Kubernetes Secrets are stored only Base64-encoded and unencrypted in etcd by default. Anyone with read access to etcd can read all secrets in plaintext.
Enable encryption at rest for etcd. This encrypts secrets before they are written to etcd. Better yet: use an external secrets store (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) and the External Secrets Operator or Secrets Store CSI Driver to inject secrets into pods at runtime.
Secrets should be mounted as volumes, not set as environment variables. Environment variables appear in process listings, crash dumps, and logs.
Admission Controllers
Kubernetes admission controllers inspect requests to the API server before they are executed. With policy engines like OPA Gatekeeper or Kyverno, you can enforce security rules.
Examples of useful policies: No container may run as root. No container may have privileged capabilities. All images must come from an approved registry. All images must be signed. Every deployment must have resource limits.
Secure CI/CD Pipeline for Containers
The CI/CD pipeline is the path from source code to running container. If the pipeline is compromised, an attacker can inject malicious code into every deployment.
Pipeline Security Measures
Image scanning as a quality gate: Integrate Trivy or Grype as a step in the pipeline. If critical vulnerabilities are found, the build aborts.
Image signing: Sign container images with Cosign (from Sigstore) or Notary. Kubernetes admission controllers can then verify whether an image has a valid signature before it is deployed.
SBOM generation: Create a Software Bill of Materials (SBOM) for every image using tools like Syft. The SBOM documents which software components are contained in the image and is the foundation for vulnerability tracking.
Least privilege for pipeline access: The CI/CD runner needs access to the container registry (push) and the Kubernetes cluster (deploy). Restrict permissions to the absolute minimum: push access only to specific repositories, deployment access only to specific namespaces.
Monitoring and Runtime Protection
Containers run, containers die, new containers start. This dynamic behavior makes traditional monitoring and security oversight challenging.
Runtime Security
Tools like Falco (open source, CNCF project) monitor the behavior of running containers in real time and detect suspicious activities such as unexpected shell invocations in containers, access to sensitive files (/etc/shadow, /etc/passwd), outbound network connections to unknown destinations, or the launch of unexpected processes.
Falco defines rules that describe normal behavior. Any deviation is reported as an alert. For containers that should have no shell (e.g., a Node.js application container), any shell invocation is a strong indicator of compromise.
Logging and Audit
Centralize container logs with a log aggregator (e.g., Fluentd, Loki, Elasticsearch). Container logs are ephemeral and are lost when the container terminates. Without centralized collection, you have no way to analyze an incident after the fact.
Enable Kubernetes audit logging as part of your logging and monitoring strategy. It records all API calls to the Kubernetes API server and is indispensable for forensics after a security incident.
Container Security for SMEs: A Pragmatic Start
Not every mid-market company needs a full container security program with service mesh, RBAC automation, and runtime security. If you are just getting started with containers or running a small cluster, start with the basics.
Week 1: Introduce Trivy as an image scanner in your CI/CD pipeline. Fix critical and high vulnerabilities in your images.
Week 2: Ensure that no container runs as root. Adjust Dockerfiles and Kubernetes manifests.
Week 3: Implement network policies with default-deny in your production namespaces. Selectively open the required connections.
Week 4: Enable encryption at rest for etcd and migrate secrets from environment variables to mounted Kubernetes Secrets.
These four measures address the most common and critical container security risks and can be implemented within one month.
Container Security and Regulatory Requirements
Containers are not a special regulatory topic. They fall under the general requirements for secure development and operation of IT systems.
NIS2 Article 21 requires security measures in the acquisition, development, and maintenance of network and information systems. Container images, Kubernetes clusters, and CI/CD pipelines are components of these systems. ISO 27001 Annex A, Control A.8.25 (Secure development lifecycle), also applies to containerized applications. Control A.8.9 (Configuration management) requires that the configuration of software and services is documented and controlled, which includes Dockerfiles, Kubernetes manifests, and Helm charts.
Document your container security policy in your ISMS — in ISMS Lite, policies, scanning results, and pod security standards can be centrally managed and prepared for audits. Record: Which base images are allowed? Which scanning tools are used? Which pod security standards apply? How are secrets managed? This documentation is your evidence for audits.
Common Mistakes and Anti-Patterns
Treating containers as a replacement for VMs. Containers are not small VMs. A container that includes a complete Linux distribution with an SSH server, cron jobs, and multiple services loses all the advantages of container technology and inherits the security problems of both worlds. A container should run one process and nothing else.
Everything in one namespace. When development, staging, and production environments run in the same Kubernetes namespace, isolation is missing. An error in the development environment can affect production. Use separate namespaces — better yet, separate clusters — for different environments.
Ignoring container updates. Containers are built and then run unchanged for months. New vulnerabilities in base images go unpatched because nobody rebuilds the images. Implement a regular rebuild cycle (at least monthly) and continuously scan running images for new vulnerabilities.
No resource limiting. Containers without CPU and memory limits can destabilize the entire host or cluster. A single container that requests unlimited memory due to a memory leak can crash other containers on the same host. Always set resource requests and limits in your Kubernetes manifests.
Further Reading
- Secure Development Lifecycle (SDL): Sicherheit in den Entwicklungsprozess einbauen
- Secrets Management: Passwörter, API-Keys und Zertifikate sicher verwalten
- Dependency Scanning: Schwachstellen in Drittbibliotheken finden
- Netzwerksegmentierung für KMU: Zonen, VLANs und Firewalls
- API-Sicherheit: Authentifizierung, Rate Limiting und Input Validation
