Console Login

Container Escapes Are Real: Hardening Docker and Kubernetes for Production in 2022

Container Escapes Are Real: Hardening Docker and Kubernetes for Production in 2022

Let’s cut the marketing fluff. If you think running your application in a Docker container automatically makes it secure, you are asking for a data breach. I've spent the last three months cleaning up the mess left by Log4Shell (CVE-2021-44228), and if that disaster taught us anything, it's that the default configuration of almost every container runtime is far too permissive.

In the Norwegian tech scene, where we pride ourselves on stability and strict adherence to Datatilsynet's privacy guidelines, sloppy DevOps is a legal liability. A container is just a process with some fancy cgroups and namespaces around it. It shares the host kernel. If an attacker breaks out of that namespace, they own the node. And if you are on a shared hosting environment with weak hypervisor isolation, they might just own your neighbors too.

The "Root" of All Evil

The most common sin I see in Dockerfile audits is the default user. By default, containers run as root. Yes, it's "root inside the container," but depending on your runtime configuration and potential kernel vulnerabilities (like "Dirty Pipe" which is currently making waves in the Linux community), mapping to the host root is a dangerous game.

The Fix: Enforce Non-Root Users

Stop writing Dockerfiles that end after the CMD instruction. You need to create a specific user and switch to it. This limits the blast radius if an application vulnerability allows remote code execution.

# BAD PRACTICE
FROM node:16-alpine
WORKDIR /app
COPY . .
CMD ["node", "index.js"]

# BATTLE-HARDENED PRACTICE
FROM node:16-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY . .
# Ensure permissions are correct before switching
RUN chown -R appuser:appgroup /app
USER appuser
CMD ["node", "index.js"]

Drop Those Capabilities

The Linux kernel divides the privileges traditionally associated with superuser into distinct units, known as capabilities. By default, Docker grants a container a significant number of these, including CAP_CHOWN, CAP_NET_RAW, and others that a web server simply does not need.

I adopt a "deny all, allow some" approach. It breaks things initially, but it forces you to understand exactly what your application is doing.

Pro Tip: If you are running a standard Nginx or Node.js app, you almost certainly do not need NET_ADMIN or SYS_ADMIN. Granting these is practically handing over the keys to the server.

Here is how you lock this down in a Kubernetes securityContext. Note that in 2022, with PodSecurityPolicy being deprecated in Kubernetes 1.21+, we are moving toward Pod Security Standards, but the context definition remains the implementation method.

apiVersion: v1
kind: Pod
metadata:
  name: secure-nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    securityContext:
      runAsNonRoot: true
      runAsUser: 101
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

The Infrastructure Reality: Noisy Neighbors and Kernel Sharing

Software limits like drop: ALL are your first line of defense. But what happens when there is a zero-day in the kernel itself? This is where your choice of hosting provider becomes a security decision, not just a financial one.

Many budget VPS providers use OpenVZ or LXC to oversell resources. In those environments, you are sharing a kernel not just with your own containers, but with other customers on the same physical box. If the kernel panics or is exploited, everyone goes down.

At CoolVDS, we refuse to use container-based virtualization for our instances. We use KVM (Kernel-based Virtual Machine). This provides hardware-level isolation. Each CoolVDS instance runs its own dedicated kernel. If you are running a Kubernetes cluster on CoolVDS, you have a hard boundary between your nodes and the rest of our infrastructure.

Comparison: Isolation Levels

Feature Container (Docker/LXC) KVM VPS (CoolVDS)
Kernel Shared with Host Dedicated / Isolated
Attack Surface High (Syscalls) Low (Hypervisor calls)
Performance Native Near-Native (with VirtIO drivers)
Neighbor Risk High Extremely Low

Supply Chain Security: Scan Before You Ship

In 2022, you cannot trust images from Docker Hub blindly. Crypto-miners are routinely found in "typosquatted" images (e.g., ngnix instead of nginx).

Integrate a scanner like Trivy into your CI/CD pipeline. It’s fast, open-source, and catches OS package vulnerabilities before they hit production.

# Install Trivy (v0.24.0 is current as of early 2022)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.24.0

# Scan your image, failing only on Critical issues
trivy image --exit-code 1 --severity CRITICAL my-app:latest

Data Sovereignty and Latency

Security isn't just about hackers; it's about lawyers. With the Schrems II ruling making data transfers to the US legally complex, hosting your container infrastructure within the EEA is crucial for GDPR compliance.

When you deploy on CoolVDS, your data sits on NVMe storage physically located in our datacenters. We don't ship your volumes across the Atlantic. Plus, if your user base is in Oslo or Bergen, the latency difference between a local provider and a generic US hyperscaler is noticeable. We optimize our routing through NIX (Norwegian Internet Exchange) to ensure that your packets take the shortest path possible.

Conclusion

Container security is a layered discipline. You harden the code, you harden the container runtime, and crucially, you must harden the infrastructure it runs on. Do not put your hardened Kubernetes cluster on a flimsy, oversold virtualization platform.

You need dedicated resources, hardware isolation, and low latency. CoolVDS provides the KVM foundation your DevOps strategy requires. Stop fighting for CPU cycles and start deploying with confidence.

Ready to lock down your infrastructure? Deploy a secure KVM instance on CoolVDS in under 55 seconds.