Ravindra BagaleCourses & study guides मराठी

Chapter 67: Docker Swarm vs Kubernetes: the Same App on Both, Side by Side

67.1 Docker Swarm from zero: managers, workers, Raft and your first service

Why: the problem

Before we can compare Swarm and Kubernetes fairly, we need a real Swarm in front of us. Docker Swarm mode is the orchestrator built into Docker Engine itself. There is nothing extra to install: the same docker binary that runs containers on your laptop can turn a group of machines into one cluster with a single command, docker swarm init. That simplicity is the main reason teams still pick it, and it is also why it is the best place to start the comparison. Why does an orchestrator exist at all? Running one container with docker run is easy. Running twelve copies across three servers, replacing the ones that die, spreading them across machines, giving them one stable address and updating them without downtime is not something a human should do by hand at 2 AM. An orchestrator keeps a desired state, such as "six replicas of orders:1.0.0 on port 8080", and works all the time to make the real state match it. Kubernetes does this with controllers and etcd; Swarm does it with managers that share a Raft log. What is inside a Swarm? Manager nodes accept commands, store the cluster state in a replicated Raft database and schedule tasks. Worker nodes only run tasks. A service is the desired state you declare, and each running container of a service is a task. Swarm creates an overlay network so containers on different machines talk as if they were on one LAN, and its routing mesh publishes a port on every node so a request to any node reaches a healthy task. Managers need a majority, called quorum, to make changes: three managers survive one failure, five survive two. This is the same rule etcd follows in Kubernetes. How will we build it? On a laptop we do not have three servers, so we run three Docker-in-Docker containers as nodes on one bridge network, exactly as many training labs and CI systems do. If you have three EC2 instances, the commands are identical; you only open ports 2377/tcp for management, 7946/tcp and udp for node gossip and 4789/udp for overlay traffic. We initialise the first manager, join two more nodes with tokens, inspect the cluster, run a first service with three replicas, and watch Swarm heal it when we remove a container by force.

What: every term in plain English

  • Swarm mode — Orchestrator built into Docker Engine, enabled with docker swarm init.
  • Manager node — Stores cluster state in Raft and schedules tasks; can also run tasks.
  • Worker node — Only runs tasks given by managers.
  • Raft — Consensus algorithm managers use to agree on cluster state.
  • Quorum — Majority of managers, such as 2 of 3, needed to change state.
  • Join token — Secret string that lets a node join as a worker or a manager.
  • Service — Desired state: image, replicas, ports, networks, update policy.
  • Task — One container scheduled for a service on a node.
  • Overlay network — Virtual network spanning all nodes, encrypted on request.
  • Routing mesh — Publishes a service port on every node and forwards to healthy tasks.
Create a bridge network for the lab nodes. Start three docker:dind containers as nodes. Run docker swarm init on node1. Read the worker and manager join tokens. Join node2 as manager and node3 as worker. List nodes and check quorum. Create a service with three replicas.
A three-node Swarm with a routing mesh

How: step by step

  1. Create a bridge network for the lab nodes. Nodes can reach each other.
  2. Start three docker:dind containers as nodes. Three engines.
  3. Run docker swarm init on node1. First manager.
  4. Read the worker and manager join tokens. Tokens printed.
  5. Join node2 as manager and node3 as worker. Three nodes.
  6. List nodes and check quorum. Leader and reachable managers.
  7. Create a service with three replicas. Tasks spread out.
  8. Remove a task container by force and watch healing. Replaced in seconds.

A useful way to remember the architecture is to map every Swarm part to its Kubernetes partner before we go further. Swarm managers with their Raft store play the role of the API server, etcd, scheduler and controller manager combined into one process. Swarm workers play the role of kubelet nodes. A Swarm service is close to a Deployment plus a Service in one object, and a task is close to a pod with one container. The routing mesh is close to a NodePort Service with kube-proxy on every node. Keeping this map in mind makes the next three lessons much easier, because you will see the same idea twice with different names. Notice also what is missing in Swarm: there is no separate CNI choice, no admission controllers, no custom resources and no operators. Fewer moving parts make Swarm easy to learn and operate; the same missing parts are exactly what large platforms at Flipkart, Swiggy or Zomato rely on in Kubernetes.

Example 1: Build a three-node Swarm on one laptop

Goal. Build a three-node Swarm on one laptop.

nodes.sh

docker network create swarmlab
for n in node1 node2 node3; do
  docker run -d --privileged --name $n --hostname $n --network swarmlab docker:28-dind
done
sleep 8
alias d1='docker exec node1 docker'
docker exec node1 docker swarm init --advertise-addr eth0
WTOKEN=$(docker exec node1 docker swarm join-token -q worker)
MTOKEN=$(docker exec node1 docker swarm join-token -q manager)
docker exec node2 docker swarm join --token $MTOKEN node1:2377
docker exec node3 docker swarm join --token $WTOKEN node1:2377
docker exec node1 docker node ls

What each line does

  • docker:28-dind — Docker-in-Docker image; each container is a full Docker Engine acting as a node.
  • --privileged — Needed only for this lab so the inner engine can create containers; never use it for app containers.
  • swarm init --advertise-addr — Tells other nodes which address reaches this manager.
  • join-token -q — Prints only the token, so we can store it in a variable instead of copying by hand.
  • node2 as manager — Two managers are not fault tolerant yet; we add a third in the next example.

Green output

$ bash nodes.sh
Swarm initialized: current node (k3x9...) is now a manager.
This node joined a swarm as a manager.
This node joined a swarm as a worker.
ID                HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS  ENGINE VERSION
k3x9q1... *       node1     Ready   Active        Leader          28.5.1
p7m2w8...         node2     Ready   Active        Reachable       28.5.1
z4c6v0...         node3     Ready   Active                        28.5.1

Expected result. One command created the cluster and two more joined the nodes. Compare this with Kubernetes, where even kind needs a config file and kubeadm needs certificates, a CNI and a join command per node.

Example 2: Quorum in practice: promote, demote and lose a manager

Goal. Quorum in practice: promote, demote and lose a manager.

quorum.sh

docker exec node1 docker node promote node3
docker exec node1 docker node ls --format '{{.Hostname}} {{.ManagerStatus}}'
docker stop node2
sleep 5
docker exec node1 docker node ls --format '{{.Hostname}} {{.Status}} {{.ManagerStatus}}'
docker exec node1 docker service ls
docker stop node3
sleep 5
docker exec node1 docker service ls || true
docker start node2 node3
sleep 10
docker exec node1 docker node ls --format '{{.Hostname}} {{.Status}} {{.ManagerStatus}}'

What each line does

  • docker node promote — Turns a worker into a manager; now we have three managers.
  • Stop node2 — One of three managers is gone; 2 of 3 is still a majority, so the cluster works.
  • Stop node3 too — Only 1 of 3 left, no quorum, so management commands fail while running tasks keep serving.
  • Start them again — Managers rejoin and Raft catches them up automatically.
  • --format — Go template output keeps the screen readable.

Green output

$ bash quorum.sh
Node node3 promoted to a manager in the swarm.
node1 Leader
node2 Reachable
node3 Reachable
node1 Ready Leader
node2 Down Unreachable
node3 Ready Reachable
ID   NAME   MODE   REPLICAS   IMAGE   PORTS
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online.
node1 Ready Leader
node2 Ready Reachable
node3 Ready Reachable

Expected result. Three managers survive one failure, never two. This is exactly the etcd rule in Kubernetes, which is why both production Swarms and production control planes use three or five managers, never two or four.

Example 3: First service: replicas, routing mesh and self-healing

Goal. First service: replicas, routing mesh and self-healing.

service.sh

docker exec node1 docker service create --name web --replicas 3 --publish 8080:80 nginx:1.27-alpine
docker exec node1 docker service ps web --format '{{.Name}} {{.Node}} {{.CurrentState}}'
docker exec node3 wget -qO- http://node1:8080 | grep -o '<title>.*</title>'
TASK=$(docker exec node2 docker ps -q --filter name=web | head -1)
docker exec node2 docker rm -f $TASK
sleep 4
docker exec node1 docker service ps web --format '{{.Name}} {{.Node}} {{.CurrentState}} {{.Error}}'
docker exec node1 docker service scale web=6
docker exec node1 docker service ls

What each line does

  • service create — Declares desired state: three replicas of nginx with port 8080 published.
  • service ps — Shows each task, its node and state; tasks are spread across nodes.
  • Routing mesh — node3 calls node1:8080 and gets an answer even if no web task runs on node1.
  • docker rm -f — Simulates a crash; the manager sees fewer running tasks than desired.
  • service scale — Changes desired replicas, like kubectl scale.

Green output

$ bash service.sh
web
overall progress: 3 out of 3 tasks
verify: Service web converged
web.1 node1 Running 5 seconds ago
web.2 node2 Running 5 seconds ago
web.3 node3 Running 5 seconds ago
<title>Welcome to nginx!</title>
web.2 node2 Running 3 seconds ago
 \_ web.2 node2 Failed 4 seconds ago  task: non-zero exit (137)
web scaled to 6
ID     NAME  MODE        REPLICAS  IMAGE              PORTS
x1y2   web   replicated  6/6       nginx:1.27-alpine  *:8080->80/tcp

Expected result. Swarm replaced the killed task in about four seconds and keeps the failed one in history. The Kubernetes equivalent is a ReplicaSet recreating a deleted pod, which you saw in Chapter 60.

Every command, step by step (kind lab with kubectl)

  1. Network

    docker network create swarmlab
    

    What it does: Lab LAN.

    3c1f...
    
  2. Nodes

    docker run -d --privileged --name node1 --network swarmlab docker:28-dind
    

    What it does: Engine.

    9a8b...
    
  3. Init

    docker exec node1 docker swarm init --advertise-addr eth0
    

    What it does: Manager.

    Swarm initialized
    
  4. Token

    docker exec node1 docker swarm join-token -q worker
    

    What it does: Worker token.

    SWMTKN-1-xxxx
    
  5. Join

    docker exec node3 docker swarm join --token $WTOKEN node1:2377
    

    What it does: Worker.

    This node joined a swarm as a worker.
    
  6. Nodes

    docker exec node1 docker node ls
    

    What it does: Cluster.

    node1 Leader
    
  7. Promote

    docker exec node1 docker node promote node3
    

    What it does: Third manager.

    promoted
    
  8. Service

    docker exec node1 docker service create --name web --replicas 3 -p 8080:80 nginx:1.27-alpine
    

    What it does: Deploy.

    converged
    
  9. Tasks

    docker exec node1 docker service ps web
    

    What it does: Placement.

    web.1 node1 Running
    
  10. Scale

    docker exec node1 docker service scale web=6
    

    What it does: Six.

    web scaled to 6
    

When it is red 1

Error response from daemon: This node is not a swarm manager.

Cause. Running a service command on a worker.

Fix, step by step

  1. Run it on a manager, or promote the node.

When it is red 2

Timeout was reached before node joined.

Cause. Port 2377 blocked between nodes.

Fix, step by step

  1. Open 2377/tcp, 7946/tcp+udp, 4789/udp in the security group.

When it is red 3

The swarm does not have a leader.

Cause. Quorum lost.

Fix, step by step

  1. Bring managers back, or run docker swarm init --force-new-cluster on one survivor.

When it is red 4

service web: 0/3 replicas, no suitable node

Cause. Constraints or resources cannot be met.

Fix, step by step

  1. docker service ps web --no-trunc to read the reason.

When it is red 5

curl to the published port hangs

Cause. Overlay ports blocked or the task is unhealthy.

Fix, step by step

  1. Check 4789/udp and docker service ps.

Practice tasks

Easy Task 1: Init

Why: Start.

What to do: Run docker swarm init.

How:
  1. Leader shown.
Solution
docker node ls

Easy Task 2: Join

Why: Nodes.

What to do: Join a worker.

How:
  1. Use join-token -q.
Solution
docker node ls

Easy Task 3: Service

Why: Deploy.

What to do: Create nginx with 3 replicas.

How:
  1. Publish 8080.
Solution
docker service ls

Medium Task 4: Spread

Why: Placement.

What to do: Check which node runs each task.

How:
  1. service ps.
Solution
docker service ps web

Medium Task 5: Heal

Why: Crash.

What to do: Force-remove a task container.

How:
  1. Watch history.
Solution
docker service ps web

Medium Task 6: Quorum

Why: Managers.

What to do: Promote to three managers and stop one.

How:
  1. Still works.
Solution
docker service ls

Hard Task 7: Lose

Why: Two down.

What to do: Stop two managers.

How:
  1. Read the error.
Solution
docker service ls

Hard Task 8: Dunzo

Why: Main task.

What to do: Tracker Swarm with timings.

How:
  1. 4/4 again.
Solution
docker service ls

Homework: try at home

For Dunzo's delivery tracker, build a three-manager plus one-worker Swarm, run nginx with four replicas on port 8081, kill one manager and one task, and record how long the service takes to return to 4/4.

Recap

  • Swarm mode is built into Docker; docker swarm init creates a cluster.
  • Managers keep state with Raft and need a majority, so run three or five.
  • A service is desired state; each container is a task.
  • The routing mesh publishes a port on every node.
  • Swarm heals failed tasks automatically, like a Kubernetes ReplicaSet.

FAQ

Q. Is Docker Swarm dead?

No. Mirantis maintains Swarm mode in Docker Engine and supports it commercially, with a long-term support commitment, but new features are rare and the community is far smaller than Kubernetes.

Q. Is Swarm the same as classic Docker Swarm?

No. Classic Swarm was a separate project and is retired. Everything here is Swarm mode, built into Docker Engine since 1.12.

Q. Can managers run app tasks?

Yes, by default. In production you can drain managers with docker node update --availability drain so they only manage.

Q. Can I run this lab on EC2 instead of Docker-in-Docker?

Yes. Launch three t3.small Amazon Linux 2023 instances in one VPC subnet, install Docker with dnf, allow 2377/tcp, 7946/tcp and udp and 4789/udp between them in one security group, and run the same init and join commands with each private IP as the advertise address. Everything else in this chapter stays the same, and the routing mesh then answers on every public IP.

Q. Is the overlay network encrypted?

Control traffic is always encrypted with TLS. Add --opt encrypted to an overlay network to encrypt app traffic too.

Interview questions

  1. What is the difference between a manager and a worker?

    Model answer: Managers hold Raft state and schedule; workers only run tasks.

  2. Why an odd number of managers?

    Model answer: Quorum needs a majority; four managers tolerate only one failure, the same as three.

  3. How does Swarm self-heal?

    Model answer: Managers compare running tasks with desired replicas and schedule replacements.

  4. What ports must be open for Swarm?

    Model answer: 2377/tcp, 7946/tcp and udp, and 4789/udp.

Quick quiz

Q1. Which port do managers use?

2377/tcp.

Q2. How many managers survive one failure?

Three.

Q3. What is a task?

One container of a service.

Q4. What does the routing mesh do?

Publishes the port on every node.

Q5. Which command adds desired replicas?

docker service scale.

Samajla ka?