25/12/2022

2. Création du cluster

Lu 328 fois Licence Creative Commons

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".