According to the Docker documentation, Swarm mode is an advanced feature for managing a cluster of Docker daemons. Each instance of Docker Engine participating in the swarm is a node, and act as managers, to manage membership and delegation, and workers, which run swarm services. A given Docker host can be a manager, a worker, or perform both roles. You can run one or more nodes on a single physical computer or cloud server, but production swarm deployments typically include Docker nodes distributed across multiple physical and cloud machines.
In a development environment, where you probably don't have access to multiple physical devices to configure a swarm, a solution would be to create virtual machines (VMs), each of them running an instance of Docker Engine.
Last month, I wrote a tutorial about Multipass, a tool from Canonical that can be used to create Ubuntu virtual machines, and through this article, you will learn how to use it to configure the swarm. I've followed the instructions from this article, but I'll explain the general process and how you can deploy services in a swarm.
Virtual Machines
To create a virtual machine with Multipass, you would run the following command:
$ multipass launch --name node1 lunar
The above command would create a virtual machine, named node1
, with the following characteristics:
- 1 CPU
- 5GB of disk
- 1GB of RAM
Depending on the requirements of your development environment, the default configuration can be limited, and you may want to assign more resources. I suggest creating a VM with the following features if more resources are needed:
- 2 CPUs
- 8GB of disk
- 2GB of RAM
I'm running tests on a computer with 4 CPUs and 12GB of RAM, and assigning the above resources to each node won't affect the normal operation of the host.
Let's create a three-node cluster.
First, create a BASH script (init-instance.sh
):
NM=$1
multipass launch --name ${NM} lunar --memory 2G --disk 8G --cpus 2
multipass transfer install-docker.sh ${NM}:/home/ubuntu/install-docker.sh
multipass exec ${NM} -- sh -x /home/ubuntu/install-docker.sh
-
NM
is the variable that will get the name of the VM from the command line - Will launch a VM with custom configuration
- The
install-docker.sh
file will be transfered from the host to the VM - The script that will install Docker Engine on each node
Now create the script for installing Docker Engine on each node of the swarm.
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/u> "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install latest version
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Manage Docker as a non-root user
## Create the docker group
sudo groupadd docker
## Add your user to the docker group
sudo usermod -aG docker $USER
## Enable the docker daemon to run on system boot
sudo systemctl enable docker
The script will:
- Add Docker's official GPG key
- Add the repository to Apt resources
- Install latest version of Docker Engine
- Manage Docker as a non-root user
- Create the
docker
group - Add your user to the
docker
group
- Create the
Docker Swarm uses the overlay
driver by default, and it's not supported by the rootless mode. That's why Docker must be configured following the post-installation steps.
Now run the following command to create the manager node:
$ sh -x init-instance.sh manager
Then, create two worker nodes:
$ sh -x init-instance.sh worker1
$ sh -x init-instance.sh worker2
The Docker Engine instances are now running.
Initialize the Swarm
The swarm must be initialized in the manager node, and the worker1
and worker2
VMs must be added to the swarm as worker nodes.
Initialized the swarm:
$ multipass exec manager -- docker swarm init
You'll get the following output:
Swarm initialized: current node (fgjgd7qr4yg0dnlk8nurrqk9q) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5d9bj8wua4wy812hzl7vqc2r54yroy227i2oqkl27k3vzxdk7e-7na4j9souwf0s2yf6tmw5daiq 10.81.157.203:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
It will give you the token and command needed to add the worker nodes to the swarm. 10.81.157.203
is the IP address assigned by Multipass to the manager
VM.
Add the worker1
VM to the swarm as worker:
$ multipass exec worker1 -- docker swarm join --token SWMTKN-1-5d9bj8wua4wy812hzl7vqc2r54yroy227i2oqkl27k3vzxdk7e-7na4j9souwf0s2yf6tmw5daiq 10.81.157.203:2377
Add the worker2
VM to the swarm as worker:
$ multipass exec worker2 -- docker swarm join --token SWMTKN-1-5d9bj8wua4wy812hzl7vqc2r54yroy227i2oqkl27k3vzxdk7e-7na4j9souwf0s2yf6tmw5daiq 10.81.157.203:2377
The swarm is now configured. You can list the nodes in the swarm by running:
$ multipass exec manager -- docker node ls
Deploy a Service to the Swarm
Now that the swarm is configured, you can run standalone containers on each node but they won't be managed by the manager node, only services deployed to the swarm.
Let's deploy the first service, an Nginx server with three replicas.
$ multipass exec manager -- docker service create --name nginx --replicas 3 -p 80:80 nginx
- The
docker service create
command creates the service - The
--name
flag is used to assing a name to the service,nginx
- The
--replicas
flag specifies the number of replicas - The
-p
flag is used to open the port80
in the host to receive and redirect requests to the port80
in the container
You can check the running services with the following command:
$ multipass exec manager -- docker service ls
You'll get the following output:
ID NAME MODE REPLICAS IMAGE PORTS
5rflc7yq4pyg nginx replicated 3/3 nginx:latest *:80->80/tcp
To see which nodes are running the service, run the following command:
$ multipass exec manager -- docker service ps nginx
You'll get the following output:
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ysp4p3ut581a nginx.1 nginx:latest worker1 Running Running 6 minutes ago
7zozyfe4s8a5 nginx.2 nginx:latest worker2 Running Running 6 minutes ago
njdou1bmh4tm nginx.3 nginx:latest manager Running Running 6 minutes ago
To display details about a service in an easily readable format, run:
$ multipass exec manager -- docker service inspect --pretty nginx
It will display:
ID: 5rflc7yq4pygo7kxu8pq7ev7l
Name: nginx
Service Mode: Replicated
Replicas: 3
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: nginx:latest@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026
Init: false
Resources:
Endpoint Mode: vip
Ports:
PublishedPort = 80
Protocol = tcp
TargetPort = 80
PublishMode = ingress
If you want to delete the service, just type:
$ multipass exec manager -- docker service rm nginx
Conclusion
Through this article, you learned how to configure a swarm using virtual machines and you deploy your first service.
Top comments (0)