Console Login

Container Security in 2020: Surviving the Wild West of Microservices

Container Security in 2020: Surviving the Wild West of Microservices

Let’s be honest: your containers are leaking. I’ve audited enough clusters this year to know that most "production-ready" deployments are just one kernel exploit away from a total compromise. We love containers for the agility—spinning up a microservice in milliseconds is addictive—but we often treat them like lightweight VMs. They are not.

If you are still running processes as root inside a container, you are effectively handing the keys to your host kernel to anyone who finds a vulnerability in your application code. With the recent explosion of supply chain attacks and the complexity of Kubernetes version 1.19 dropping, the margin for error is zero.

Furthermore, security in October 2020 isn't just technical; it's legal. The CJEU's Schrems II ruling this July has nuked the Privacy Shield. If you are piping customer data through containers hosted on US-controlled clouds, you aren't just risking a hack; you're inviting the wrath of the Datatilsynet (Norwegian Data Protection Authority).

Here is how to lock down your hull without capsizing the ship.

1. The "Latest" Tag is a Russian Roulette

I still see FROM node:latest in production Dockerfiles. This is negligence. "Latest" is a moving target. One day it's Node 14.13.0, the next it's 15.0.0 with breaking changes or, worse, a compromised upstream dependency.

You need determinism. Pin your versions, and preferably, use the SHA256 digest. If you care about attack surface, ditch the full OS images for Alpine Linux. A standard Debian image has hundreds of packages you don't need. Alpine has... barely any.

Bad Practice:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3
COPY . /app
CMD ["python3", "/app/main.py"]

The Battle-Hardened Way:

# Use specific digest for immutability
FROM python:3.8-alpine@sha256:456...

# Create a non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app
COPY . .

# Switch to non-root
USER appuser

CMD ["python", "main.py"]
Pro Tip: Scanning your images is mandatory. Tools like Trivy or Clair should be blocking your CI/CD pipeline if high-severity CVEs are found. Don't let the bad code leave Jenkins.

2. Drop Capabilities (And Stop Being Root)

By default, Docker containers run with a subset of Linux capabilities that are still too broad for most web apps. Does your Nginx container need to tweak system time or load kernel modules? Absolutely not.

We apply the principle of least privilege. Drop everything, then add back only what is strictly necessary. If you are hosting on CoolVDS, you benefit from our KVM virtualization which provides a strong hardware-level boundary, but you should still practice defense-in-depth inside the VM.

Here is how you strip a container naked:

docker run --rm -it \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --read-only \
  --tmpfs /run \
  --tmpfs /tmp \
  alpine:3.12 sh

This command drops all Linux capabilities, adds back only the ability to bind network ports, mounts the root filesystem as read-only (immutable infrastructure!), and uses in-memory storage for temporary files. Good luck establishing persistence in a container that can't write to its own disk.

3. The Schrems II Reality Check

Technical security means nothing if your legal standing is compromised. Since the Schrems II judgment invalidated the EU-US Privacy Shield, using hyperscalers (AWS, Azure, GCP) for processing European personal data has entered a legal grey zone. Standard Contractual Clauses (SCCs) are under heavy scrutiny.

For a Norwegian or European CTO, the safest bet is data sovereignty. Hosting on CoolVDS NVMe instances means your data resides physically in Oslo. It stays under Norwegian jurisdiction and GDPR protections, away from the reach of the US CLOUD Act. This isn't just compliance; it's a competitive advantage when selling to privacy-conscious enterprise clients.

4. Kubernetes Security Context

If you are orchestrating with Kubernetes (and in 2020, who isn't?), you define security at the Pod level. Do not rely on defaults. A Pod Security Policy (PSP) is your friend, but configuring the securityContext in your deployment YAML is the immediate fix.

Here is a snippet from a deployment I reviewed last week for a fintech client. We moved them from a default config to this hardened state:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-payment-gateway
spec:
  template:
    spec:
      securityContext:
        runAsUser: 1000
        runAsGroup: 3000
        fsGroup: 2000
      containers:
      - name: payment-api
        image: payment-api:1.4.2
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          capabilities:
            drop:
              - ALL
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      volumes:
      - name: tmp
        emptyDir: {}

This configuration explicitly forbids privilege escalation. Even if an attacker compromises the application via a buffer overflow, they cannot gain root privileges to jump out of the container. It effectively neutralizes a vast class of exploits.

5. The Hardware Factor: Why VDS Matters

Containers share the host kernel. If that kernel panics, everyone goes down. If there is a kernel exploit (like the dirty COW vulnerability from a few years back), container isolation dissolves.

This is why "noisy neighbors" and security are linked. On cheap, oversold VPS providers, you are often fighting for CPU time which can lead to timing attacks or simple denial of service. At CoolVDS, we don't play that game. We use KVM (Kernel-based Virtual Machine) to ensure your Docker host has dedicated hardware resources.

Furthermore, scanning images and handling high-throughput encrypted traffic requires high I/O. Our pure NVMe storage arrays ensure that your security tools (like Falco or Suricata) can analyze traffic in real-time without choking your actual application throughput. Latency within Norway is often sub-2ms on our network—don't ruin that speed with slow storage.

Summary Checklist for 2020:

  • Stop using latest tags.
  • Run as non-root (UID > 1000).
  • Make the filesystem Read-Only.
  • Audit your `CAP_DROP` settings.
  • Ensure data residency complies with Schrems II (Host in Norway).

Security is a process, not a product. But starting with a solid foundation makes the process a hell of a lot easier. If you need a rock-solid, compliant, and blazing fast foundation for your container fleet, stop gambling with shared hosting.

Ready to harden your infrastructure? Spin up a CoolVDS NVMe instance in Oslo today and experience the difference dedicated resources make.