I tried to provide at my best basic tutorial on Docker Swarm on how to configure/join workers to manager(master) nodes and run services. orchestrating service through Docker Swarm.
After reading this blog, you would definitely come across basic idea on the container orchestration...
What is container Orchestration ?
Container Orchestration systems is where the next action is likely to be in the movement towards Building, Shipping, Running containers at scale. The list of most popular software that currently provides a solution for this are Kubernetes, Docker Swarm and others.
Why do we need container orchestration ?
Imagine you might had to run hundred of containers, you can easily see if they are running in a distributed mode, ensuring your cluster is up and running etc
Few features are:
- health checks on containers
- Launch exact count of containers for an particular Docker image
- Scaling number of containers up and down depending on the load
- Perform rolling update on softwares across containers
- ... more
I hope reader would be aware of Docker basic commands ..
The first step is to create a set of Docker machines that will act as nodes in our Docker Swarm. I am going to create 5 Docker Machines, where one of them will act as the Manager (Leader) and the other will be worker nodes.
I will be using below Docker machines as hostnames with their roles ..
node1(192.168.0.28) <- Manager
node2(192.168.0.27) <- Worker
node3(192.168.0.26) <- Worker
node4(192.168.0.25) <- Worker
node5(192.168.0.24) <- Worker
Creating Swarm Cluster
Once your machines are setup, you can now proceed with setting up swarm. The first thing to do is to initilize swarm. Login to node1 and initilize swarm
root@node1# docker swarm init --advertise-addr 192.168.0.28
Swarm initialized: current node (wga1nmopjbir2ks92rxntj9dz) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-13fkd65lfhh2d1yb31fd59tuk 192.168.0.28:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
root@node1#
You will also notice that the output mentions the docker swarm join command to use in case you want another node to join as a worker. Keep in mind that you can have a node join as a worker or as a manager. At any point in time, there is only one LEADER and the other manager nodes will be as backup in case the current LEADER opts out.
root@node1# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
wga1nmopjbir2ks92rxntj9dz * node1 Ready Active Leader
root@node1#
You could use tokens to join either other nodes as a manager or worker. see below on how to get tokens ?
Joining as Worker Node
To find out the join command for a worker, trigger below command
root@node1# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-13fkd65lfhh2d1yb31fd59tuk 192.168.0.28:2377
root@node1#
Joining as Manager Node
root@node1# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-a9j3npou6i5pb90fs9h92ez3u 192.168.0.28:2377
root@node1#
Adding worker nodes to Swarm
you need to SSH to node{2..5} and join them as workers.
root@node2# docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-13fkd65lfhh2d1yb31fd59tuk 192.168.0.28:2377
This node joined a swarm as a worker.
root@node2#
root@node3# docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-13fkd65lfhh2d1yb31fd59tuk 192.168.0.28:2377
This node joined a swarm as a worker.
root@node3#
root@node4# docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-13fkd65lfhh2d1yb31fd59tuk 192.168.0.28:2377
This node joined a swarm as a worker.
root@node4#
root@node5# docker swarm join --token SWMTKN-1-3j0boiejfa0dhp82ar51fl1yvsscuwk3n1jppvzafvbv6mycyo-13fkd65lfhh2d1yb31fd59tuk 192.168.0.28:2377
This node joined a swarm as a worker.
root@node5#
Login to manager node(node1) and check the status
root@node1# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
wga1nmopjbir2ks92rxntj9dz * node1 Ready Active Leader
4wzc1nesi1hxa3ekq753w0koq node2 Ready Active
4nrsuwslw149mg4nwlipmxxlo node3 Ready Active
jbdizz7gvfdz03shtgu23h8kv node4 Ready Active
afpi9osujgcsqkdiqg4tnz6nb node5 Ready Active
root@node1#
you could also execute 'docker info' and check out swarm section.
Swarm: active
NodeID: wga1nmopjbir2ks92rxntj9dz
Is Manager: true
ClusterID: 7xpyowph2y1q2q12rhrkzzfei
Managers: 1 ==> Swarm markered as 1 manager among total 5 active nodes
Nodes: 5
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 3
Dispatcher:
Heartbeat Period: 5 seconds
CA Configuration:
Expiry Duration: 3 months
Force Rotate: 0
Autolock Managers: false
Root Rotation In Progress: false
Node Address: 192.168.0.28
Manager Addresses:
Testing Swarm orchestration
we have swarm up and running, its time to schedule our containers on it. we will not focus on the application and no need for us to worry where the appilcation is going to run.
we will tell the manager to run the containers for us and it will take care of scheduling our container and send these commands to our nodes to distribute.
we will run 'nginx' container and expose 'port 80'. we could specify number of instances to launch via 'replicas'.
All would be runing from the 'node1' managerical node and we could use for administration.
root@node1# docker service create --replicas 5 -p 80:80 --name web nginx
lwvjgxcxrg5wqw2fwrgzosnnw
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
root@node1#
you could now see the status of the service being orchestrated to different nodes.
root@node1# docker service ls PORTS
ID NAME MODE REPLICAS nginx:latest *:80->80/tcp
MAGE PORTS
lwvjgxcxrg5w web replicated 8/8 nginx:latest *:80->80/tcp
root@node1#
root@node1# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l00c9u3kmfbn web.1 nginx:latest node1 Running Running 5 minutes ago
nzzi7z3wvikl web.2 nginx:latest node2 Running Running 5 minutes ago
91uizczo4dp3 web.3 nginx:latest node3 Running Running 5 minutes ago
nor39f9gu3j2 web.4 nginx:latest node4 Running Running 5 minutes ago
mtn3et6gu5on web.5 nginx:latest node5 Running Running 5 minutes ago
root@node1#
Accessing service
you can acess the service by hitting any of the manager or worker node. It does not matter any particular node does not have any container scheduled on it.
root@node1# curl http://192.168.0.28:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@node1#
Scaling up and Scaling down
Currently we are running 5 containers and lets assume we require 10 containers, fire below to scale up.
root@node1# docker service scale web=10
root@node1# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l00c9u3kmfbn web.1 nginx:latest node1 Running Running 18 minutes ago
nzzi7z3wvikl web.2 nginx:latest node2 Running Running 18 minutes ago
91uizczo4dp3 web.3 nginx:latest node3 Running Running 18 minutes ago
nor39f9gu3j2 web.4 nginx:latest node4 Running Running 18 minutes ago
mtn3et6gu5on web.5 nginx:latest node5 Running Running 18 minutes ago
t1reh7fnzfg9 web.6 nginx:latest node3 Running Running 10 minutes ago
qiyegknsz90w web.7 nginx:latest node1 Running Running 10 minutes ago
zqsafvln29ft web.8 nginx:latest node2 Running Running 10 minutes ago
mx6ezdng0n1i web.9 nginx:latest node4 Running Running 16 seconds ago
xrmugsonlbvl web.10 nginx:latest node5 Running Running 16 seconds ago
root@node1#
you can reduce with same command, it would reduce your containers on the nodes.
root@node1# docker service scale web=5
Draining node
whenever the node is ACTIVE, it will be always ready to accept tasks from Manager.
root@node1#docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
wga1nmopjbir2ks92rxntj9dz * node1 Ready Active Leader
4wzc1nesi1hxa3ekq753w0koq node2 Ready Active
4nrsuwslw149mg4nwlipmxxlo node3 Ready Active
jbdizz7gvfdz03shtgu23h8kv node4 Ready Active
afpi9osujgcsqkdiqg4tnz6nb node5 Ready Active
root@node1#
When the node is active, it can receive new tasks:
- during a service update to scale up
- during a rolling update
- when you set another node to Drain availability
- when a task fails on another active node
But sometimes, we have to bring the Node down for some maintenance reason. This meant by setting the Availability to Drain mode. Let us try that with one of our nodes.
since there are 10 containers runing, each node is having 2 containers on it. lets made one of the node drain and see how the containers are being orchestrated without disrupting service.
root@node1# docker inspect node5
.
.
<snip>
"Spec": {
"Labels": {},
"Role": "worker",
"Availability": "active" ==> status set to active
.
.
<snip>
}
},
"Status": {
"State": "ready",
"Addr": "192.168.0.24"
}
<snip>
root@node1# docker node update --availability drain node5
node5
root@node1#
root@node1# docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l00c9u3kmfbn web.1 nginx:latest node1 Running Running 30 minutes ago
nzzi7z3wvikl web.2 nginx:latest node2 Running Running 30 minutes ago
91uizczo4dp3 web.3 nginx:latest node3 Running Running 30 minutes ago
nor39f9gu3j2 web.4 nginx:latest node4 Running Running 30 minutes ago
e5pdetk2lghs web.5 nginx:latest node3 Running Running less than a second ago
mtn3et6gu5on \_ web.5 nginx:latest node5 Shutdown Shutdown 1 second ago
t1reh7fnzfg9 web.6 nginx:latest node3 Running Running 21 minutes
agoqiyegknsz90w web.7 nginx:latest node1 Running Running 21 minutes
agozqsafvln29ft web.8 nginx:latest node2 Running Running 21 minutes
agomx6ezdng0n1i web.9 nginx:latest node4 Running Running 11 minutes ago
m23nbrdvb635 web.10 nginx:latest node4 Running Running less than a second ago
xrmugsonlbvl \_ web.10 nginx:latest node5 Shutdown Shutdown less than a second ago
root@node1#
root@node1# docker inspect node5
<snip>
"Spec": {
"Labels": {},
"Role": "worker",
"Availability": "drain"
<snip>
You could now see the containers on the node5 has been re-scheduled on node3 and node4.
you could now get on with maintenance on node5 and once they are up, you would require to make them into active state. On active state, containers will again get replicated.
Remove service
You could remove the service with 'rm' command.
root@node1# docker service rm web
Rolling upgrade
root@node1# docker service update --image <imagename>:<version> web
Thanks for re-sharing...
No comments:
Post a Comment