Note
Please read the previous posts before continuing with this one. I discussed the basics of Docker and showed 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 a 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 the tutorial where I set up the 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 the 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 the previous step. You’ll need to first use docker-machine env [name] command to change your environment and then run join command from the 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 that the docker composes the 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 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 authorize 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 manager node using docker node promote command and a manager node can be demoted to worker node using docker node demote command.
Docker Machine
To set up an environment with multiple virtual machines I used Docker Machine. It’s a tool that installs Docker engine on virtual machines and manages 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 the 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 the docker stack services command.
Visualiser
In the solution above, I used a tool “visualizer” as part of my stack file. It’s not a mandatory part of stack file, it’s just a tool (great tool) to help visualize 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