8i | 9i | 10g | 11g | 12c | 13c | 18c | 19c | 21c | 23ai | Misc | PL/SQL | SQL | RAC | WebLogic | Linux
Home » Articles » Linux » Here
Docker : Docker Swarm - Defining Clustered Multi-Container Applications
This article describes how to use Docker Swarm to create clustered multi-container applications.
- Assumptions
- Prerequisites
- Start Swarm
- Stack Definition
- Deploy Stack
- Scale a Service
- Remove Stack
- Leave Swarm
- Considerations
Related articles.
Assumptions
If you plan on using the examples in this article, you are going to need a few things in place before you start.
- You will need the Docker Engine installed, as described here.
- You should be familiar with Docker Compose, as described here.
- In this example I use an Oracle database image and an Oracle REST Data Services (ORDS) image. If you want to follow along you will have to build them first. The build information can be found here (DB build, ORDS build).
- We will be using the "docker-stack.yml" file here.
Prerequisites
In order for this to work, without adjustment, you will need to perform the following prerequisites.
Clone the Git repository here. You will need to place the relevant installation media under the software directories of the "ol7_183" database build and the "ol7_ords" build.
Build the images.
# Build DB image cd ~/dockerfiles/database/ol7_183 docker build -t ol7_183:latest . # Build ORDS image cd ~/dockerfiles/ords/ol7_ords docker build -t ol7_ords:latest .
The example also uses a Portainer image, but that is downloaded automatically from Docker Hub when required.
Once you've completed these prerequisites without errors, we can move on.
Start Swarm
The swarm is started with the docker swarm init
command. The node that starts the swarm automatically becomes the manager of the swarm.
$ docker swarm init Swarm initialized: current node (elo30e3qmw0ot4gwcl5vpfhff) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-3gdzi62dgi4wn8zv42w4uhh3axnjor4haqw054giyzfch76mlj-2g8bcl62d9rqfrf2q72hrkekg 10.0.2.15:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. $
Notice the docker swarm join
command in the output of the docker swarm init
command. Not surprisingly, this is the command you use if you want any other machines to join the swarm. For this to work each machine will need to be accessible on the network, without any firewalls blocking them on the designated port.
Stack Definition
If you've used Docker Compose, the definition of a stack will look very familar, as it uses a compose file. Some examples still use a file name called "docker-compose.yml", while others use the name "docker-stack.yml" for the file name. I prefer the latter, as there are some options which are valid for Docker Compose, which are not valid for a stack definition.
For this article I'm using the "docker-stack.yml" file found here. This file defines a three services.
- db : A service to run an Oracle database container.
- ords : A service to run two Oracle REST Data Services (ORDS) containers.
- portainer : A service to run a Portainer container.
The "docker-stack.yml" contains the following entry for the ORDS service, which defines how is should be deployed. In this case we are expecting 2 containers, which the swarm will restart on failure, with each being limited to 1 CPU.
deploy: replicas: 2 restart_policy: condition: on-failure resources: limits: cpus: "1"
The rest of the definition matches what you would see in a regular Docker Compose file, minus the build instructions. If you reference any compose-specific parameters, they will be ignored and a warming displayed on screen.
Deploy Stack
We deploy a stack to the swarm using the docker stack deploy
command, referencing the "docker-stack.yml" file using the "--compose-file" or "-c" flag.
$ cd ~/dockerfiles/swarm/ol7_183_ords $ docker stack deploy --compose-file ./docker-stack.yml ords-stack Creating network ords-stack_ordsnet Creating network ords-stack_default Creating service ords-stack_ords Creating service ords-stack_db Creating service ords-stack_portainer $
The following commands give us some information about the stack. We can check what stacks are in the swarm using the docker stack ls
command.
$ docker stack ls NAME SERVICES ords-stack 3 $
We can see the services that are running, including the number of replicates of each, using the docker service ls
command.
$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS 3yy4pncrars5 ords-stack_db replicated 0/1 ol7_183:latest *:1521->1521/tcp 0eo2a8pi91tg ords-stack_ords replicated 2/2 ol7_ords:latest *:8080->8080/tcp, *:8443->8443/tcp u7qnhf4l2tyd ords-stack_portainer replicated 1/1 portainer/portainer:latest *:9000->9000/tcp $
We can display information about the processes running in a stack using the docker stack ps {stack name}
command.
$ docker stack ps ords-stack ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS j4rpczp0k6ch ords-stack_portainer.1 portainer/portainer:latest localhost.localdomain Running Running 5 minutes ago jlrmo1g0yqta ords-stack_db.1 ol7_183:latest localhost.localdomain Running Running 17 seconds ago rkvub2qez8ub ords-stack_ords.1 ol7_ords:latest localhost.localdomain Running Running 4 minutes ago 43usasqwjn6s ords-stack_ords.2 ol7_ords:latest localhost.localdomain Running Running 4 minutes ago $
The docker ps
command can still be used in the normal way of course.
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 66dc6c991f51 portainer/portainer:latest "/portainer" 7 minutes ago Up 6 minutes 9000/tcp ords-stack_portainer.1.j4rpczp0k6chpj5b6acgqxl44 fe92be4d84f8 ol7_183:latest "/bin/sh -c 'exec ${…" 7 minutes ago Up 6 minutes (healthy) 1521/tcp, 5500/tcp ords-stack_db.1.jlrmo1g0yqtagbjbz3rn7gyff 6991979026f1 ol7_ords:latest "/bin/sh -c 'exec ${…" 7 minutes ago Up 7 minutes (healthy) 8080/tcp, 8443/tcp ords-stack_ords.2.43usasqwjn6s9wl03y3uyzdvx ca3b6a58ebe2 ol7_ords:latest "/bin/sh -c 'exec ${…" 7 minutes ago Up 7 minutes (healthy) 8080/tcp, 8443/tcp ords-stack_ords.1.rkvub2qez8ubtxewibuiab0ep $
Scale a Service
We can scale up or down the replicas for a specific service using the docker service scale
command. The following command increases the number of replicates from 2 to 5 for the ORDS service, using the service name listed with the docker service ls
command. The output from the command shows the additional containers starting.
$ docker service scale ords-stack_ords=5 ords-stack_ords scaled to 5 overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converged $ $ docker stack ps ords-stack ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS j4rpczp0k6ch ords-stack_portainer.1 portainer/portainer:latest localhost.localdomain Running Running 14 minutes ago jlrmo1g0yqta ords-stack_db.1 ol7_183:latest localhost.localdomain Running Running 9 minutes ago rkvub2qez8ub ords-stack_ords.1 ol7_ords:latest localhost.localdomain Running Running 13 minutes ago 43usasqwjn6s ords-stack_ords.2 ol7_ords:latest localhost.localdomain Running Running 13 minutes ago rnw0i26gudqn ords-stack_ords.3 ol7_ords:latest localhost.localdomain Running Running about a minute ago a64bj66nv9rh ords-stack_ords.4 ol7_ords:latest localhost.localdomain Running Running about a minute ago kdh39395zdc8 ords-stack_ords.5 ol7_ords:latest localhost.localdomain Running Running about a minute ago $
We can scale down the service also.
$ docker service scale ords-stack_ords=2 ords-stack_ords scaled to 2 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged $ $ docker stack ps ords-stack ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS j4rpczp0k6ch ords-stack_portainer.1 portainer/portainer:latest localhost.localdomain Running Running 16 minutes ago jlrmo1g0yqta ords-stack_db.1 ol7_183:latest localhost.localdomain Running Running 11 minutes ago rkvub2qez8ub ords-stack_ords.1 ol7_ords:latest localhost.localdomain Running Running 15 minutes ago 43usasqwjn6s ords-stack_ords.2 ol7_ords:latest localhost.localdomain Running Running 15 minutes ago $
Remove Stack
The docker stack rm
command will remove the specified stack.
$ docker stack rm ords-stack Removing service ords-stack_db Removing service ords-stack_ords Removing service ords-stack_portainer Removing network ords-stack_default Removing network ords-stack_ordsnet $
Depending on the container shutdowns, it can take some time to complete, so you might want to check the status using the docker stack ps
command, until all the processes are gone.
$ docker stack rm ords-stack Removing service ords-stack_db Removing service ords-stack_ords Removing service ords-stack_portainer Removing network ords-stack_default Removing network ords-stack_ordsnet $ $ docker stack ps ords-stack ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS jlrmo1g0yqta 3yy4pncrars5wk9bvucs1nf2l.1 ol7_183:latest localhost.localdomain Remove Running 5 seconds ago $ $ docker stack ps ords-stack nothing found in stack: ords-stack $
Leave Swarm
A machine can leave a swarm using the docker swarm leave
command. The "-f" flag allows the swarm manager to leave the swarm.
$ docker swarm leave -f Node left the swarm. $
Considerations
Just some things to consider when using Docker Swarm.
- Swarm assumes all containers can be run on any node in the cluster, unless expressly restricted using a placement constraint. In the example used here, the DB and Portainer services are restricted to the Swarm manager node using a constraint. If the services are accessing any external resources, like file systems, they need to be present on all nodes. It's common to use NFS to allow file systems to we shared between nodes in the cluster.
- Most of what we did with the stack definition can be performed manually from the command line, but it makes sense to define applications in a "docker-stack.yml" file, so it can be checked into version control.
For more information see:
Hope this helps. Regards Tim...