Console Login

Kubernetes vs. Docker Swarm in 2019: Stop Over-Engineering Your Infrastructure

Kubernetes vs. Docker Swarm: The Reality Check Your CTO Needs

It is 2019, and if I see one more resume listing "Kubernetes Expert" for a blog attracting 500 daily visitors, I might just `rm -rf /` my own workstation. There is a disease plaguing the DevOps community right now: Resume Driven Development. Everyone wants to run Google-scale infrastructure, but nobody wants to deal with the operational complexity of maintaining a highly available control plane when a simple `docker-compose up` would suffice.

I have spent the last six months migrating a logistics platform here in Oslo from a brittle, over-engineered Kubernetes cluster back to Docker Swarm. Why? Because the maintenance overhead of K8s was costing more man-hours than the actual application development. However, for another client dealing with microservices across three datacenters, K8s was the only viable path.

This article isn't a feature list. It is a battle report from the trenches. We will look at where Swarm shines, where Kubernetes is mandatory, and why neither will save you if your underlying VPS provider has high I/O latency.

The War Story: When etcd Meets Cheap Storage

Last winter, we deployed a Kubernetes 1.13 cluster for a client on a "budget" European VPS provider. The specs looked fine on paper: 4 vCPUs, 8GB RAM. But three days after launch, the API server started timing out. Pods were flapping. The cluster state was inconsistent.

The culprit wasn't our YAML configurations. It was fsync latency.

Kubernetes relies on etcd for state storage. Etcd is incredibly sensitive to disk write latency because it calls `fsync` heavily to ensure data consistency. If the disk takes longer than 10ms to acknowledge a write, etcd declares the node unhealthy, and the cluster initiates a failover storm.

We ran ioping on that budget host:

# ioping -c 10 .
4 KiB from . (ext4 /dev/sda1): request=1 time=18.4 ms
4 KiB from . (ext4 /dev/sda1): request=2 time=22.1 ms
4 KiB from . (ext4 /dev/sda1): request=3 time=45.2 ms

45ms latency is a death sentence for a K8s control plane. We migrated that workload to CoolVDS NVMe instances the next night. The result? 0.3ms latency. The cluster stabilized instantly. Lesson learned: Container orchestration is useless without high-performance storage.

Docker Swarm: The "Good Enough" Hero

Docker Swarm is currently integrated directly into the Docker Engine (since 1.12). It is declarative, secure by default, and you likely already know the syntax if you use Docker Compose.

When to use Swarm:

  • Your team is small (under 10 engineers).
  • You want to go from "zero" to "cluster" in 5 minutes.
  • You don't need complex ingress controllers or service meshes like Istio.

Here is how simple a Swarm deployment is. You define it in a `docker-compose.yml` file, adding a `deploy` key:

version: '3.7'
services:
  web:
    image: nginx:alpine
    deploy:
      replicas: 5
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet

networks:
  webnet:

Deploying this requires one command:

docker stack deploy -c docker-compose.yml my_stack

There is no separate binary to install. No `kubeadm` headaches. It just works. For many Norwegian SMEs hosting internal tools or moderate traffic web apps, Swarm reduces TCO (Total Cost of Ownership) significantly because you don't need a dedicated "Kubernetes Admin" on payroll.

Kubernetes: The Industrial Grade Solution

Kubernetes (K8s) is the de-facto standard for enterprise orchestration. It is powerful, extensible, and complex. With version 1.15 recently released, stability is better, but the learning curve remains a wall.

When to use Kubernetes:

  • You need auto-scaling based on custom metrics (not just CPU/RAM).
  • You require complex stateful sets (databases on containers, though I generally advise against this).
  • You need namespace isolation for multi-tenant environments.

In K8s, the same Nginx deployment looks like this verbose YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 5
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.12
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

You then apply it via `kubectl apply -f nginx-deployment.yaml`. The power here isn't in the verbosity, but in the ecosystem. Helm charts, Operators, and CRDs (Custom Resource Definitions) allow you to automate almost anything.

Under the Hood: Kernel Tuning for Containers

Whether you choose Swarm or K8s, running containers in production on Linux (CentOS 7 or Ubuntu 18.04) requires kernel tuning. Default Linux settings are not designed for thousands of ephemeral virtual interfaces.

If you don't tune your `sysctl.conf`, you will hit connection tracking limits under load. I add this to every node provisioning script:

# /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

# Increase connection tracking table
net.netfilter.nf_conntrack_max = 131072

# Handle large number of open files for high-density pods
fs.file-max = 2097152
Pro Tip: Always disable swap on Kubernetes nodes (`swapoff -a`). K8s schedulers do not handle swap memory well and it causes performance degradation. If your node runs out of RAM, it is better for the OOM Killer to terminate a pod than for the system to grind to a halt swapping to disk.

The Hardware Reality: Latency and Data Privacy

Here in Norway, we have specific constraints. GDPR is fully enforced, and the Datatilsynet does not look kindly on vague data processing agreements. Hosting outside the EU/EEA is becoming legally risky. Even with the US Privacy Shield framework, many Norwegian CTOs prefer data residency within Oslo or nearby Nordic hubs to ensure compliance and lower latency.

Latency matters. A ping from Oslo to a datacenter in Frankfurt might take 20-30ms. Local routing via NIX (Norwegian Internet Exchange) stays under 2-3ms. For synchronous microservices, that difference aggregates per request.

This is where the choice of provider dictates your architecture's success. Containers are lightweight processes, but they share the host kernel. If you use a "Noisy Neighbor" VPS where the host CPU is oversubscribed, your K8s scheduler will lag.

At CoolVDS, we utilize KVM virtualization. Unlike OpenVZ or LXC containers-on-containers, KVM provides hard resource isolation. When you reserve 4 cores, you get 4 cores. This consistency is mandatory for the predictable performance required by container orchestrators.

Feature Docker Swarm Kubernetes
Setup Complexity Low (Built-in) High (kubeadm/kubespray)
Learning Curve Days Months
Scaling limit ~1k nodes (starts degrading) 5k+ nodes
Storage Requirements Standard SSD OK High IOPS NVMe Critical (etcd)

Conclusion

If you are building the next Spotify, use Kubernetes. If you are a team of five developers deploying a SaaS product, use Docker Swarm. But whatever you choose, do not neglect the infrastructure layer.

An orchestrator can manage your containers, but it cannot fix a slow disk or a congested network pipe. High-performance NVMe storage and local peering are not luxuries; they are the baseline requirements for modern DevOps in 2019.

Ready to test your cluster performance? Deploy a high-performance NVMe KVM instance on CoolVDS in Oslo. Spinning up takes 55 seconds.