Console Login

Kubernetes vs. Docker Swarm: A 2019 Reality Check for Norwegian DevOps

Stop Over-Engineering: Choosing the Right Orchestrator in 2019

If I have to review one more architecture diagram where a startup with three microservices is trying to deploy a multi-region federated Kubernetes cluster, I might just `rm -rf /` my own workstation. The hype cycle in 2019 is deafening. Everyone wants Google-scale infrastructure, but very few people actually have Google-scale problems. As systems architects, our job isn't to pick the shiniest toy; it's to pick the tool that won't wake us up at 3 AM on a Sunday.

In the Nordic hosting market, specifically here in Norway, we face a unique set of constraints. We care about latency to Oslo, we care about Datatilsynet (The Norwegian Data Protection Authority) breathing down our necks regarding GDPR, and we care about raw stability. Today, we are going to look at the state of container orchestration as of mid-2019, comparing the heavyweights: Kubernetes (K8s) and Docker Swarm, with a nod to HashiCorp's Nomad.

The Latency Trap and The "Noisy Neighbor"

Before we touch the orchestration layer, we need to address the substrate. An orchestrator manages resources. If the underlying resource is garbage, your orchestration will be garbage. I've seen Kubernetes clusters implode not because of bad YAML, but because the underlying VPS had high CPU steal.

When running `etcd` (the brain of Kubernetes), disk I/O latency is critical. If your VPS provider is putting you on spinning rust or over-provisioned SATA SSDs, your cluster state will drift. This is why, for our reference implementations at CoolVDS, we strictly enforce KVM virtualization on NVMe storage. You need consistent I/O operations per second (IOPS).

Check your disk latency right now:

ioping -c 10 .

If you aren't seeing averages below 1ms, you are going to have a bad time with distributed consensus algorithms.

Docker Swarm: The "Good Enough" Hero

Docker Swarm is currently uncool. That's exactly why I like it. For 80% of the dev teams I talk to in Oslo, Swarm is actually the superior choice. It is built into the Docker engine. There is no extra binary to install. The learning curve is practically flat if you know Docker Compose.

Swarm shines in scenarios where you have a small team (1-5 ops people) and a moderate number of services (under 50). It handles overlay networking, secrets, and rolling updates out of the box.

The Configuration Simplicity

Here is a production-ready Swarm stack file. Notice how readable this is compared to the verbose K8s manifests.

version: "3.7"
services:
  app:
    image: registry.coolvds.com/my-app:v2
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          - node.role == worker
    environment:
      - DB_HOST=db
    networks:
      - backend

  db:
    image: postgres:11-alpine
    volumes:
      - db-data:/var/lib/postgresql/data
    deploy:
      placement:
        constraints:
          - node.role == manager
    networks:
      - backend

networks:
  backend:
    driver: overlay

volumes:
  db-data:

To deploy this on a CoolVDS cluster, you simply run:

docker stack deploy -c docker-compose.yml my-stack

The downside? Swarm's future is uncertain. With Mirantis acquiring Docker Enterprise assets, the community is nervous. However, as of June 2019, it is stable, robust, and fast.

Kubernetes: The Industrial Grade Standard

Kubernetes (currently v1.14/v1.15) has won the war. It is the standard. But it is also a beast. It solves problems you don't have yet, introducing complexity you can't afford yet. You need it if you require:

  • Complex autoscaling (HPA/VPA).
  • Custom Resource Definitions (CRDs) and Operators.
  • Granular RBAC (Role-Based Access Control) for large teams.
  • Massive scale (100+ nodes).

However, running K8s requires a rigorous adherence to best practices. One major pain point I see in Norwegian deployments is the lack of resource limits, leading to the "OOMKill" (Out of Memory) loop when a Java app decides to eat all the RAM on the node.

The Verbose Reality

To achieve roughly the same result as the Swarm file above, you need multiple files or a Helm chart. Here is just the Deployment manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: registry.coolvds.com/my-app:v2
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        env:
        - name: DB_HOST
          value: "db-service"
Pro Tip: Always set your requests and limits. If you don't, the scheduler treats your pod as "BestEffort" QoS. In a resource contention scenario (which happens often on shared clouds, though less so on dedicated-resource platforms like CoolVDS), BestEffort pods are the first to be killed.

Network Policies and GDPR

One specific advantage of Kubernetes for European companies is the NetworkPolicy API. GDPR requires us to practice "Data Protection by Design and by Default." By default, all pods in K8s can talk to each other. This is bad security practice.

We can lock this down. For a financial application hosted in Oslo, you might apply a policy that denies all ingress traffic unless explicitly allowed. This is a massive compliance win when the auditors come knocking.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress

You need a CNI plugin that supports this (like Calico or Weave). Flannel generally doesn't enforce policies.

Infrastructure Matters: The CoolVDS Advantage

Whether you choose Swarm or Kubernetes, you are building a house. The orchestrator is the frame, but the VPS is the foundation. If the foundation cracks, the house falls.

In 2019, many "cloud" providers are still selling you vCPUs that are heavily overcommitted. When you try to run a K8s control plane, which is sensitive to CPU latency, on a stolen CPU cycle, you get timeouts. You get Leader Election failures in `etcd`.

At CoolVDS, we take a different approach:

  1. KVM Virtualization: We don't use containers to host your containers. We use the kernel-based virtual machine to ensure hard isolation.
  2. Pure NVMe: We don't tier storage. Everything is NVMe. This is crucial for Docker image pulls and database transactions.
  3. Local Peering: Our connectivity to NIX (Norwegian Internet Exchange) ensures that if your users are in Oslo, their requests don't bounce through Frankfurt before coming back.

Benchmarking the Difference

Don't take my word for it. Install `sysbench` on your current host and compare it against a CoolVDS instance.

sysbench cpu --cpu-max-prime=20000 run

On a heavily shared host, you will see high standard deviation in the event execution time. On a dedicated-resource VDS, the latency curve is flat. Consistency is key for orchestration.

Conclusion

If you are a team of 30 engineers building the next Spotify, use Kubernetes. The complexity cost is amortized over the size of the team. If you are a team of 3 managing a critical e-commerce platform for the Nordic market, Docker Swarm on high-performance infrastructure is likely your sweet spot for 2019.

But regardless of the software, ensure your hardware respects your data. Low latency, high I/O, and data sovereignty aren't optional features—they are the baseline.

Ready to stabilize your cluster? Deploy a high-performance, NVMe-backed KVM instance on CoolVDS in under 55 seconds and stop fighting with hardware lag.