Setup a Docker Swarm
Categories:
7 minute read
To create a Swarm you require:
A minimum of 2 Docker nodes that can communicte on a network over:
- 2377/TCP (client to Swarm over HTTPS)
- 7946/BOTH (Control plane)
- 4789/TCP (VXLAN-based overlay networking)
Initalize the Swarm on the first manager node
A node with Docker installed is a single-enginge node and you need to confogure Docker to run in Swarm mode so it can act as a multi-engine node. Logon to the first Docker node that you want to be a manager.
Obviously the IP and join details in this example will be different per setup
$ docker swarm init --advertise-addr 192.168.0.13:2377 --listen-addr 192.168.0.13:2377
Swarm initialized: current node (uuukt57mhnr02p7q0wk8kw10l) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0btobek7ebvbtk4c3ncs2laux2yqpz4roiufsl2cdwftt3dqat-a0uofotfgakzpixrt6ol6zm77 192.168.0.13:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
advertise-addr
configures the address and port to be advertised to other nodes using this Swarmlisten-addr
is where the node will accept traffic on
Add additional manager nodes
On the original manager node you can run the following command to retireve the command and values that can be copy/pasted onto new manager nodes to join them.
$ docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0btobek7ebvbtk4c3ncs2laux2yqpz4roiufsl2cdwftt3dqat-7kz5u6t75ptrqpc3kygwh7ssi 192.168.0.13:2377
Now logon onto the additional manager nodes and paste the command.
You can check that your managers are registered by running the following command.
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
uuukt57mhnr02p7q0wk8kw10l * node1 Ready Active Leader 20.10.17
iwft3pma29oo12nfddru1deid node2 Ready Active Reachable 20.10.17
swhtvpxigheh744unqc09hj7z node3 Ready Active Reachable 20.10.17
Add worker nodes
Repeat the same process on the worker nodes as the manager but you need the worker token instead. So on a manager node run the following command and copy the output to clipboard and paste it onto your worker nodes to join them.
$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-0btobek7ebvbtk4c3ncs2laux2yqpz4roiufsl2cdwftt3dqat-a0uofotfgakzpixrt6ol6zm77 192.168.0.13:2377
On any of the manager nodes, check to make sure your worker nodes are joined. Any node with no data in the MANAGER STATUS
column are worker nodes and the node with an *
simply identifies to you which node you are logged into and running the command from.
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
uuukt57mhnr02p7q0wk8kw10l node1 Ready Active Leader 20.10.17
iwft3pma29oo12nfddru1deid node2 Ready Active Reachable 20.10.17
swhtvpxigheh744unqc09hj7z * node3 Ready Active Reachable 20.10.17
7gr0zv9cw0dcwb6gg6mcxodxv node4 Ready Active 20.10.17
blpcfyi7hole1dx792zq17pvt node5 Ready Active 20.10.17
Create an overlay network
This command creats a new Docker overlay network called grinntec-net
which is available to all Docker nodes in the same Swarm.
$ docker network create -d overlay grinntec-net
o8iaoig5den15ha3tvir17cpc
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
9ae4bca4962e bridge bridge local
62dd78760eae docker_gwbridge bridge local
o8iaoig5den1 grinntec-net overlay swarm
8c93d83c35df host host local
adt8wii4ba2s ingress overlay swarm
2c5a36e59aea none null local
Deploy a container as a Service
Logged into one of the manager nodes run the following command to deploy an image to the worker nodes.
$ docker service create --name web-fe --network grinntec-net -p 8080:8080 --replicas 2 nginx
t9h19g5mhucy6v7evhmz344er
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
This command creates a new service with the name of web-fe
and to work on the overlay network call grinntec-net
, and told Docker to listen on port 8080
and translate that traffic to 8080
, two
replicas of the image are required and the image used in nginx
.
The service is saved as a configuration of the desired state of this service. As the Swarm monitors the web-fe containers, if the observed state does not match the desired state then the Swarm will work to ensure the desired state is achieved. This is typiclly when a worker node is offine and the number of replcias as dropped below the required number as per the current desired state for this container web-fe
.
You can see the observed state
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
t9h19g5mhucy web-fe replicated 2/2 nginx:latest *:8080->8080/tcp
Or a more detailed view using
$ docker service ps web-fe
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
j22zc3m5pzpz web-fe.1 nginx:latest node4 Running Running 8 minutes ago
1t2ayyc4v12b web-fe.2 nginx:latest node3 Running Running 8 minutes ago
Scale the service up
We’re seeing a lot of traffic, let’s scale up from 2 to 10 instances.
$ docker service scale web-fe=10
web-fe scaled to 10
overall progress: 10 out of 10 tasks
1/10: running [==================================================>]
2/10: running [==================================================>]
3/10: running [==================================================>]
4/10: running [==================================================>]
5/10: running [==================================================>]
6/10: running [==================================================>]
7/10: running [==================================================>]
8/10: running [==================================================>]
9/10: running [==================================================>]
10/10: running [==================================================>]
verify: Service converged
$ docker service ps web-fe
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
2u7oj8ere0jh web-fe.1 nginx:latest node2 Running Running 3 minutes ago
450ic1m7ij0f web-fe.2 nginx:latest node1 Running Running 3 minutes ago
iaui9yyp9sar web-fe.3 nginx:latest node1 Running Running about a minute ago
m8htwrriw7zh web-fe.4 nginx:latest node3 Running Running about a minute ago
lbl27juxx05t web-fe.5 nginx:latest node4 Running Running about a minute ago
64sfczr1jr63 web-fe.6 nginx:latest node3 Running Running about a minute ago
onogf97lkbpt web-fe.7 nginx:latest node4 Running Running about a minute ago
ihqio6csb2et web-fe.8 nginx:latest node5 Running Running about a minute ago
h4dx06cn1ewx web-fe.9 nginx:latest node5 Running Running about a minute ago
6sp9aux50ykg web-fe.10 nginx:latest node2 Running Running about a minute ago
Update the Service with a new version
A new version of the image has been released so we need to push it out to all 10 instances of the Service without downtime. The followwing command will update the web-fe
service to use the latest version of the nginx image
, with a rolling update configuration that updates 2 tasks
at a time and waits for 20 seconds
between each update. This rolling update strategy helps to minimize downtime during the update process.
$ docker service update --image nginx:latest --update-parallelism 2 --update-delay 20s web-fe
web-fe
overall progress: 10 out of 10 tasks
1/10: running [==================================================>]
2/10: running [==================================================>]
3/10: running [==================================================>]
4/10: running [==================================================>]
5/10: running [==================================================>]
6/10: running [==================================================>]
7/10: running [==================================================>]
8/10: running [==================================================>]
9/10: running [==================================================>]
10/10: running [==================================================>]
verify: Service converged
State of the Service during the update. Some are shutdown whilst upgrading. But you have multiples running to allow for the desired state.
$ docker service ps web-fe
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4qrjsjqzdgiu web-fe.1 nginx:stable node2 Running Running 1 second ago
2u7oj8ere0jh \_ web-fe.1 nginx:latest node2 Shutdown Shutdown 3 seconds ago
5mzx1icqp7x7 web-fe.2 nginx:stable node1 Running Running 53 seconds ago
450ic1m7ij0f \_ web-fe.2 nginx:latest node1 Shutdown Shutdown 54 seconds ago
d2pyk0zl77lu web-fe.3 nginx:stable node2 Running Running 1 second ago
1ggalbjr0g9e \_ web-fe.3 nginx:latest node2 Shutdown Failed 3 seconds ago "error while removing network:…"
24ifzyhu96hd web-fe.4 nginx:stable node3 Running Running about a minute ago
7c6owd7kvcf3 \_ web-fe.4 nginx:latest node1 Shutdown Shutdown about a minute ago
y0dxcybkmklq web-fe.5 nginx:stable node5 Running Running 27 seconds ago
pdujac0801kl \_ web-fe.5 nginx:latest node5 Shutdown Shutdown 29 seconds ago
8vv4hmm7iqfa web-fe.6 nginx:stable node3 Running Running 27 seconds ago
m6u7nu8qijkr \_ web-fe.6 nginx:latest node3 Shutdown Shutdown 29 seconds ago
z6op7153ufpj web-fe.7 nginx:stable node5 Running Running 53 seconds ago
fbcqknuqlcgn \_ web-fe.7 nginx:latest node5 Shutdown Shutdown 54 seconds ago
1gmx8zp4czde web-fe.8 nginx:stable node1 Running Running about a minute ago
aeh626vdw93r \_ web-fe.8 nginx:latest node3 Shutdown Shutdown about a minute ago
opi9vpc6lz8w web-fe.9 nginx:stable node4 Running Running about a minute ago
2pnqlhxpv3ov \_ web-fe.9 nginx:latest node4 Shutdown Shutdown about a minute ago
pp8ib1c5v0r9 web-fe.10 nginx:stable node4 Running Running about a minute ago
1zx5hidgt9dj \_ web-fe.10 nginx:latest node4 Shutdown Shutdown about a minute ago