Docker Swarm
Docker Swarm
Docker Swarm is nothing but a group of Docker Engines(Hosts) which run in swarm mode. At a time, a Docker host can be a manager, worker, or both.
Advantages of the swarm:
Changes can be deployed without restarting the whole stack.
During an update operation, the Docker engine will stop the services with the old configuration and redeploys them with the new specified configuration.
When we create and deploy a service, we define its state i.e. number of replicas required, networks attached, ports exposed…etc and the Docker engine(s) in the swarm works to maintain that specified state.
Nodes
Node is nothing but a Docker Host part of a Swarm.
To deploy your application to a swarm, we need to submit a service definition at the manager node. The manager node then deploys the service(s) as tasks to worker nodes present in the swarm
Manager nodes handled the orchestration and cluster management tasks to maintain the desired state of the swarm.
Worker Nodes:
Worker nodes in the swarm receive tasks from manager nodes and execute them.
By default, manager nodes can also be worker nodes, but we can set up them to run manager tasks only.
Services and tasks
A service deployed as a global, swarm executes that task in every available node in the cluster.
For a replicated services model, the manager distributes the task based on several replicas and the scale parameters specified.
In general, a task definition contains a Docker container and the commands to run inside that container.
Load balancing
Swarm manager uses ingress load balancing by default.
Docker Swarm supports external components, such as managed and cloud-based load balancers, which can access the service on the exposed ports of any node in the cluster even if that service(s) is running in another node on the cluster
Swarm mode also has an internal DNS that automatically assigns each service a DNS entry so that the services can talk to each other with these DNS names.
Getting Started.
Following activities are involved in the deployment of a docker swarm.
1. Initializing a cluster of Docker Engines in swarm mode
2. Adding nodes to the swarm
3. Deploying application services to the swarm
4. Managing the swarm once you have everything running
Ports Required :
Port | TCP/UDP | Usage |
2377 | TCP | cluster management communications |
7946 | TCP/UDP | for communication among nodes |
4789 | UDP | for overlay network traffic |
Creation of Swarm
$ docker swarm init –advertise-addr <MANAGER-IP>
$ docker info #view the current state of the swarm $ docker node ls #view information about nodes
Add nodes to the swarm as Workers
$ docker swarm join –token <accesstoken> ManagerIP:2377 Add nodes to the swarm as Manager
$ docker swarm join-token manager
# then execute the token generated in add. manager nods
Deploy a service
Example:
$ docker service create –replicas 1 –name DemoService alpine ping google.com
The docker service create creates the service.
The –name names the service HelloWorld.
The –replicas specify the desired number of instances.
The arguments alpine ping google.com define the service as an Alpine-Linux container that executes the command ping google.com
# Run docker service ls to see the list of running services: $ docker service ls
Inspect Services
$ docker service inspect <SERVICE-ID>
docker service ps <SERVICE-ID>
#To see which nodes are running the services(s)
docker ps
# Run on the node where the task is running to see details about the
container
Scale the service(s)
$ docker service scale <SERVICE-ID>=<NUMBER-OF-TASKS>
For example:
$ docker service scale helloworld=5
Delete the service
$ docker service rm <SERVICE-Name>
Update a service
$ docker service update –image redis:3.0.7 redis
By default, the scheduler carries out rolling updates as follows :
Stop the first task.
Schedule update for the stopped task.
Start the container for the updated task.
If the update to a task returns RUNNING, wait until the specified delay period then start the next task. Incase a task returns FAILED, pause the update.
# To restart a paused update.
$ docker service update <SERVICE-ID
$ docker service update
Drain a node
DRAIN availability prevents a worker node from accepting new tasks from the swarm manager. $ docker node update –availability drain <NODE-ID>
Re-Activate a drained Node/Worker
$ docker node update –availability active <NODE-ID>
Swarm mode and Ingress routing mesh
Docker Engine swarm mode makes it easy to publish/expose ports for services to make them available to resources outside the swarm via an ingress routing mesh.
To use the ingress network, the following ports must be open.
Port 7946 TCP/UDP : container network discovery.
Port 4789 UDP : container ingress network.
Publish a port for a service
$ docker service create \
–name <SERVICE-NAME> \
–publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \ <IMAGE>
Example:
$ docker service create \
–name my-web \
–publish published=8080,target=80 \
–replicas 2 \
nginx
The routing mesh listens on the exposed/published port for the IP address assigned to a node.
For Public IP addresses, the port is accessible from outside the Docker host.
All other IP addresses the access is limited from within the host
Sample Deployment – WordPress with 3 Replica!
In this demo deployment, we are using the following.
3 Ubuntu 20.04 EC2 Instances (ie. 3 Manager)
MySQL Server on RDS
GlusterFS
Traefik
GlusterFS : free and open-source software scalable network filesystem.
Traefik : A HTTP reverse proxy and load balancer made to deploy microservices and support Docker and Docker Swarm
Stage 1 : Setup GlusterFS:
$ apt-get install -y glusterfs-server
# Create a mount target (brick):
$ mkdir -p /glusterfs/bricks/example.com
# add in FSTAB
/dev/xvdf /glusterfs/bricks/example.com xfs defaults 0 0
# Create a shared folder “wordpress”
$ mkdir /glusterfs/bricks/example.com/wordpress
# Add hosts entries (All 3 Servers)
172.31.42.145 node1
172.31.39.147 node2
172.31.38.147 node3
Establish Gluster cluster nodes trust relationship
From Node1:
$ gluster peer probe node2
$ gluster peer probe node3
Create a shared volume
$ gluster volume create example_com-wordpress replica 3 node1:/glusterfs/bricks/example.com/wordpress
node2:/glusterfs/bricks/example.com/wordpress
node3:/glusterfs/bricks/example.com/wordpress
Start the Volume
$ gluster volume start example_com-wordpress
List Volumes/Check Status
$ gluster volume list
$ gluster volume status
Create a Local Mount Point to hold Shared WP files(On Each Node) $ mkdir -p /data/example_com-wordpress
Update Fstab
On Each node, add this line at the end of /etc/fstab file:
# Node1
node2:/example_com-wordpress /data/example_com-wordpress glusterfs defaults,_netdev 0 0
node3:/example_com-wordpress /data/example_com-wordpress glusterfs defaults,_netdev 0 0
# Node2
node1:/example_com-wordpress /data/example_com-wordpress glusterfs defaults,_netdev 0 0
node3:/example_com-wordpress /data/example_com-wordpress glusterfs defaults,_netdev 0 0
# Node3
node1:/example_com-wordpress /data/example_com-wordpress glusterfs defaults,_netdev 0 0
node2:/example_com-wordpress /data/example_com-wordpress glusterfs defaults,_netdev 0 0
Deploy the stack
$ docker stack deploy –compose-file=stack.yml WP_Stack_wordpress
stack.yml
version: ‘3’
networks:
traefik-net:
example_com-network:
services:
# LB
traefik:
image: traefik:v1.1.0-rc1
command: |-
–docker
–docker.swarmmode
–docker.domain=”swarm.example.com” –docker.watch
–web
ports:
– 80:80
networks:
– traefik-net
volumes:
– /var/run/docker.sock:/var/run/docker.sock deploy:
placement:
constraints:
– node.role == manager
# WordPress Area
wordpress:
image: wordpress:php7.4-apache
ports:
– 8001:80
networks:
– example_com-network
– traefik-net
volumes:
– /data/example_com-wordpress:/var/www/html environment:
WORDPRESS_DB_HOST: host:3306
WORDPRESS_DB_USER: admin
WORDPRESS_DB_PASSWORD: password WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: wp_
deploy:
mode: global #replicas becomes 3 as we have 3 nodes in the swarm labels:
APP: WORDPRESS
traefik.port: 80
traefik.frontend.rule:
“Host:swarm.example.com,www.swarm.example.com”
traefik.backend.loadbalancer.sticky: “true” #For sticky sessions restart_policy:
condition: on-failure
Check Swarm Deployment status
docker service ls
Testing site.
$ curl -I http://swarm.example.com/
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Date: Fri, 26 Mar 2021 12:09:31 GMT
Link: <http://swarm.example.com/wp-json/>; rel=”https://api.w.org/” Server: Apache/2.4.38 (Debian)
Set-Cookie: _TRAEFIK_BACKEND=http://10.0.11.2:80
X-Powered-By: PHP/7.4.16