Skip to content

Instantly share code, notes, and snippets.

@surajsaini95
Last active May 20, 2020 13:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save surajsaini95/9e8fcd871cb841be7ecb6773dd3f0dc1 to your computer and use it in GitHub Desktop.
Save surajsaini95/9e8fcd871cb841be7ecb6773dd3f0dc1 to your computer and use it in GitHub Desktop.

Docker-Swarm

The world is constantly being attracted towards containers and its orchestration especially in large and dynamic environments which has also led to the rising of various tools and platforms in trend.

As we all know that Docker is a major player in the world of containers and therefore in this blog, we will be exploring what it offers in terms of orchestration.

Yes, we will be looking at Docker-Swarm and some of its key components !!!

Also here I am assuming that the reader is prior aware of the basic docker concepts like container, image, etc.

What is a Docker Swarm?

Swarm is a fully integrated and built-in container orchestration tool provided by Docker. It is a set of nodes i.e Docker hosts which are running in swarm mode with at least one master node and several worker nodes that can be virtual or physical machines.

It allows the user to manage multiple containers deployed across multiple host machines also while in swarm mode, you can still run standalone containers on any of the Docker hosts.

But when a container is running in service mode, swarm takes over and manages the lifecycle of the service and constantly maintains the desired number of replicas, as specified in the definition.

Swarm Architecture

Now as we have covered a bit about Docker-Swarm, let's look at its components now.

Swarm-Cluster Architecture

The major components of a swarm cluster includes nodes ( worker & manager ), services, docker client.

Nodes

A node is a machine that joins the swarm cluster and each of the node contains an instance of docker engine. Each node of a docker swarm is a docker daemon and all of them interact with docker API over HTTP.

There are 2 types of nodes in the swarm cluster :

  • Manager Node

    • The main function of the manager node is to assign tasks to worker nodes in the swarm and keeps track of the services running.
    • It is responsible for all orchestration and container management tasks required to maintain the desired state of the cluster.
    • There can be multiple manager nodes and based on the Raft consensus algorithm one of them gets assigned as the "leader node".
  • Worker Node

    • These nodes receive and execute tasks distributed by the manager node in the swarm.
    • Each worker node runs an agent that reports back to the master node about the state of the tasks assigned.
    • By default manager nodes also run services as worker nodes which can be configured to run as manager only (if needed).

Services

Now to execute something or to deploy an application on swarm cluster it should be properly defined as service. It specifies which container image to use and which commands to execute inside running containers and other stuffs like which port to use, update policy, etc.

Again there are 2 types of services:

  • Global Service, in which the swarm runs one task for the service on every available node in the cluster.
  • Replicated Service, in which the swarm manager distributes a specific number of replica tasks among the nodes based upon the scale you set in the desired state.

Tasks

Tasks is the most basic and smallest unit of scheduling within a swarm. Manager nodes assign tasks to worker nodes from the service in action, and after this assignment, the task cannot be moved to another worker.

A task is a uni-directional and can go through a series of state i.e assigned, prepared, running, etc.

If the task fails, the manager will assign a new version of that task to another available node in the swarm.

Now let's look at it practically.

The cluster will have 3 worker node and a master node and we will be using docker-machine and virtualbox to get our virtual machines ready with docker-engine installed.

To check the status of docker-machine on your system

$ docker-machine -v
docker-machine version 0.16.0, build 702c267f

Bring up machines

Now bring one machine at a time (might take some time).

$ docker-machine create --driver virtualbox manager

$ docker-machine create --driver virtualbox worker1

$ docker-machine create --driver virtualbox worker2

$ docker-machine create --driver virtualbox worker3

After that list the machines.

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER     ERRORS
manager   -        virtualbox   Running   tcp://192.168.99.100:2376           v19.03.5   
worker1   -        virtualbox   Running   tcp://192.168.99.101:2376           v19.03.5   
worker2   -        virtualbox   Running   tcp://192.168.99.102:2376           v19.03.5  
worker3   -        virtualbox   Running   tcp://192.168.99.103:2376           v19.03.5  

Now let's create swarm cluster

SSH into the manager virtual machine and run the following commands to join as manager and worker individually on each node.

Initialize docker-swarm

$ sudo docker-machine ssh manager
docker@manager:~$ docker swarm init --advertise-addr 192.168.99.100

You must get a similar output

Swarm initialized: current node (q1hry94rx04jqk7r5hwiuogbv) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-2uir91nxhwob7m9mlyn7fm80meofeia9w2hsx59853cxe1p7a0-bo75x86zw7gv3f2wev80fdm4g 192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Join as manager ( if more managers needed)

$ docker swarm join-token manager                                                                                             
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-2uir91nxhwob7m9mlyn7fm80meofeia9w2hsx59853cxe1p7a0-c25v8ib80i4udjnrhush4sb3x 192.168.99.100:2377

Join worker

Now SSH into each worker machine and run below command to join as worker

$ sudo docker-machine ssh worker1
docker@worker1:~$docker swarm join --token SWMTKN-1-2uir91nxhwob7m9mlyn7fm80meofeia9w2hsx59853cxe1p7a0-bo75x86zw7gv3f2wev80fdm4g 192.168.99.100:2377
This node joined a swarm as a worker.

Follow the same steps for other workers as well.

Verification

Now verify that all nodes have joined the swarm cluster. For that go to the master node and run following command:

docker@manager:~$ docker node ls                                                                                                              
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
q1hry94rx04jqk7r5hwiuogbv *   manager             Ready               Active              Leader              19.03.5
w7j9tig7elf6cgafxu6kv8flg     worker1             Ready               Active                                  19.03.5
j92xu0td5lvxex1rk11w3bkmq     worker2             Ready               Active                                  19.03.5

As you can see that all the nodes have joined and also note the manager status to see which master node is elected as leader(in case if you have multiple master nodes).

Example : Create a Service with replicas

Now just to get an idea how services work in swarm cluster and for the sake of simplicity we will be deploying an nginx image .

docker@manager:~$ docker service create --name my-nginx-app --replicas 3 -p 80:80 surajsaini95/my-nginx-app:1.0                                                       
o19z75qzv99t5ytib1bldfxju
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

Also you can verify by listing the services on manager and it will also show that which node is currently executing the task dispatched.

docker@manager:~$ docker service ls                                                                                                           
ID                  NAME                MODE                REPLICAS            IMAGE               				PORTS
o19z75qzv99t        my-nginx-app        replicated          3/3                 surajsaini95/my-nginx-app:1.0       *:80->80/tcp
d

docker@manager:~$ docker service ps my-nginx-app                                                                                              
ID                  NAME                IMAGE               				 NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
ejxp2a4ajd9v        my-nginx-app.1      surajsaini95/my-nginx-app:1.0        worker3             Running             Running 2 minutes ago                       
p1caegrzcmqs        my-nginx-app.2      surajsaini95/my-nginx-app:1.0        manager             Running             Running 2 minutes ago                       
sgja8xcp6gp8        my-nginx-app.3      surajsaini95/my-nginx-app:1.0        worker2             Running             Running 2 minutes ago                       

Access the deployed app

Now for that go to your browser and hit any of the IP of the nodes which have joined the swarm cluster and it will present you the modified index page of Nginx. Note here that even the node which is not executing the task currently (worker1 in my case )will also present you the same output . This is the magic of service discovery provided by swarm.

Scaling up and Scaling down

To scale application up and down you can use the following command:

docker@manager:~$ docker service scale my-nginx-app=5                                                                                         
my-nginx-app scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   [==================================================>] 
2/5: running   [==================================================>] 
3/5: running   [==================================================>] 
4/5: running   [==================================================>] 
5/5: running   [==================================================>] 
verify: Service converged 

Now verify it again

docker@manager:~$ docker service ps my-nginx-app                                                                                              
ID                  NAME                IMAGE               				 NODE                DESIRED STATE       CURRENT STATE               ERROR               PORTS
ejxp2a4ajd9v        my-nginx-app.1      surajsaini95/my-nginx-app:1.0        worker3             Running             Running about an hour ago                       
p1caegrzcmqs        my-nginx-app.2      surajsaini95/my-nginx-app:1.0        manager             Running             Running about an hour ago                       
sgja8xcp6gp8        my-nginx-app.3      surajsaini95/my-nginx-app:1.0        worker2             Running             Running about an hour ago                       
uso3ywdnycsd        my-nginx-app.4      surajsaini95/my-nginx-app:1.0        worker1             Running             Running 10 seconds ago                          
od87wesfyx31        my-nginx-app.5      surajsaini95/my-nginx-app:1.0        worker1             Running             Running 10 seconds ago                     

Applying Rolling Updates

To smoothly update you app use the following command

docker@manager:~$  docker service update my-nginx-app --image surajsaini95/my-nginx-app:2.0                                                                     
my-nginx-app
overall progress: 5 out of 5 tasks 
1/5: running   [==================================================>] 
2/5: running   [==================================================>] 
3/5: running   [==================================================>] 
4/5: running   [==================================================>] 
5/5: running   [==================================================>] 
verify: Service converged 

Now swarm will shut down the old container one at a time and run a new container with the updated image. This ensures smooth rollout of updated with zero downtime.

Run the following command to see this process:

docker@manager:~$ docker service ps my-nginx-app                                                                                              
ID                  NAME                 IMAGE               				  NODE                DESIRED STATE       CURRENT STATE                 ERROR               PORTS
4xrxwy70ksgl        my-nginx-app.1       surajsaini95/my-nginx-app:2.0        worker3             Running             Running about a minute ago                        
ejxp2a4ajd9v         \_ my-nginx-app.1   surajsaini95/my-nginx-app:1.0        worker3             Shutdown            Shutdown about a minute ago                       
p42vctuv3twl        my-nginx-app.2       surajsaini95/my-nginx-app:2.0        manager             Running             Running about a minute ago                        
p1caegrzcmqs         \_ my-nginx-app.2   surajsaini95/my-nginx-app:1.0        manager             Shutdown            Shutdown about a minute ago                       
yhnfn7yefuzq        my-nginx-app.3       surajsaini95/my-nginx-app:2.0        worker2             Running             Running 53 seconds ago                            
sgja8xcp6gp8         \_ my-nginx-app.3   surajsaini95/my-nginx-app:1.0        worker2             Shutdown            Shutdown about a minute ago                       
0hm1fb13ghw1        my-nginx-app.4       surajsaini95/my-nginx-app:2.0        worker1             Running             Running 42 seconds ago                            
uso3ywdnycsd         \_ my-nginx-app.4   surajsaini95/my-nginx-app:1.0        worker1             Shutdown            Shutdown 50 seconds ago                           
1g7ca3qdauam        my-nginx-app.5       surajsaini95/my-nginx-app:2.0        manager             Running             Running about a minute ago                        
od87wesfyx31         \_ my-nginx-app.5   surajsaini95/my-nginx-app:1.0        worker1             Shutdown            Shutdown about a minute ago                

Draining a node

To shut down a particular node use the following command

docker@manager:~$docker node update --availability drain  worker3

Remove service

To remove a particular service from swarm cluster

docker@manager:~$docker service rm my-nginx-app

Leave cluster

docker@worker1:~$docker swarm leave

Stoping virtual machines

Now perform a final clean-up of the VMs which we have created for nodes.

$ docker-machine stop worker3
$ docker-machine stop worker2
$ docker-machine stop worker1
$ docker-machine stop master

Benefits of Docker-Swarm

We have seen what is docker-swarm and how it works, now let's see why we should use it and what are the benefits it offers :

  • Scaling through desired state reconciliation
  • Multi-host networking
  • Service discovery through embedded DNS
  • Load balancing
  • And many more...

Other Players

There are also other tools and platform available for the container orchestration purpose which are being used in the production environment as well. Some of them are :

  • Kubernetes
  • CoreOS Fleet
  • Mesosphere Marathon
  • And many more...

Thanks for Keeping Up...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment