Console Login

Hardening Docker & Kubernetes: A 2021 Survival Guide for Nordic DevOps

Hardening Docker & Kubernetes: A 2021 Survival Guide for Nordic DevOps

Let’s get one thing straight immediately: Containers are not real isolation.

I recently audited a setup for a fintech startup in Oslo. They were smug about their microservices architecture. "Everything is containerized," they told me, assuming that meant they were immune to host-level attacks. Ten minutes later, I had root access to their host node. Why? Because they treated Docker like a magic shield instead of what it actually is: a collection of Linux namespaces and cgroups glued together with duct tape.

If you are running production workloads in 2021 without hardening your runtime, you are negligent. With the recent runc vulnerabilities (CVE-2021-30465 just dropped), default configurations are a liability. Here is how we lock things down, from the container runtime to the metal.

1. The "Root" of All Evil

By default, a process inside a Docker container runs as PID 1 with root privileges. If an attacker compromises that process (via a vulnerable npm package or a bad dependency), and they escape the container (which happens more often than we like to admit), they are root on your host.

I see this in `Dockerfile` definitions constantly. It stops today. You must enforce a non-root user.

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

# BATTLE-HARDENED PATTERN
FROM node:14-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY . .
# Permission fix is mandatory before switching users
RUN chown -R appuser:appgroup /app
USER appuser
CMD ["node", "index.js"]
Pro Tip: When using CoolVDS NVMe instances, we recommend using base images like Alpine 3.13 not just for size, but for the reduced attack surface. Less code means fewer CVEs.

2. Drop Capabilities Like They’re Hot

Even if you aren't root, the Linux kernel grants "capabilities" to processes. By default, Docker grants a laundry list of them, including `CAP_CHOWN`, `CAP_NET_RAW`, and `CAP_AUDIT_WRITE`. Your Node.js API does not need to modify kernel audit logs.

The golden rule of 2021 security: Deny all, permit necessary.

The Docker Run Approach

Don't just run the container. Strip it naked and give it only what it needs.

docker run --d -p 8080:8080 \
  --name web-app \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --read-only \
  --tmpfs /tmp \
  coolvds/secure-app:v1

Notice the --read-only flag. If an attacker gets a shell, they can't write a backdoor to the filesystem. They can only write to the ephemeral /tmp (which we mounted as tmpfs). Persistence is dead; long live the immutable infrastructure.

3. Kubernetes SecurityContext

For those of you orchestrating on K8s (we are seeing huge uptake of version 1.20 and 1.21 in the Nordic enterprise sector), you can't rely on `docker run` flags. You define this in your Deployment YAML.

With Kubernetes 1.21 deprecating PodSecurityPolicies, you need to get comfortable with the securityContext block immediately.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-nginx
spec:
  template:
    spec:
      securityContext:
        runAsUser: 1000
        runAsGroup: 3000
        fsGroup: 2000
      containers:
      - name: nginx
        image: nginx:1.19-alpine
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE

4. The Norwegian Context: Schrems II and Data Sovereignty

Technological security is useless if you fail legal security. Since the CJEU's Schrems II ruling last year, relying on US-based cloud providers (AWS, Azure, GCP) has become a legal minefield for Norwegian companies handling personal data. The Privacy Shield is dead. Standard Contractual Clauses (SCCs) are under fire.

The Datatilsynet (Norwegian Data Protection Authority) is not known for its leniency. If you are hosting critical GDPR data, the safest physical location is a server on Norwegian soil, governed by Norwegian law.

This is where infrastructure choice becomes a security feature. Using a local provider like CoolVDS ensures your data physically resides in Oslo or nearby EU zones, drastically simplifying your compliance documentation.

5. The Infrastructure Layer: KVM vs. Shared Kernels

Container security eventually hits the kernel floor. If you are running Docker on a cheap OpenVZ or LXC VPS, you are sharing the host kernel with your neighbors. If their container crashes the kernel, your service goes down. If they exploit a kernel bug, they might read your memory.

This is why we strictly utilize KVM (Kernel-based Virtual Machine) for all CoolVDS instances. KVM provides hardware-level virtualization. Your kernel is yours. It is distinct from the host and distinct from other tenants.

Performance Check: I/O Wait

Security scanning (like running ClamAV or Trivy on incoming files) is I/O intensive. On standard SATA SSDs, a full scan can spike your I/O Wait, causing your web application to hang.

We benchmarked a standard ClamAV scan on a 50GB dataset:

Storage Type Scan Time System Load (1 min avg)
Standard SSD VPS 14m 20s 4.5 (Sluggish)
CoolVDS NVMe 3m 45s 0.8 (Responsive)

Low latency isn't just about speed; it's about availability during security operations.

6. Automated Scanning Pipeline

You cannot secure what you do not see. In 2021, you should be scanning images before they ever hit your cluster. Tools like Trivy are essential.

# CI/CD Step Example
$ trivy image --severity HIGH,CRITICAL coolvds/my-app:latest

2021-05-20T10:00:00.000+0200    INFO    Detecting Alpine vulnerabilities...

image: coolvds/my-app:latest
Total: 0 (HIGH: 0, CRITICAL: 0)

If the result is anything other than zero, the build fails. No exceptions.

Final Thoughts

Container security is a game of layers. You harden the code, you strip the permissions, and you lock down the network. But ultimately, your containers float on top of a server. If that foundation is shaky—whether due to noisy neighbors, shared kernels, or uncertain legal jurisdictions—your "secure" container is a house of cards.

Don't let a kernel panic in a neighboring container take down your production database. Build your fortress on dedicated KVM resources.

Ready to harden your stack? Deploy a KVM-isolated, NVMe-powered instance on CoolVDS today and get root (the real kind) in under 60 seconds.