Configuration Compose du cluster
Créer un fichier docker-compose.yml:
version: "3.8"
networks:
cluster-net:
driver: bridge
Traefik
On déclare un premier service pour Traefik accessible en HTTP sur le port 80
:
# ...
services:
reverse-proxy:
image: "traefik:v2.9"
networks:
- cluster-net
ports:
- "80:80"
Ajouter un volume pour le Unix socket du Docker daemon, et des valeurs à command
pour configurer Traefik avec Docker, activer le dashboard et définir un point d'entrée sur le port 80
:
# ...
services:
reverse-proxy:
# ...
command:
- "--api.dashboard=true"
- "--providers.docker"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=cluster-net"
- "--providers.docker.watch=true"
- "--entrypoints.web=true"
- "--entrypoints.web.address=:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Pour finir, on ajoute des labels qui seront lus par Traefik, afin de configurer l'accès à son dashboard sur traefik.localhost:
# ...
services:
reverse-proxy:
# ...
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=host(`traefik.localhost`)"
- "traefik.http.routers.traefik.entrypoints=web"
- "traefik.http.routers.traefik.service=api@internal"
Noeud manager
On déclare ensuite un service pour le noeud manager du cluster qui répondra pour le sous-domaine cluster.localhost sur le port 80
:
# ...
services:
# ...
manager:
image: "docker:20.10-dind"
privileged: true
networks:
- cluster-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.manager.rule=HostRegexp(`cluster.localhost`, `{subdomain:[a-z]+}.cluster.localhost`)"
- "traefik.http.routers.manager.entrypoints=web"
- "traefik.http.routers.manager.service=manager"
- "traefik.http.services.manager.loadbalancer.server.port=80"
Créer ensuite un fichier docker-compose.inner.yml (à laisser vide pour l'instant) qui servira à déclarer la stack à déployer dans le cluster. On crée un bind mount sur le noeud manager:
# ...
services:
# ...
manager:
# ...
volumes:
- ./docker-compose.inner.yml:/home/docker-compose.yml
Noeuds worker
Pour les autres noeuds, créer un service similaire, sans bind mount:
# ...
services:
# ...
worker:
image: "docker:20.10-dind"
privileged: true
networks:
- cluster-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.worker.rule=HostRegexp(`cluster.localhost`, `{subdomain:[a-z]+}.cluster.localhost`)"
- "traefik.http.routers.worker.entrypoints=web"
- "traefik.http.routers.worker.service=worker"
- "traefik.http.services.worker.loadbalancer.server.port=80"
Démarrage du cluster
Initialisation
On souhaite démarrer le cluster avec Docker Compose en ayant 3 noeuds workers. On utilisera l'option --scale
de la commande up
:
docker compose up -d --scale worker=3
Puis on initialise le cluster à partir du manager en y exécutant la commande docker swarm init
qui va nous fournir la commande à exécuter dans les autres noeuds:
docker compose exec manager docker swarm init
[output]Swarm initialized: current node (t8veub4pnqobbzqi33xohran9) is now a manager.
[output]
[output]To add a worker to this swarm, run the following command:
[output]
[output] docker swarm join --token SWMTKN-1-4j46c0i3e8cih6lgd0bu5j2tuau2nowor84ehuzesuq87wonfy-et0ljdvsng45hip4ql7lw9yyu 172.20.0.3:2377
[output]
[output]To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Ajout des workers
Il faut maintenant ajouter les workers. Vous pouvez recopier la commande affichée suite à l'initialisation et l'exécuter dans chaque worker:
docker compose exec 7c0e4203c9f9 docker swarm join --token SWMTKN-1-4j46c0i3e8cih6lgd0bu5j2tuau2nowor84ehuzesuq87wonfy-et0ljdvsng45hip4ql7lw9yyu 172.20.0.3:2377
[output]This node joined a swarm as a worker.
Ou bien récupérer la commande à exécuter en utilisant docker swarm join-token worker
et en la passant à chaque conteneur dont le nom contient worker
avec xargs:
SWARM_JOIN_COMMAND=$(docker compose exec manager docker swarm join-token worker | tail -n +2 | tr -d '\n'); \
docker ps -q --filter "name=worker" | xargs -i docker exec {} $SWARM_JOIN_COMMAND
[output]This node joined a swarm as a worker.
[output]This node joined a swarm as a worker.
[output]This node joined a swarm as a worker.
Vérifications
Ouvrir une session shell dans le manager:
docker compose exec -it manager sh
Lister les noeuds du cluster avec docker node ls
:
docker node ls
[output]ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
[output]op87efie6jv231d0hfidutdlx 62c5e92c7de6 Ready Active 20.10.22
[output]p6zcaczi453zqbgqjbhagwm0x 31655c5ded43 Ready Active 20.10.22
[output]aybuftdxkg3ldy1ne902fwzaq 077919377f63 Ready Active 20.10.22
[output]t8veub4pnqobbzqi33xohran9 * b9b1291034c8 Ready Active Leader 20.10.22
Lister ensuite les services avec docker service ls
dont la liste devrait être vide:
docker service ls
[output]ID NAME MODE REPLICAS IMAGE PORTS
Enfin, visiter le dashboard de Traefik sur traefik.localhost et vérifier que tous les routers sont en état "Success".