How to Setup Three Node Docker Swarm Cluster on Ubuntu 22.04

|
Last Updated:
|
|
Setup Three Node Docker Swarm Cluster on Ubuntu

How can I setup a Docker swarm? In this tutorial, you will learn how to setup three node Docker swarm cluster on Ubuntu 22.04. Docker Swarm is a cluster management and orchestration tool for Docker Engines.

Benefits of Docker Swarm

Some benefits of using Docker Swarm include:

  • Scalability: You can easily scale your application by adding or removing nodes from the swarm.
  • High availability: Swarm ensures that containers are automatically rescheduled in the event of a node failure to ensure that your applications are always available.
  • Load balancing: Swarm automatically distributes traffic to containers based on the available resources.
  • Easy management: You can use the Docker API and command-line interface to manage your swarm, making it easy to integrate with existing tools and processes.
  • Service Discovery: Docker swarm allows you to discover and connect to other services running in your swarm cluster.
  • Rolling Update: Swarm allows you to perform rolling updates to your nodes incrementally in a controlled manner.

Setting up Three Node Docker Swarm on Ubuntu 22.04

First of all, in a Docker swarm cluster environment, there exists different concepts;

  • Docker Node: this is a host running Docker engine. It can be a physical or virtual machine. A Docker node can run as a manager node, worker node or both.
  • Manager Node: These are the nodes run orchestration and cluster management functions. They are responsible for maintaining the desired state of the swarm. They dispatch units of work called tasks to worker nodes.
    • Note that by default manager nodes also act as a worker nodes. This means the scheduler can assign tasks to a manager node.
  • Worker Node: These are the nodes that receive and execute tasks dispatched from the manager nodes.
  • Tasks: A task is a running container which is part of a swarm service and managed by a swarm manager.
  • Service: A service is the definition of the tasks to execute on the manager or worker nodes.

In this setup, we have three Nodes;

NodeIP AddressRole of the Node
swarm01192.168.10.10manager, worker
swarm02192.168.10.20worker
swarm03192.168.10.30worker

Setup and Configure Static IP addresses on Docker Node

Ensure that you configure static IP addresses on your Docker swarm cluster nodes.

See how to configure static IP addresses using Netplan on Ubuntu systems;

Configure Static IP Addresses using Netplan on Ubuntu

Install Docker Engine on All Nodes

You need Docker engine installed on all nodes you intend to set them up as a swarm.

Since we are using Ubuntu 22.04 nodes in this guide, you can follow the link below to learn how to install and

Install Docker CE on Ubuntu

Open Required Protocols and Ports between Swarm Nodes

If you have firewall running on the Docker swarm cluster nodes, there are ports and protocols you need to allow between the swarm nodes;

These include;

  • TCP port 2377 for cluster management communications
  • TCP and UDP port 7946 for communication among nodes
  • UDP port 4789 for overlay network traffic
  • IP Protocol 50 (ESP) which is only applicable if you plan on creating an overlay network with encryption (--opt encrypted).

To open these ports/protocols, for example on nodes running Ubuntu;

On swarm01 node, to allow both swarm02 and swarm03;

for i in 192.168.10.20 192.168.10.30; do ufw allow from $i to any port 2377 proto tcp; done
for i in 192.168.10.20 192.168.10.30; do ufw allow from $i to any port 7946 proto tcp; done
for i in 192.168.10.20 192.168.10.30; do ufw allow from $i to any port 7946 proto udp; done
for i in 192.168.10.20 192.168.10.30; do ufw allow from $i to any port 4789 proto udp; done
for i in 192.168.10.20 192.168.10.30; do ufw allow from $i to any proto esp; done

Do the same on other nodes, replacing the source IP addresses accordingly.

Start Docker Engine Daemon

On all the Docker swarm cluster nodes, ensure Docker service is running;

systemctl is-active docker

Output should be active. Otherwise, start and enable Docker service to run on system boot;

systemctl enable --now docker

Initialize a Docker Swarm Cluster on Manager Node

It is now time to create and initialize a Docker swarm. Thus, login to Manager node and create a swarm.

Docker swarm can be controlled via the docker swarm command.

To see command line usage/help, run;

docker swarm --help
Usage:  docker swarm COMMAND

Manage Swarm

Commands:
  ca          Display and rotate the root CA
  init        Initialize a swarm
  join        Join a swarm as a node and/or manager
  join-token  Manage join tokens
  leave       Leave the swarm
  unlock      Unlock swarm
  unlock-key  Manage the unlock key
  update      Update the swarm

Run 'docker swarm COMMAND --help' for more information on a command.

Thus, to initialize a Docker swarm, simply use docker swarm init as follows.

docker swarm init --advertise-addr <ip|interface>[:port]

Where IP is the Manager node’s IP address that will be reachable by other swarm nodes.

docker swarm init --advertise-addr 192.168.10.10

The command will initialize a swarm and set the current node as the Manager.

Sample output;

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

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

    docker swarm join --token SWMTKN-1-358ntjh2bqw4jrcxq6wlch73yor6csqa3l050h3dgspxq6ti3x-ejhwnh99irv0rudgvgezm59qd 192.168.10.10:2377

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

First node, which is manager node has now been created. You can list Docker swarm nodes using the command;

docker node ls

Sample output;

ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
imt55exvbkyo2zzdq2xn2ebxl *   swarm01    Ready     Active         Leader           20.10.22

You can also use the command below to get status of swarm;

docker info

If you loose the swarm cluster join token, you can always display using docker swarm join-token option.

For example, to show the manager join token;

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

    docker swarm join --token SWMTKN-1-358ntjh2bqw4jrcxq6wlch73yor6csqa3l050h3dgspxq6ti3x-26km5yegdozlcq1lxno23x0w0 192.168.10.10:2377


To show just the token only;

docker swarm join-token -q manager

To show the worker join token;

docker swarm join-token worker

Sample output;

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

    docker swarm join --token SWMTKN-1-358ntjh2bqw4jrcxq6wlch73yor6csqa3l050h3dgspxq6ti3x-ejhwnh99irv0rudgvgezm59qd 192.168.10.10:2377

Add Worker Nodes into Docker Swarm Cluster

Next, to make the cluster whole, you need to add worker nodes into it.

As mentioned above, we will use our swarm01 as both manager and worker node. By default manager nodes also act as a worker nodes. This means the scheduler can assign tasks to a manager node.

Add swarm02 into Docker swarm

Login to swarm02 node or whatever your second node is and add it to the swarm cluster.

The command to use to add worker nodes into the swarm cluster is given when you initialize a swarm.

root@swarm02:~# docker swarm join \
--token SWMTKN-1-358ntjh2bqw4jrcxq6wlch73yor6csqa3l050h3dgspxq6ti3x-ejhwnh99irv0rudgvgezm59qd \
192.168.10.10:2377

If the command above successfully runs, you should see such an output;

This node joined a swarm as a worker.

Similarly, add your third node, in this example setup is swarm03 into the cluster;

root@swarm03:~# docker swarm join \
--token SWMTKN-1-358ntjh2bqw4jrcxq6wlch73yor6csqa3l050h3dgspxq6ti3x-ejhwnh99irv0rudgvgezm59qd \
192.168.10.10:2377

Get Docker Swarm Node Details

Docker provides various commands that you can use to get various information about the nodes on the swarm cluster.

The command is;

docker node

For example, you can list the available nodes on the swarm cluster;

docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
imt55exvbkyo2zzdq2xn2ebxl *   swarm01    Ready     Active         Leader           20.10.22
yzp9ppjxte94w3hk1bvy1bc6p     swarm02    Ready     Active                          20.10.12
ejtziqfxfk1gsvt11x8edo22d     swarm03    Ready     Active                          20.10.22

All the three nodes in the swarm now with swarm01 being the leader! You have now setup three node Docker swarm cluster.

The * (asterisk) adjacent to the node ID shows the node you are currently connected to.

Some of the swarm services/nodes state;

  • Ready: The node is available and ready to accept tasks.
  • Disconnected: The node has been disconnected from the swarm, but is still running.
  • Pending: The node is being added to the swarm but is not yet ready to accept tasks.
  • Down: The node is down and not accepting tasks.
  • Unknown: The node’s status is not known, usually caused by a network error or other connectivity issues.
  • Drain: The node has been drained, meaning that it is not accepting new tasks, but existing tasks will continue to run until completion.
  • Active: The scheduler can assign tasks to the node.
  • Pause : No new tasks can be assigned to the node by the scheduler, but existing tasks remain running.
  • Leader: The node is the current primary manager node that makes all swarm management and orchestration decisions for the swarm.
  • Reachable: Is a secondary manager that is eliogible to become a primary manager in case the leader node becomes unavailable.
  • Unavailable: The node is a manager but it can’t communicate with other managers in the cluster.

You can also get a detailed information on one or more nodes;

docker node inspect <node-name>

e.g

docker node inspect swarm03

Sample output;

[
    {
        "ID": "ejtziqfxfk1gsvt11x8edo22d",
        "Version": {
            "Index": 20
        },
        "CreatedAt": "2023-01-28T10:58:56.486765341Z",
        "UpdatedAt": "2023-01-28T10:58:56.561125458Z",
        "Spec": {
            "Labels": {},
            "Role": "worker",
            "Availability": "active"
        },
        "Description": {
            "Hostname": "swarm03",
            "Platform": {
                "Architecture": "x86_64",
                "OS": "linux"
            },
            "Resources": {
                "NanoCPUs": 2000000000,
                "MemoryBytes": 2071773184
            },
            "Engine": {
                "EngineVersion": "20.10.22",
                "Plugins": [
                    {
                        "Type": "Log",
                        "Name": "awslogs"
                    },
                    {
                        "Type": "Log",
                        "Name": "fluentd"
                    },
                    {
                        "Type": "Log",
                        "Name": "gcplogs"
                    },
                    {
                        "Type": "Log",
                        "Name": "gelf"
                    },
                    {
                        "Type": "Log",
                        "Name": "journald"
                    },
                    {
                        "Type": "Log",
                        "Name": "json-file"
                    },
                    {
                        "Type": "Log",
                        "Name": "local"
                    },
                    {
                        "Type": "Log",
                        "Name": "logentries"
                    },
                    {
                        "Type": "Log",
                        "Name": "splunk"
                    },
                    {
                        "Type": "Log",
                        "Name": "syslog"
                    },
                    {
                        "Type": "Network",
                        "Name": "bridge"
                    },
                    {
                        "Type": "Network",
                        "Name": "host"
                    },
                    {
                        "Type": "Network",
                        "Name": "ipvlan"
                    },
                    {
                        "Type": "Network",
                        "Name": "macvlan"
                    },
                    {
                        "Type": "Network",
                        "Name": "null"
                    },
                    {
                        "Type": "Network",
                        "Name": "overlay"
                    },
                    {
                        "Type": "Volume",
                        "Name": "local"
                    }
                ]
            },
            "TLSInfo": {
                "TrustRoot": "-----BEGIN CERTIFICATE-----\nMIIBajCCARCgAwIBAgIUU/SWwBZeMD4eXlmeJQKuKjlghK4wCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMjMwMTI4MDkzOTAwWhcNNDMwMTIzMDkz\nOTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABODAkPhhZZtB4nyI94gpSoKfzEYUOFtYa0K7bR2Y75fAfpC0YCwgqkh/KQi9\nQ5Y21sGspeOiqzJb+Ai/GObTPHSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBR3p6FR2jgVw3H3jRut8cHFxL4KPDAKBggqhkjO\nPQQDAgNIADBFAiB0BCjJCUDsrELEZwFmGCwUZVENBJTuE57VwGZ0J/JvAwIhANM5\nlrJQwekBjATSJoYNvXwGnfjEwZhB3F1ZIfP3XOtH\n-----END CERTIFICATE-----\n",
                "CertIssuerSubject": "MBMxETAPBgNVBAMTCHN3YXJtLWNh",
                "CertIssuerPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4MCQ+GFlm0HifIj3iClKgp/MRhQ4W1hrQrttHZjvl8B+kLRgLCCqSH8pCL1DljbWwayl46KrMlv4CL8Y5tM8dA=="
            }
        },
        "Status": {
            "State": "ready",
            "Addr": "192.168.10.30"
        }
    }
]

for more commands, check;

docker node --help

Promote a Worker Node to Manager Node

How do I promote a worker to manager in docker Swarm? Yes, it is possible to promote a worker node into a manager node in docker swarm cluster. Having multiple docker swarm manager nodes ensures that if a leader manager fails for some reasons, another Manager in the cluster can assume the managerial roles of scheduling and re-balance tasks to match the desired state.

So, to promote a node, use the command docker node promote <NODE1 NODE2 NODEN>, where NODEN is the hostname current node in the cluster. This command has to be executed on the manager node.

For example, this commands promotes swarm worker node swarm02 into manager node.

docker node promote swarm02

You can confirm that the node is now a manager;

docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
imt55exvbkyo2zzdq2xn2ebxl *   swarm01    Ready     Active         Leader           20.10.22
yzp9ppjxte94w3hk1bvy1bc6p     swarm02    Ready     Active         Reachable        20.10.12
ejtziqfxfk1gsvt11x8edo22d     swarm03    Ready     Active                          20.10.22

Similarly, you can demote a node from manager to just a worker using docker node demote command.

docker node demote swarm02

You can also remove a node from the cluster by running the command, docker swarm leave, on the same node you are removing from cluster.

Other Tutorials

How to Deploy WordPress as a Docker Container

How to Install Docker Resource Usage Extension

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
Kifarunix
Linux Certified Engineer, with a passion for open-source technology and a strong understanding of Linux systems. With experience in system administration, troubleshooting, and automation, I am skilled in maintaining and optimizing Linux infrastructure.

Leave a Comment