Skip to content

LAB : Setup Docker Swarm Cluster#

Présentation#

Objectifs:#

  • Familiarisation avec Docker-swarm
  • Déploiement d'un stack Docker Swarm
  • Appropriation des concepts d'orchestration avec Swarm

Architecture#

Dans ce lab, nous allons déployer un stack d'une application 3-tiers composés des briques suivantes:

  • Moodboard-frontend: Conçu en react permet d'exposer l'interface utilisateur

  • Moodboard-backend: conçu en springboot, permet d'exposer des API et continet la logique métier

  • PostgreSQL: Base de données utilisé pour la persistance des données

Prérequis#

  • Connaissance de Docker
  • Familiarisation avec les concepts de base de Docker Compose
  • Familiarisation avec les concepts de base de Docker Swarm
  • 03 Instance EC2 avec docker installé sur chacune
  • Minimum de connaissance sur Linux

  • Avoir un Cluster Swarm fonctionnel

Déroulement du Lab#

Etape 1: Configuration DNS#

Pour une meileure utilisation du proxy, il faudra modifier notre configuration DNS locale afin de faire les redirections sur la base des FQDNs.

devops@lecloudfacile:~$ vim /etc/hosts

et copier le contenu ci-dessous:

<IP_PUBLIC_DU_NOEUD_MANAGER> jenkins-dev.lecloudfacile.io app.moodboard.xyz adminer.moodboard.xyz api.moodboard.xyz portainer.moodboard.xyz

Etape 2: Preparation des images moodboard backend et frontend#

Backend#

Le dockerfile du backend est déjà dans le répertoire springboot-react-app/moodboard-backend.

La commande suivante va permettre de créer l'image. Cependant, vérifier que vous n'avez pas déjà l'image avant de refaire de build (docker image ls).

docker build -t moodboard-backend-app:1.0.0 springboot-react-app/moodboard-backend
Push de l'image sur Docker HUB#

La série d'opération suivante permet d'envoyer l'image vers Doker HUB.

#Tagguer l'image pour préparer son envoi vers Docker HUB
docker tag moodboard-backend-app:1.0.0 lecloudfacile/moodboard-backend-app:1.0.0

# S'authentfier sur Docker HUB
docker login -u lecloudfacile

# Envoyer l'image versvotre registry

docker push lecloudfacile/moodboard-backend-app:1.0.0

NB: N'oubliez pas de remplacer lecloudfacile par votre nom d'utilisateur

Frontend#

Le dockerfile du frontend est déjà dans le répertoire springboot-react-app/moodboard-frontend.

La commande suivante va permettre de créer l'image. Cependant, vérifier que vous n'avez pas déjà l'image avant de refaire de build (docker image ls).

docker build -t moodboard-frontend-app:1.0.0 springboot-react-app/moodboard-frontend
Push de l'image sur Docker HUB#

La série d'opération suivante permet d'envoyer l'image vers Doker HUB.

#Tagguer l'image pour préparer son envoi vers Docker HUB
docker tag moodboard-frontend-app:1.0.0 lecloudfacile/moodboard-frontend-app:1.0.0

# S'authentfier sur Docker HUB
docker login -u lecloudfacile

# Envoyer l'image versvotre registry

docker push lecloudfacile/moodboard-frontend-app:1.0.0

NB: N'oubliez pas de remplacer lecloudfacile par votre nom d'utilisateur

Etape 3 : Se connecter sur noeud Manager & Récupération du code source#

La commande suivante permet de récupérer le code source des applications backend (Springboot) & frontend (react).

git clone https://github.com/wingufactory/lecloudfacile-devops-labs.git
cd stack-swarm

Etape 4: Examen des fichiers de configurations nginx#

Les régles de redirection du proxy sont consignés dans des fichiers de conf qui sont chargés aux démarrage du conteneur nginx. Dans le répertoire lecloudfacile-devops-labs/stack-swarm/nginx-proxy/conf.d, il y'a des fichiers templates à utiliser par la suite selon le lab.

Exemple d'un fichier de configuation

# le bloc server englobe toutes les configurations spécifiques à un serveur virtuel, c'est-à-dire une instance de Nginx qui traite les requêtes pour un ou plusieurs domaines.
server {

    # indique à Nginx d'écouter sur le port 80, qui est le port standard pour le trafic HTTP non sécurisé. 
    listen 80;

    # spécifie le ou les noms de domaine que ce bloc de serveur est censé gérer.
    server_name app.moodboard.xyz;

    # le bloc location définit comment Nginx doit traiter les requêtes pour une URL spécifique
    location / {
        #indique que toutes les requêtes qui correspondent à la localisation / doivent être transmises à http://frontend:80
        proxy_pass http://frontend:80;

        # modifie l'en-tête HTTP Host de la requête transmise en y mettant la valeur  $host = app.moodboard.xyz
        proxy_set_header Host $host;

        # ajoute ou remplace l'en-tête HTTP X-Real-IP avec l'adresse IP de l'utilisateur qui a initié la requête
        proxy_set_header X-Real-IP $remote_addr;

        # ajoute l'adresse IP du client à la liste des adresses dans l'en-tête X-Forwarded-For
        # est utilisé pour suivre la chaîne d'adresses IP dans une requête client qui passe à travers un proxy ou un équilibreur de charge
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # définit l'en-tête X-Forwarded-Proto à la valeur $scheme, qui représente le schéma utilisé pour la connexion à Nginx (http dans ce cas). Cela permet au serveur backend de savoir si la requête d'origine était en HTTP ou en HTTPS.
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Etape 5: Examen du stack nginx reverse proxy#

Le fichier docker-compose du stack du reverse proxy se trouve à l'emplacmenet suivante lecloudfacile-devops-labs/stack-swarm/nginx-proxy

# Indication de la version de l'API
version: '3.8'

# Déclaration liste des services

services:


  # Service nginx-reverse-proxy: Reverse Proxy

  nginx-reverse-proxy:


    # Choix de l'image

    image: nginx

    # Attachement du service au réseau <frontend> 

    networks:
      - frontend

    # Montage du volume pour la persitence des données

    volumes:
      - ./conf.d:/etc/nginx/conf.d


    # Exposition de port
    ports:
      - '80:80'


    # Definition des politiques de deploiement
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
      replicas: 2
      placement:
        constraints: [node.role == manager]


# Déclaration du réseau <frontend> utilisé par le proxy nginx.        
networks:
  frontend:
    name: frontend

Etape 6: Démarrage du stack proxy#

Executez la commande suivante en s'assurant d'être à l'emplacmenet suivante lecloudfacile-devops-labs/stack-swarm/nginx-proxy

devops@lecloudfacile:~$ docker stack deploy --compose-file docker-compose.yaml proxy

Merci de vous assurer que le conteneur est bien démarré.

devops@lecloudfacile:~$ docker stack ps proxy

Etape 7: Examen du stack applicatif (backend, frontend, database et adminer)#

Le fichier docker-compose du stack applicatif se trouve à l'emplacmenet suivante lecloudfacile-devops-labs/stack-swarm

# Indication de la version de l'API
version: '3.8'

# Création d'un volume nommé <pgdata> pour la persistance des données. Il sera utilisé par la base de données Postgresql.
volumes:
  pgdata:
    name: pgdata


# Création d'un réseau nommé <app-network> pour l'ensemble des conteneurs qui vont appartenir à la stack et déclaration du réseau <frontend> utilisé par le proxy nginx.
networks:
  app-network:
    name: app-network
  frontend:
    name: frontend
    external: true

# Déclaration liste des services
services:

  # Service database: Base de données Postgresql 
  database:


    # Choix de l'image
    image: postgres:16.2-alpine

    # Déclaration des variables d'environnement requises
    environment:
      POSTGRES_USER: 'lecloudfacile'
      POSTGRES_PASSWORD: 'TwwsVdt9INkUATx'
      POSTGRES_DB: 'lecloudfacile'
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "lecloudfacile"]
      interval: 10s
      retries: 5

    # Montage du volume pour la persitence des données
    volumes:
      - pgdata:/var/lib/postgresql/data 

    # Attachement du service au réseau <app-network> 
    networks:
      - app-network


    # Definition des politiques de deploiement

    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
      replicas: 1
      placement:
        constraints: [node.role == manager]

  # Service adminer: Client web pour B-base de données
  adminer:


    # Choix de l'image
    image: adminer

    # Indiquer que ce service dépend du service <database>
    depends_on:
      - database

    # Attachement du service aux réseaux <app-network> pour communiquer avce la DB et <frontend> pour communiquer avec le proxy
    networks:
      - app-network
      - frontend

    # Definition des politiques de deploiement
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
      replicas: 1
      placement:
        constraints: [node.role == manager]

  # Service backend: Application springboot contenant le logique métier et exposant des apis pour faciliter la communication.
  backend:


    # Choix de l'image
    # remplacer `lecloudfacile` par votre identifiant docker hub
    image: lecloudfacile/springboot-react-app-backend:1.0.0

    # Indiquer que ce service dépend du service <database>
    depends_on:
      - database

    # Déclaration des variables d'environnement requises
    environment:
      SPRING_DATASOURCE_URL: 'jdbc:postgresql://database:5432/lecloudfacile'
      SPRING_DATASOURCE_USERNAME: 'lecloudfacile'
      SPRING_DATASOURCE_PASSWORD: 'TwwsVdt9INkUATx'
      FRONTEND_APP_URL: 'http://app.moodboard.xyz'
      SPRING_JPA_HIBERNATE_DDL_AUTO: update

    # Attachement du service aux réseaux <app-network> pour communiquer avce la DB et <frontend> pour communiquer avec le proxy
    networks:
      - app-network
      - frontend

    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
      replicas: 1
      placement:
        constraints: [node.role == manager]


  # Service frontend: Application react qui exposent les pages de l'application.
  frontend:


    # Choix de l'image
    # remplacer `lecloudfacile` par votre identifiant docker hub
    image: lecloudfacile/springboot-react-app-frontend:1.0.0

    # Déclaration des variables d'environnement requises
    environment:
      REACT_APP_API_URL: "http://backend:8080/api/feedback"

    # Indiquer que ce service dépend du service <backend>
    depends_on:
      - backend

    # Attachement du service aux réseaux <app-network> pour communiquer avce la DB et <frontend> pour communiquer avec le proxy
    networks:
      - app-network
      - frontend


    # Definition des politiques de deploiement
    deploy:
      restart_policy:
        condition: on-failure
        max_attempts: 3
      replicas: 1
      placement:
        constraints: [node.role == manager]

Etape 8: Démarrage du stack applicatif#

Executez la commande suivante en s'assurant d'être à l'emplacmenet suivante lecloudfacile-devops-labs/stack-swarm

devops@lecloudfacile:~$ docker stack deploy --compose-file app-docker-compose.yaml app

Merci de vous assurer que le conteneur est bien démarré.

devops@lecloudfacile:~$ docker stack ps app

Etape 9: [Si besoin] Recharge de la configuration du proxy#

Parfois, si le nginx ne repond pas correctement et pointe toujours vers d'anciens fichiers de configurations, Il faudra recharger la configuration du proxy pour prendre en compte les modifications apportées.

devops@lecloudfacile:~$ docker service ls
devops@lecloudfacile:~$ docker service update --force proxy_nginx-reverse-proxy

Etape 10: Accès à l'application#

Ouvrez un navigateur et tapez l'adresse suivante : http://app.moodboard.xyz

Etape 10: Arrétez l'application#

  • Supprimer le stack applicatif
devops@lecloudfacile:~$ docker stack ls
devops@lecloudfacile:~$ docker stack rm app 
devops@lecloudfacile:~$ docker volume ls
devops@lecloudfacile:~$ docker volume rm pgdata
  • Supprimer le stack proxy
devops@lecloudfacile:~$ docker stack ls
devops@lecloudfacile:~$ docker stack rm proxy 

Conclusion#

Dans la suite, nous allons voir comment déployer portainer sur swarm. Nous aurons besoin de tous les stack UP. N'oubliez pas d'éteindre cos instances EC2, si vous ne passez pas directement au prochain lab pour éviter des coûts additionnels.