How to setup a swarm cluster
Tags: docker
Published: 2021-02-13 11:18:09

# How to setup of a swarm cluster

This is a how to setup a swarm cluster (which commands to use and how).
For the cluster setup I used the [play with docker](https://labs.play-with-docker.com/).
I assume that you know what is a worker or a manager, if not please check [here]((https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/)).

## swarm initialization

Initializing a swarm:

- **docker swarm init**

```sh
docker swarm init --advertise-addr  192.168.0.28
```

command output:

```sh
$ docker swarm init --advertise-addr 192.168.0.28
Swarm initialized: current node (uckrsawa44hpn8aiyg7alplav) is now a manager.

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

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.0.28:2377

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

After executing the above command, the node becomes a **manager**.

*Check the command effect:*

- **docker info**

command output:

```sh
Swarm: active
  NodeID: uckrsawa44hpn8aiyg7alplav
  Is Manager: true
  Managers: 1
  Nodes: 1
```

the output informs us that the current node is a manager (e.g. Is manager: true)

- **docker node ls**

command output:

```sh
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
uckrsawa44hpn8aiyg7alplav *  manager1  Ready   Active        Leader
```

The * signifies the current node that we are connected (for now is the only one).
Moreover, the column MANAGER STATUS informs us that the node is the leader of the swarm cluster (also a manager).

## Adding a worker

After you have instantiated a swarm, the output command displays the command that you have to execute on the
node in order to join the swarm.

- **docker swarm join --token [TOKEN] [IP:2377]**

```sh
docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
192.168.0.28:2377
```

Or you can execute the command **docker swarm join-token worker**.

*Check the command effect:*

- **docker node ls**

The above command can be executed in a manager node, if the node that you are working on is not a manager
you see the bellow message:

```sh
Error response from daemon: This node is not a swarm manager. Worker nodes can\'t be used to view or modify cluster state.
Please run this command on a manager node or promote the current node to a manager.
```

In a manger node:

```sh
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
uckrsawa44hpn8aiyg7alplav *   node1      Ready     Active         Leader           20.10.0
enemrsanyskdatph4kevf93tc     node2      Ready     Active                          20.10.0
```

You see in the second line that in node 2 the MANAGER STATUS is empty, this indicates that the node2 is a worker.

## Make a worker node manager

- **docker node update --role manger [HOSTNAME]**

In the current cluster setup node2 is a worker, in order to update the node2 to manager
in the manager node (e.g. node1) execute the command:

```sh
docker node update --role manger node2
```

*Check the command effect:*

- **docker node ls**

```sh
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
uckrsawa44hpn8aiyg7alplav *   node1      Ready     Active         Leader           20.10.0
enemrsanyskdatph4kevf93tc     node2      Ready     Active         Reachable        20.10.0
```

You see now that the  MANGER STATUS changed from empty to Reachable.

## Adding a manager

- **docker swarm join-token manager**

In order to join to a swarm cluster as a manager, you execute the above command in a manager node
and you paste the output in the node that you want to join as a manager.

The above command output (on a manager node):

```sh
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-15hse3mbkcunho3vd03zsgx4ak6zzjh8yi6rckee3pn41dhl8s-3lm0r9ohlxuls3vbrf0hp44ky 192.168.0.28:2377
```

*Check the command effect:*

- **docker node ls**

```sh
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
uckrsawa44hpn8aiyg7alplav     node1      Ready     Active         Leader           20.10.0
enemrsanyskdatph4kevf93tc     node2      Ready     Active         Reachable        20.10.0
u1gh6f5phbv68251oqfzwyk9e *   node3      Ready     Active         Reachable        20.10.0
```

node3 is added to cluster as manager (e.g. MANGER STATUS is Reachable)

## Create services in a cluster

Let's say that I want to run three containers/tasks, one container/task per node
(e.g. one container in node1, one in node2 and one in node3).

In a manager node execute the command (the container is created from alpine image):

- **docker service create --replicas 3 alpine ping 8.8.8.8**

*Check the command effect:*

- **docker service ls**

output:

```sh
ID             NAME             MODE         REPLICAS   IMAGE           PORTS
nn7rcguvkbal   trusting_allen   replicated   3/3        alpine:latest
```

from the output we can see that we have three replicas (3/3) running.

- **docker service ps [service_name]**

Using the above command you can inspect:

- which nodes are executing the given service
- the state of the service (e.g. running, starting etc)

the output for the service name trusting_allen looks like:

```sh
ID             NAME               IMAGE           NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
plnrxhc9izj7   trusting_allen.1   alpine:latest   node2     Running         Running 4 minutes ago
jjhbo65o785z   trusting_allen.2   alpine:latest   node3     Running         Running 4 minutes ago
rwwlu5n1lfbr   trusting_allen.3   alpine:latest   node1     Running         Running 4 minutes ago
```

As wee se from the output each node execute one task/containers (--replicas 3) and the status is running.

## Summary/Cheat sheet

- initialize a cluster, current node becomes a manager/leader: **docker swarm init**
- inspect nodes that are part of the cluster, only manager node can execute the command: **docker node ls**
- add a worker/manager to a swarm:
  1. execute **docker swarm join-token [manager|worker]** (command is executed in a manager node)
     If you want to add a manager you write manger as the last argument.
     If you want to add a worker you write worker as the last argument.
  2. copy and paste the command output in the node that you are interested to add as manager/worker
- update a worker to manager: **docker node update --role manger [HOSTNAME]**
- create a service with replicas: **docker service create --replicas [number of replicas] [image]**
- inspecting service sin the cluster: **docker service ls**
- inspecting a specific service (current status, which nodes runs the task etc.): **docker service ps [service_name]**