Everything you need to know about Docker Swarm
Tags: docker, devops, linux, swarm
Published: 2021-05-23 05:16:10

##Introduction

Docker is a free and open framework for building, delivering, and running apps. Docker allows you to decouple your code from your hardware, allowing you to easily deliver apps. You will handle the infrastructure the same way you manage your apps with Docker. One of the characteristics you have with docker is that you can run multiple docker environments in the same host environment. 
However, docker may be able to maintain only a certain number of containers, because it runs on a single node. But what if someone wants to work with or develop thousands of containers.

This is where Docker swarm comes into the picture. A docker swarm is the virtualization of the large number of nodes(running Docker engine) running in a cluster. These nodes can communicate with each other, helping developers to maintain multiple nodes in a single environment.


##Docker swarm

A swarm mode consists of Multiple Docker hosts which serve as managers (to handle membership and delegation) and workers which run swarm services. A Docker host may be a manager, a worker, or both at the same time. You determine the optimum state of service when you develop it (number of replicas, network and storage resources available to it, ports the service exposes to the outside world, and more). Docker strives to keep the optimal state. Docker schedules a worker node's activities on other nodes if that node becomes inaccessible. A job, as opposed to a standalone container, is a running container that is part of a swarm service and operated by a swarm manager.

When you're in swarm mode, you can change the configuration of a service, including the networks and volumes it's connected to, without having to restart it manually. Docker will upgrade the configuration, avoid any service tasks that have out-of-date configurations, and start new ones that fit the desired configuration.
So, the difference between swarm mode and standalone docker containers is that, when in swarm mode only managers can manage containers or swarm, unlike standalone containers which can be started on any daemon. But, the daemon can participate in swarm mode as a manager or worker, or both.


##Docker swarm architecture
![architecture diagram](https://camo.githubusercontent.com/2414d3a74f17d5601aa0abb140ca97ea3eab8ad4/68747470733a2f2f692e706f7374696d672e63632f4d4b4850383959792f737761726d2e6a7067)
Previously, we have used terms such as manager, worker, nodes, etc, Now let us try to understand what it means and how the docker swarm works.

###Node
A node is a Docker engine instance that is part of the swarm. This can also be thought of as a Docker server. One or more nodes may operate on a single physical device or cloud server. But in development, these swarm cluster nodes can be spread over several machines on the cloud.
There are two types of nodes, a manager node, and a worker node.

+ Manager
In the above image, we can see a swarm manager who is responsible to manage what a docker worker does. It maintains track of all of its workers' whereabouts. Docker Manager knows what job the worker is working on, what task it has been allocated, how assignments are distributed to all jobs, and whether the worker is up and running.
Docker Manager's API is used to build a new service and orchestrate it. Assigns tasks to workers using the worker’s IP addresses.

+ Worker
The Docker Manager has complete power over a Docker Worker. The Docker Worker accepts and executes the tasks/instructions that the Docker Manager has delegated to it. A Docker Worker is a client agent that informs the manager about the state of the node it’s been running on through a REST API over HTTP protocol.


##services
The tasks to be executed on the manager or worker nodes are described by a service. It is the swarm system's core mechanism and the main point of user engagement with the swarm.
When you create a service, you also create containers and also specify tasks, which must be executed inside them.
The swarm manager distributes a certain number of replica tasks among the nodes in the replicated resources model depending on the scale you set in the desired state.

+ Load Balancing
To expose the resources you want to make available externally to the swarm, the swarm manager uses ingress load balancing. The swarm manager can automatically add a PublishedPort to the service automatically or manually configure one. If you don't mention a port, the swarm manager assigns a port between 30000 and 32767 to the operation.

External modules, such as cloud load balancers, can access the service through the PublishedPort of any node in the cluster. regardless of whether that node is actually performing the service's task. Ingress links are routed to a running task instance by all nodes in the swarm.


##Swarm features

After looking at what the docker swarm is and its related terminology, let us see what are the different features that swarm mode offers on the docker engine

+ Use the Docker Engine CLI to create a swarm of Docker Engines where you can deploy application services. You don’t need additional orchestration software to create or manage a swarm.
+ The Docker Engine manages some specialization at runtime, rather than managing distinction between node roles at deployment time. The Docker Engine can be used to deploy both manager and worker nodes. This means that a swarm can be created on just a disc image.
+ Docker Engine takes a declarative approach of defining the optimal state of your application stack's different resources. For example, a web front-end server with message queueing services and a backend database might be described as an application.
+ You should declare the number of tasks to be performed with each service. When the swarm manager scales up or down(this means that we are scaling up or down the number of services or containers), it automatically adapts to preserve the desired environment, by adding or deleting tasks.
+ The swarm manager node checks the cluster status continuously and reconciles any inconsistencies between the current state and the target state. For instance, you set up a service of running 10 container replicas on 5 workers, and two of the replicas on one of the worker crashes. Then, the manager creates two more replicas and assigns them to the worker who is up and running.
+ A network overlay for your services may be specified. When the application is initialized or modified the swarm manager immediately assigns addresses to the containers in the overlay network. The ports may be shown to an external load balancer for the utilities. Internally, you should decide how service containers can be distributed between nodes.

Now, let us get into some practical, we are going to create a cluster, add two worker nodes and then deploy services to that swarm.
Pre-requisites:
1. Three Linux machines, that can communicate over a network
2. Docker installed on all three of them.

This tutorial includes three Linux hosts with Docker-enabled and network-compatible communications. They can be physical, virtual, or Amazon EC2 instances or otherwise hosted.
One will be a manager and the other two will be workers.
We are going to use three Linux machines hosted on AWS, that is EC2 instances.

While creating EC2 instances add the following rules in the security group as follows:
The following ports must be available. On some systems, these ports are open by default.
+ TCP port 2377 for cluster management communications
+ TCP and UDP port 7946 for communication among nodes
+ UDP port 4789 for overlay network traffic

![aws image-1](https://lh6.googleusercontent.com/_dO-z3KAK_eJK8pvZRpa4ABb0eQShKWCu-XrTlt6FEZb1vAe9JHBTzlGr_hMth7iNuD8I7NCxhMPg42S_gIKcYIaQZK7HHLCo9apriyatb3AA2A7uqkmG5clAIUiI5TcRilRiOA)
While creating the manager machine add these rules.
Then while creating the worker nodes use the same security group created for the manager machine.

![aws image-2](https://lh3.googleusercontent.com/l_zk1msM6Do4-Vqxwu5-E8ae1WwH2cvlPhhmjUGuTC_uOQQhQEexoz99ihbSlL61ie6ER7a_YzX1Y-n8rzC0qGUu_hIESTz_M4aRv0cU)
Next, ssh into all the machines and install docker-engine.
Use the following commands to install docker-engine on all three machines.
+ Update and add packages of the apt installation index so that apt can use an HTTPS repository.
```
$ sudo apt-get update
```
```
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
```
+ Add Docker’s official GPG key:
```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg 
```
+ Use the following command to set up the stable repository
```
$ echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
+ Install docker engine
```
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
```
Repeat this for all the three machines.

You are able to create a swarm after you have completed all the setup steps. Ensure that the host machines are running the Docker Engine daemon. Open a terminal and ssh on the computer where the manager node must be executed.

Run the following command to create a new swarm:
```
$ docker swarm init --advertise-addr <MANAGER-IP>
```
We have a manager machine with IP 172.31.80.181, so the command is:
```
$ docker swarm init --advertise-addr 172.31.80.181
```
![image-1](https://lh5.googleusercontent.com/bBObNBdbEYxnX9cqfpFSSegsWKvj8_7L2VC80xfUUAD6mZ6UkjmVpO-ygplavIYnwWIVlx_oEK8jeyojBo4PkTI0QO7utj47hXFijn7dW7gBpqNoOnKh0U3gRqUYAjJywf4WhDc)
The --advertise-addr flag configures the manager node as 172.31.80.181 to publish its address. The other swarm nodes must have access to the IP address of the manager.
The output consists of commands to attach new nodes to the swarm. Nodes will enter as managers or workers according to the flag value.

To see the current state you can use docker info:
```
$ sudo docker info
```
![image-2](https://lh3.googleusercontent.com/KOYu_m2HaHpa8THEDQJ4To4HShgp0hCZWgTOZYvb8igh_kKtLP8oIO1-DG1hRC5NfIKV5V0eZXUPBBRZzmSIeM0fAF7IO6EKfGN7j6d6)
In this above image, we can see that there are no containers running on the docker server and the swarm flag is active. This also prints out the clusterId and number of managers and nodes etc.

To view information about nodes use the command
```
$ docker node ls
```
![image-3](https://lh4.googleusercontent.com/AFe1gqFm_LdpMicIK-ie3ii41KAwuL1QTaBkRwEV5wcHHHF3h4kbOPSqqgT0OSq3vWrnad0rGT7hhinjQvBt5hoMQGBY9wy13kDJiGqYRSm_tGFHM7wmZMQstWHuAbq2IoBvW20)
The * next to the ID represents that this is the node we are currently connected to.
The swarm mode Docker Engine names the machine hostname node automatically.

##Adding Worker Nodes
It's time to add worker nodes to the above-created swarm cluster.
ssh into the machine where you want to run your worker.
Now, we must run the output of docker swarm init as a command in this worker terminal:
```
$ docker swarm join --token SWMTKN-1-05ikz9ituzi3uhn1dq1r68bywhfzczg260b9zkhigj9bubomwb-a003dujcz7zu93rlb48wd0o87 172.31.80.181:2377 
```
![image-4](https://lh5.googleusercontent.com/ZhQ5C7fxOSzq6sV4BBMG-AFhxFjsPokbTfkJeRo74Tn0dziXWUkPwUNXAW9kjyiJRYub1Vx-mUzoiC3tZKh0AZUonLYP9ydUq8VZ7o9CB4P1dLg56T-3DDJv-HpZ-JR6IW8E2GM)

You can execute the following command on a manager node to retrieve a worker's join command if your command is not available:
```
$ docker swarm join-token worker
```
![image-5](https://lh3.googleusercontent.com/HEZYxK-EUszv77JLLWilxNWdGkV633JXATrNJ7N0M1SfataG62KcyuVtSfDvLjzUwgJiXFpGbya6V_4qr8ReCBgeqvPWrEbsKKEzS54bbv4Dl3P_OGjuxclXgY4hRpEOcJNa_D8)
Do the same with the other worker as well. SSH into another machine and run the join command.

To view worker nodes, open a terminal and ssh in the machine that runs the manager node and execute the Docker node ls command:
```
$ docker node ls
```
![image-6](https://lh6.googleusercontent.com/RI-b7Fx5rA3e-8PPWpZskO-OCQSSl-AnUfdbL_1UJBW5KbKGYjYeEIKgV6Y8IAkJNduJHdz0bFVXumx_9ZwPNLXM95nicPFTiUKs2ckgT-hTyG1Qo7vlgWSQFg2qtHeG_nlQvxQ)
The manager nodes in the swarm are determined by the column MANAGER. Worker1 and worker2 are identified as working nodes by the empty state in this column.



##Deploy service to the swarm
Now we have a cluster with a manager and two workers. We can now deploy services to the swarm cluster.

Open the terminal into the manager node after SSH, and run the following command:
```
$ docker service create --replicas 1 --name helloworld alpine ping docker.com
```
Let's break down the above command:
+ docker service create: to create a service
+ --replicas: this flag indicates the desired state of 1 running instance.
+ --name: used to name the service
+ alpine ping docker.com: this indicates that the services is going to run alpine Linux and the primary command to run inside the instance or service is ping docker.com
![image-7](https://lh5.googleusercontent.com/woerrRuAFhnZOahzy1jmOERTxQZoZOfLzpnVlT_IbxSJwu54Py313sSJVMGVTRjt4oV7cwkxQ727tuF3--Bi-H4F9__6j1BQmBN2PQRzVYxgTK7JYnYOG3MgUvHgL7Wfreo0EZs)



To see the list of running services run the below command:
```
$ docker service ls
```
![image-8](https://lh3.googleusercontent.com/Y9FtdwlgrlqwJn_bYEnVX7KrXlNeRToeZ5tkk1edVceK0aohCDYwIezTCAZP8btEmd0dfWJvbMWJouEem4WrxOKVcLH5v0qqhKbN7yC9UUAtGPHF51lUVkC53XXJtZZVXCeO1ZI)
This image lists the name of the service we just create and the number of replicas, along with the base image, which is alpine.



##Conclusion
In this article, We started with a description of the docker, then we discussed the need for multiple docker hosts. We then described what is docker swarm, its uses, and its working through docker swarm architecture, we also covered, different docker swarm terminologies like manager node and worker node. After we thoroughly understood the docker swarm we stated to implement it or run services in a swarm cluster. We started with creating 3 Linux hosts in AWS as EC2 instances along with the security group configuration(by adding TCP and UDP rules).
We looked at how to create or initialize a swarm cluster through a manager node, then we added a couple of worker nodes to the same cluster. TO conclude we added a service running Linux alpine to run a ping command.
Also this is my first article on dev.to, and really enjoyed writing it.

liked the post? 
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/I2I639WWJ)