Initalize a swarm on a node which you can prefer, to create a manager. The architecture of the docker swarm orchestration is that it has a manager node (which is a whole node or computer). Then there are worker nodes which can be controlled or manage by the manager node.
(image: https://blog.knoldus.com/orchestration-with-docker-swarm/)
In the diagram above the swam manager is a node which is used to control the swam nodes. In general terminology swarm manager is refered to as manager and the swarm nodes are refered to as workers or worker nodes.
Create a swarm
To create a swam first we need to create a manager. SSH into a machine and run the command
docker swarm init --advertise-addr <ip-address>
In the above command we tell docker to initalize a docker swarm for us, but when we want to manage the worker nodes or when we want to communicate with the worker nodes we need an IP address for the manager to publish in order for workers to connect to our managers, so the command argument --advertise-addr will advertise the IP address that follows the command for workder nodes of other managers to connect to this manager node.
In case we want to use only one node, we can simply run
docker swarm init
$ docker swarm init --advertise-addr 192.168.0.23
Swarm initialized: current node (v6l24ilbz1bq72ad8tklhipxx) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-04i6f00j63iyiqts65tynfapes4qx6bhxap21lod0k69jzmol3-5tjti3fxaqg94qkv3zf86k6ai 192.168.0.23:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Now we can use docker info to display the information about the current state or our swarm.
docker info
Client:
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 19.03.11
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: active
NodeID: v6l24ilbz1bq72ad8tklhipxx
Is Manager: true
ClusterID: 6a4b0em1ndyg52odc43guyr1i
Managers: 1
Nodes: 2
Default Address Pool: 10.0.0.0/8
SubnetSize: 24
Data Path Port: 4789
Orchestration:
Task History Retention Limit: 5
Raft:
Snapshot Interval: 10000
Number of Old Snapshots to Retain: 0
Heartbeat Tick: 1
Election Tick: 10
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.23
Manager Addresses:
192.168.0.23:2377
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.4.0-186-generic
Operating System: Alpine Linux v3.12 (containerized)
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.4GiB
Name: node1
ID: XHBK:ACSE:UHWV:LFEY:MCE2:BAOA:775R:DK6P:CBYL:3RDJ:2WHV:QQ4M
Docker Root Dir: /var/lib/docker
Debug Mode: true
File Descriptors: 38
Goroutines: 164
System Time: 2020-09-01T08:25:22.272726765Z
EventsListeners: 0
Registry: https://index.docker.io/v1/
Labels:
Experimental: true
Insecure Registries:
127.0.0.1
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
WARNING: API is accessible on http://0.0.0.0:2375 without encryption.
Access to the remote API is equivalent to root access on the host. Refer
to the 'Docker daemon attack surface' section in the documentation for
more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
WARNING: No swap limit support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
we can also run docker node ls to see information about all the nodes.
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
v6l24ilbz1bq72ad8tklhipxx * node1 Ready Active Leader 19.03.11
pw51r1us9l1ou62pdh3ff3dp2 node2 Ready Active 19.03.11
The * indicates we are connected to the that node.
Add nodes to the swarm
To add nodes to the swarm run the command displayed when we initalized the swarm.
docker swarm join --token SWMTKN-1-04i6f00j63iyiqts65tynfapes4qx6bhxap21lod0k69jzmol3-5tjti3fxaqg94qkv3zf86k6ai 192.168.0.23:2377
This will spawn up a node (worker). Please note that this command has to be run on a different physical computer. Also the IP address specified 192.168.0.23:2377 should be accessible to this machine where we are spawning a worker node.
If the command from the init swarm command is not accessible you can run docker swarm join-token worker to get the command.
Once the node is setup. We can use docker node ls to see how many nodes we have. I had already setup a node so you can see the output in my previous docker node ls command.
Deploy a service
I will run a simple helloworld program which will ping google.com
To create a service we use docker service create command
docker create servec --replica 3 --name helloworld alpine ping jayvala.in
The above command will create a service named helloworld with base image as alpine and the command as the last argument ping google.com
The replicas flag is important here. It specifices on how many instances we want to run this services. Its good practice to have more than one replica as it helps in high availibility.
For the swarm manager too can be an instance so once you execute this command it can spawn the service on manager too.
We can use docker service ls command to see the list of services running.
To inspect the service running on our swarm we can use
$ docker service inspect --pretty helloworld
ID: cnpv2ykky1lmm5vpdd9id0u0q
Name: helloworld
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: alpine:latest@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Args: ping jayvala.com
Init: false
Resources:
Endpoint Mode: vip
Now lets see which nodes in our swarm is running our helloworld service
$ docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zl1z36sfzr50 helloworld.1 alpine:latest node2 Running Running 4 minutes ago
b3pb76uuvpsi helloworld.2 alpine:latest node1 Running Running 4 minutes ago
21y3swo9n8cj helloworld.3 alpine:latest node2 Running Running 4 minutes ago
As we can see that we have 3 helloworld services running, one on node 1 and two on node 2.
Now as the users consuming this services increase we would want to scale up these services.
Scale up the service
To scale up the we can use the following command
docker service scale <service name>=<number of tasks>
We can se here that we can replicate the tasks (a task is nothing but a single instance of a service).
docker service scale helloworld=10
helloworld 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
The above command started 10 more replicas of the helloworld services.
Now to see which nodes are running how many process we can simply use
docker service ps helloworld
$ docker service ps helloworld
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zl1z36sfzr50 helloworld.1 alpine:latest node2 Running Running 11 minutes ago
b3pb76uuvpsi helloworld.2 alpine:latest node1 Running Running 11 minutes ago
21y3swo9n8cj helloworld.3 alpine:latest node2 Running Running 11 minutes ago
5e650ivizaet helloworld.4 alpine:latest node2 Running Running about a minute ago
2u0cz08jp9sk helloworld.5 alpine:latest node1 Running Running about a minute ago
011vnxwzyjd3 helloworld.6 alpine:latest node2 Running Running about a minute ago
drwrg7ixa42p helloworld.7 alpine:latest node1 Running Running about a minute ago
mcl513va9pes helloworld.8 alpine:latest node1 Running Running about a minute ago
6c7lwv522f4x helloworld.9 alpine:latest node2 Running Running about a minute ago
4441rdl391rv helloworld.10 alpine:latest node1 Running Running about a minute ago
Now on manager node we can do docker ps and it will list out all the tasks its been running, we can do the same on any node.
Deleting the service
To remove the service completely we can use
docker service rm helloworld
Now we can run the command docker ps to verify all our services are deleted or not.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES