Note: Please read the previous posts before continuing with this one, I discuss the basics of Docker and show how to deploy a simple and multiple applications using Docker.
Problem
How to deploy a cluster of ASP.NET Core applications using Docker Swam mode.
Solution
First we need few Virtual Machines to make a cluster of machines to run Docker on. I am using Windows 10 and will use Hyper-V for this purpose. If you’re using another OS then skip the first part of tutorial where I setup VMs.
Open Hyper-V Manager and click the Virtual Switch Manager to create an External switch:
Create VMs using docker-machine
CLI command:
docker-machine create -d hyperv --hyperv-virtual-switch "fiverswitch" m1
docker-machine create -d hyperv --hyperv-virtual-switch "fiverswitch" w1
docker-machine create -d hyperv --hyperv-virtual-switch "fiverswitch" w2
You’ll have the three VMs in Hyper-V Manager:
You could use docker-machine ls
to get a list of VMs:
In order to work within the VMs you need to run the docker-machine env [name]
, which gives you a command to run and change your environment to VM i.e. as if you are logged into the VM:
Note: you could run docker info
to confirm the name of machine. Another option is to run docker-machine ls
and notice a * in ACTIVE column, indicating your current environment.
Make one node manager by initializing the swarm in it, using docker swarm init
command:
Get the token used to create worker roles, using docker swarm join-token worker
command:
Make the other two nodes workers by joining them to swarm, using the token from previous step. You’ll need to first docker-machine env [name]
command to change your environment and then run join command from previous step:
Once you’ve joined all the VMs, you could confirm by running docker node ls
command, which lists all the nodes in a swarm:
Next we’ll create docker-compose.yml
for our services:
version: '3.3'
services:
viz:
image: dockersamples/visualizer
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- "8090:8080"
deploy:
placement:
constraints:
- node.role == manager
api:
image: naushadt25/api
ports:
- "8080:80"
environment:
MOVIES_DB_CONN: "Server=... "
deploy:
replicas: 5
web:
image: naushadt25/web
ports:
- "8090:80"
environment:
API_URL: "http://api/movies"
depends_on:
- api
deploy:
replicas: 3
And run docker stack deploy
command (you need to be in the manger node):
docker stack deploy -c docker-compose.yml fiver
Note: -c
specifies the docker compose file.
You could check the running services using docker service ls
command:
You could access your services now using the IP addresses for the VMs (you can get them by running docker-machine ls
):
In order to make changes to services, just update the docker-compose.yml
file and run docker stack deploy
command again.
When you want to remove the stack, run docker stack rm [name]
command:
Discussion
Docker provides a mechanisms to run multiple containers on multiple machines, a cluster of docker containers, using Swarm mode. A swarm is a group of machines that all run docker and distribute work (services) among themselves.
Nodes
Each machine is referred to as a Node and can be either a Manager or Worker. Manager nodes authorise one or more nodes to join the cluster as Worker nodes and subsequently these worker nodes run services.
In the solution above we initiated the swarm using docker swarm init
command, which made the active node as manager. Then we generated a token using docker swarm join-token
command and finally added a worker node by using docker swarm join
command.
You could list the nodes using docker node ls
command (from the manager node) and also remove a node using docker node rm
command. A worker node can be promoted to a manger node using docker node promote
command and a manager node can be demoted to worker node using docker node demote
command.
Docker Machine
To setup an environment with multiple virtual machines I used Docker Machine. It’s a tool that install Docker engine on virtual machines and manage them using docker-machine
commands. You don’t have to use Docker Machine to setup VMs, you could also use something like Vagrant. An example of using Vagrant could be found in Wes Higbee course here.
Few of the commonly used docker-machine
commands are:
- To list machines:
docker-machine ls
- To start machines:
docker-machine start
- To stop machines:
docker-machine stop
- To restart machines:
docker-machine restart
- To remove machines:
docker-machine rm
- To get IP address of machines:
docker-machine ip
Note: The machine with Docker engine installed is also referred to as Dockerized Host, Managed Machine or simply Machine.
Docker Stack
We can create various services (containers) using docker service
commands however that can be painful for multiple services with interdependencies. A simpler approach is to use a stack file, which is a compose file with few extra sections to deal with deployment. For instance, using the stack file we can set number of instances of each service we need (replicas).
We create a stack i.e. deploy all the services as a group, using docker stack deploy
command. You could use docker stack rm
command to remove the stack i.e. remove all the services. One really useful feature of grouping your services in a stack is that to update the stack e.g. to increase the number of replicas, just change the file and run docker stack deploy
again. To view list of services in a stack you could use docker stack services
command.
Visualiser
In the solution above, I used a tool “visualiser” as part of my stack file. It’s not a mandatory part of stack file, it’s just a tool (great tool) to help visualise the nodes and services running on it.
Further Resources
For an excellent and in-depth look at Docker, check out Wes Higbee courses on Pluralsight.
Source Code
Compose File: https://gist.github.com/TahirNaushad/c9cccdaf0748a3b25c3bbc922269c7bb#file-dockerstack-md