Virtualizace 2 - Projekt 2

Zadání projektu

Docker Swarm – základní orchestrace. Vytvořte 3 nodový cluster, nasaďte služby s replikací a simulujte výpadek nodu. Výsledky ověřte a zpracujte.

Úvod do Docker Swarm

Docker Swarm je nástroj pro orchestraci kontejnerů, který umožňuje spravovat a provozovat více Docker hostitelů jako jeden celek. Umožňuje automatické rozkládání kontejnerů mezi servery, zajišťuje vysokou dostupnost aplikací a usnadňuje škálování i správu distribuovaných systémů.

Krok 1: Vytvoření Docker Compose

Pro ukázku projektu jsem místo 3 VM použil Docker in Docker image.


name: virt_project_2
services:
  manager:
    image: docker:dind
    container_name: manager
    privileged: true
    hostname: manager
    networks:
      - swarm-net
#    healthcheck:
#      test: ["CMD", "docker", "info"]
#      interval: 5s
#      retries: 5

  worker1:
    image: docker:dind
    container_name: worker1
    privileged: true
    hostname: worker1
    networks:
      - swarm-net
    depends_on:
      - manager

  worker2:
    image: docker:dind
    container_name: worker2
    privileged: true
    hostname: worker2
    networks:
      - swarm-net
    depends_on:
      - manager

networks:
  swarm-net:
    driver: bridge
                

Krok 2: Spouštěcí skript

Pro usnadnění nasazení a vytvoření Docker Swarm clusteru jsem vytvořil skript, který inicializuje swarm v manager kontejneru, získá přístupový token a připojí 2 workery.


#!/bin/bash
set -e

echo "Spouštím 3-node Docker Swarm cluster..."
docker compose up -d

echo "Čekám, až se spustí Docker daemon v manageru..."
until docker exec manager docker info >/dev/null 2>&1; do
  sleep 2
  echo "  ...čekám na manager..."
done

MANAGER_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' manager)

echo "Manager IP adresa: $MANAGER_IP"
echo "Inicializuji Swarm..."
docker exec manager sh -c "export DOCKER_HOST=unix:///var/run/docker.sock && docker swarm init --advertise-addr $MANAGER_IP"

# získání join tokenu z managera
JOIN_TOKEN=$(docker exec manager docker swarm join-token -q worker)

if [ -z "$JOIN_TOKEN" ]; then
  echo "Nepodařilo se získat worker join token!"
  docker exec manager docker info
  exit 1
fi

echo "Token pro připojení workerů: $JOIN_TOKEN"

# připojení workerů
for NODE in worker1 worker2; do
  echo "Připojuji $NODE ke clusteru..."
  until docker exec $NODE docker info >/dev/null 2>&1; do
    echo "  ...čekám na spuštění Dockeru ve $NODE..."
    sleep 2
  done
  docker exec $NODE docker swarm join --token "$JOIN_TOKEN" manager:2377 >/dev/null
done

echo "Workeři připojeni."

echo "Stav clusteru:"
docker exec manager docker node ls

echo "Nasazuji testovací službu (NGINX, 3 repliky)..."
docker exec manager docker service create --name web --replicas 3 -p 8080:80 nginx >/dev/null

sleep 3
echo "Stav služby:"
docker exec manager docker service ls
docker exec manager docker service ps web

echo ""
echo "Hotovo!"
                

Krok 3: Ukázka

V manager kontejneru si můžeme zobrazit běžící služby a jejich rozložení replik.

                    
/ # docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
17sftwnzlqxe   web       replicated   3/3        nginx:latest   *:8080->80/tcp

/ # docker service ps web
ID             NAME      IMAGE          NODE      DESIRED STATE   CURRENT STATE        ERROR     PORTS
5fkrs9x8z7qp   web.1     nginx:latest   worker1   Running         Running 8 days ago
u1qfacwrvnxe   web.2     nginx:latest   worker2   Running         Running 8 days ago
4s6nr17k5hlp   web.3     nginx:latest   manager   Running         Running 8 days ago

/ # docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
px0h9aq9a3rz6cr0m5xchvm90 *   manager    Ready     Active         Leader           28.5.1
57f41v2r4oy5gfkmhggunp14g     worker1    Ready     Active                          28.5.1
whsrsrwg2sfnu8fq9w56hcp38     worker2    Ready     Active                          28.5.1
                

Krok 4: Simulace výpadku

Výpadek simulujeme jednoduše a to zastavením jednoho DinD kontejneru. Poté sledujeme změny v manager kontejneru.

                    
sudo docker stop worker1
                
                    
/ # docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
17sftwnzlqxe   web       replicated   3/3        nginx:latest   *:8080->80/tcp

/ # docker service ps web
ID             NAME        IMAGE          NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
e2fxgkad8pui   web.1       nginx:latest   manager   Running         Running 2 seconds ago
5fkrs9x8z7qp    \_ web.1   nginx:latest   worker1   Shutdown        Running 8 days ago
u1qfacwrvnxe   web.2       nginx:latest   worker2   Running         Running 8 days ago
4s6nr17k5hlp   web.3       nginx:latest   manager   Running         Running 8 days ago

/ # docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
px0h9aq9a3rz6cr0m5xchvm90 *   manager    Ready     Active         Leader           28.5.1
57f41v2r4oy5gfkmhggunp14g     worker1    Down      Active                          28.5.1
whsrsrwg2sfnu8fq9w56hcp38     worker2    Ready     Active                          28.5.1
                

Krok 5: Roling updates + škálování

Díky Docker Swarm můžeme jednoduše službu aktualizovat bez pádu služby, nebo dále škálovat.

                    
docker service update --image nginx:1.27 web
                

/ # docker service scale web=6
web scaled to 6
overall progress: 6 out of 6 tasks
1/6: running   [==================================================>]
2/6: running   [==================================================>]
3/6: running   [==================================================>]
4/6: running   [==================================================>]
5/6: running   [==================================================>]
6/6: running   [==================================================>]
verify: Service web converged

/ # docker service ps web
ID             NAME        IMAGE          NODE      DESIRED STATE   CURRENT STATE               ERROR     PORTS
e2fxgkad8pui   web.1       nginx:latest   manager   Running         Running about an hour ago
5fkrs9x8z7qp    \_ web.1   nginx:latest   worker1   Shutdown        Shutdown 4 minutes ago
u1qfacwrvnxe   web.2       nginx:latest   worker2   Running         Running 8 days ago
4s6nr17k5hlp   web.3       nginx:latest   manager   Running         Running 8 days ago
w2xbpvidgbxk   web.4       nginx:latest   worker1   Running         Running 7 seconds ago
va262t0saw3w   web.5       nginx:latest   worker1   Running         Running 7 seconds ago
gqwbxg2z7c6g   web.6       nginx:latest   worker2   Running         Running 7 seconds ago
                

Zdroje

https://medium.com/@ni8hin/docker-swarm-basics-a-step-by-step-guide-for-beginners-e3e1fed9e9fe

https://docs.docker.com/reference/cli/docker/swarm/

https://docs.docker.com/reference/cli/docker/service/