Docker Swarm

docker swarm explained

Docker Swarm 

Docker Swarm is nothing but a group of Docker Engines(Hosts) which run in swarm mode. At a time, a Docker host can be a manager, worker, or both. 

Advantages of the swarm: 

Changes can be deployed without restarting the whole stack. 

During an update operation, the Docker engine will stop the services with the old configuration and redeploys them with the new specified configuration. 

When we create and deploy a service, we define its state i.e. number of replicas required, networks attached, ports exposed…etc and the Docker engine(s) in the swarm works to maintain that specified state. 


Node is nothing but a Docker Host part of a Swarm. 

To deploy your application to a swarm, we need to submit a service definition at the manager node. The manager node then deploys the service(s) as tasks to worker nodes present in the swarm 

Manager nodes handled the orchestration and cluster management tasks to maintain the desired state of the swarm. 

Worker Nodes: 

Worker nodes in the swarm receive tasks from manager nodes and execute them.

By default, manager nodes can also be worker nodes, but we can set up them to run manager tasks only. 

Services and tasks 

A service deployed as a global, swarm executes that task in every available node in the cluster. 

For a replicated services model, the manager distributes the task based on several replicas and the scale parameters specified. 

In general, a task definition contains a Docker container and the commands to run inside that container. 

Load balancing 

Swarm manager uses ingress load balancing by default. 

Docker Swarm supports external components, such as managed and cloud-based load balancers, which can access the service on the exposed ports of any node in the cluster even if that service(s) is running in another node on the cluster 

Swarm mode also has an internal DNS that automatically assigns each service a DNS entry so that the services can talk to each other with these DNS names. 

Getting Started. 

Following activities are involved in the deployment of a docker swarm. 

1. Initializing a cluster of Docker Engines in swarm mode 

2. Adding nodes to the swarm 

3. Deploying application services to the swarm 

4. Managing the swarm once you have everything running

Ports Required : 

Port TCP/UDP Usage
2377 TCP cluster management communications
7946 TCP/UDP for communication among nodes
4789 UDP for overlay network traffic

Creation of Swarm 

$ docker swarm init –advertise-addr <MANAGER-IP>

$ docker info #view the current state of the swarm $ docker node ls #view information about nodes 

Add nodes to the swarm as Workers 

$ docker swarm join –token <accesstoken> ManagerIP:2377 Add nodes to the swarm as Manager 

$ docker swarm join-token manager 

# then execute the token generated in add. manager nods 

Deploy a service 


$ docker service create –replicas 1 –name DemoService alpine ping 

The docker service create creates the service. 

The –name names the service HelloWorld. 

The –replicas specify the desired number of instances. 

The arguments alpine ping define the service as an Alpine-Linux container that executes the command ping 

# Run docker service ls to see the list of running services: $ docker service ls 

Inspect Services 

$ docker service inspect <SERVICE-ID> 

docker service ps <SERVICE-ID>  

#To see which nodes are running the services(s) 

docker ps  

# Run on the node where the task is running to see details about the


Scale the service(s) 

$ docker service scale <SERVICE-ID>=<NUMBER-OF-TASKS> 

For example: 

$ docker service scale helloworld=5 

Delete the service 

$ docker service rm <SERVICE-Name> 

Update a service 

$ docker service update –image redis:3.0.7 redis 

By default, the scheduler carries out rolling updates as follows : 

Stop the first task. 

Schedule update for the stopped task. 

Start the container for the updated task. 

If the update to a task returns RUNNING, wait until the specified delay period then start the next task. Incase a task returns FAILED, pause the update. 

# To restart a paused update.  

$ docker service update <SERVICE-ID 

$ docker service update 

Drain a node 

DRAIN availability prevents a worker node from accepting new tasks from the swarm manager. $ docker node update –availability drain <NODE-ID> 

Re-Activate a drained Node/Worker 

$ docker node update –availability active <NODE-ID> 

Swarm mode and Ingress routing mesh

Docker Engine swarm mode makes it easy to publish/expose ports for services to make them available to resources outside the swarm via an ingress routing mesh. 

To use the ingress network, the following ports must be open. 

Port 7946 TCP/UDP : container network discovery. 

Port 4789 UDP : container ingress network. 

Publish a port for a service 

$ docker service create \ 

 –name <SERVICE-NAME> \ 

 –publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \  <IMAGE> 


$ docker service create \ 

 –name my-web \ 

 –publish published=8080,target=80 \ 

 –replicas 2 \ 


The routing mesh listens on the exposed/published port for the IP address assigned to a node.

For Public IP addresses, the port is accessible from outside the Docker host. 

All other IP addresses the access is limited from within the host

Sample Deployment – WordPress with 3 Replica! 

O3 yvijSsVEpB wopMj

In this demo deployment, we are using the following. 

3 Ubuntu 20.04 EC2 Instances (ie. 3 Manager)

MySQL Server on RDS 



GlusterFS : free and open-source software scalable network filesystem. 

Traefik : A HTTP reverse proxy and load balancer made to deploy microservices and support Docker and Docker Swarm

Stage 1 : Setup GlusterFS: 

$ apt-get install -y glusterfs-server 

# Create a mount target (brick): 

$ mkdir -p /glusterfs/bricks/ 

# add in FSTAB 

/dev/xvdf /glusterfs/bricks/ xfs defaults 0 0 

# Create a shared folder “wordpress” 

$ mkdir /glusterfs/bricks/ 

# Add hosts entries (All 3 Servers) node1 node2 node3 

Establish Gluster cluster nodes trust relationship 

From Node1: 

$ gluster peer probe node2 

$ gluster peer probe node3 

Create a shared volume 

$ gluster volume create example_com-wordpress replica 3 node1:/glusterfs/bricks/ 



Start the Volume 

$ gluster volume start example_com-wordpress 

List Volumes/Check Status 

$ gluster volume list 

$ gluster volume status 

Create a Local Mount Point to hold Shared WP files(On Each Node) $ mkdir -p /data/example_com-wordpress 

Update Fstab 

On Each node, add this line at the end of /etc/fstab file:

# Node1 

node2:/example_com-wordpress /data/example_com-wordpress  glusterfs defaults,_netdev 0 0 

node3:/example_com-wordpress /data/example_com-wordpress  glusterfs defaults,_netdev 0 0 

# Node2 

node1:/example_com-wordpress /data/example_com-wordpress  glusterfs defaults,_netdev 0 0 

node3:/example_com-wordpress /data/example_com-wordpress  glusterfs defaults,_netdev 0 0 

# Node3 

node1:/example_com-wordpress /data/example_com-wordpress  glusterfs defaults,_netdev 0 0 

node2:/example_com-wordpress /data/example_com-wordpress  glusterfs defaults,_netdev 0 0 

Deploy the stack 

$ docker stack deploy –compose-file=stack.yml WP_Stack_wordpress LiVictpZIhDn02ZSqGQWQnmnc7v9Dyz3b XylypSGuEjqMvQpJUUVPbtKBHWl9mwYAPvmu5dtERBB2sJo Vh1HwCxa4f42lvWkEbj7RUUhGqKl4hRMsnR9YhW O Gz1RF6OgZX0=s0


version: ‘3’ 





# LB 


 image: traefik:v1.1.0-rc1 

 command: |- 



 –docker.domain=””  – 



 – 80:80 


 – traefik-net 


 – /var/run/docker.sock:/var/run/docker.sock  deploy: 



 – node.role == manager 

# WordPress Area 


 image: wordpress:php7.4-apache 


 – 8001:80 


 – example_com-network 

 – traefik-net 


 – /data/example_com-wordpress:/var/www/html  environment: 

 WORDPRESS_DB_HOST: host:3306 





 mode: global #replicas becomes 3 as we have 3 nodes in the swarm  labels: 


 traefik.port: 80 



 traefik.backend.loadbalancer.sticky: “true” #For sticky sessions  restart_policy: 

 condition: on-failure 

Check Swarm Deployment status 

docker service ls 

y7p qXhZILHfr7wSM5n3v0mF7vBr07Jlwkb qqDVdq9PPi w

Testing site. 

$ curl -I  

HTTP/1.1 200 OK 

Content-Type: text/html; charset=UTF-8 

Date: Fri, 26 Mar 2021 12:09:31 GMT 

Link: <>; rel=”” Server: Apache/2.4.38 (Debian) 


X-Powered-By: PHP/7.4.16


Leave a Reply