Docker SWARM : clusterisation

La clusterisation simple avec Swarm

Docker SWARM : clusterisation
Photo by Taylor Vick / Unsplash

Vidéo précédante

Containers : Composition
Docker compose

Les principes de base

le consensus de Raft

et le quorum sur un swarm ping et timeout

Il n’a pas plusieurs manager actif sur un SWARM, ils sont élus par consensus.

Simulation :

Raft Consensus Algorithm
Raft is a consensus algorithm that is designed to be easy to understand.

•Un manager passif devient candidat et ping si il timeout•Le timeout et remis à zero quand un ping arrive•Si il reçoit un nombre de ping suffisant (nb de neud connu) il se considère comme manager

•Le quorum n’est possible que si il reste un nombre de manager suffisant

Pour ces raisons :

- il est indispensable de ne pas faire un cluster unique sur deux sites

-Il faut mieux 3 que 2 clusters ou un gros cluster sur trois sites-

Cas critique un gros cluster multi-site qui « split brain »

 => il y a un risque suivant la parité de multiplier les containers par deux sur les deux partie de split

Taille du swarm

Majorité

Tolerance à la panne

1

1

0

2

2

0

3

2

1

4

3

1

5

3

2

6

4

2

7

4

3

8

5

3

9

5

4

Construire une/des Cluster Docker SWARM

Choisir son architecture

Un seul gros cluster sur trois sites

Avantages :

  • Centralisation : Gestion simplifiée avec une seule instance à administrer.
  • Ressources partagées : Utilisation optimale des ressources, car elles sont centralisées.
  • Facilité de mise à l'échelle : Ajout de ressources plus simple dans un seul cluster.

Inconvénients :

  • Dépendance : Si le cluster rencontre des problèmes, tous les sites peuvent être affectés.
  • Latence : La communication entre les sites peut introduire de la latence.
  • Complexité de la configuration : Nécessite une configuration réseau robuste pour assurer la connectivité entre les sites.

Trois clusters distincts

Avantages :

  • Résilience : Si un cluster échoue, les autres restent opérationnels.
  • Isolation : Les problèmes d'un cluster n'affectent pas les autres.
  • Flexibilité : Possibilité d'adapter chaque cluster aux besoins spécifiques des sites.

Inconvénients :

  • Gestion multiple : Plus de complexité dans la gestion et la maintenance et le déploiement.
  • Ressources sous-utilisées : Risque de sous-utilisation des ressources si les clusters ne sont pas équilibrés.
  • Coûts : Potentiellement plus coûteux en termes de matériel et de licences.

Docker Machine : cluster docker et gestion de l’infrastructure

Une façon parmi d’autre de construire les nœuds du cluster
0:00
/0:44

Pour le moment servons nous d’Ansible CE

Nous allons faire un tour d’horizon d’Ansible

Principe d'Ansible

0:00
/1:36

Deux mots de plus sur les tests

Tests d’exploitation / Tests de déploiements

Le playbook Ansible pour les tests sur une Ubuntu

deploy_swarm_manager.yml

---
- name: Déployer Docker Swarm Manager sur localhost
  hosts: localhost
  tasks:
    - name: Installer les dépendances
      apt:
        name: 
          - apt-transport-https
          - ca-certificates
          - curl
          - software-properties-common
        state: present
        update_cache: yes

    - name: Ajouter la clé GPG de Docker
      apt_key:
        url: https://download.docker.com/linux/ubuntu/gpg
        state: present

    - name: Ajouter le dépôt Docker
      apt_repository:
        repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} stable
        state: present

    - name: Installer Docker
      apt:
        name: docker-ce
        state: latest

    - name: Initialiser Docker Swarm
      command: docker info 
      register: docker_info 
      changed_when: false
        
    - name: Initialiser le Swarm si pas déjà fait 
      command: docker swarm init --advertise-addr={{ ansible_default_ipv4.address }}           
      when: "'Swarm: active' not in docker_info.stdout"

Pour le lancer

$ ansible-playbook deploy_swarm_manager.yml --connection=local

Déployer un service  une stack sur Swarm avec un ingress Traefik

voir dépot Ultragreen :

formation-docker/sample-traefik-nginx-simple at main · Ultragreen/formation-docker
support de formation. Contribute to Ultragreen/formation-docker development by creating an account on GitHub.

Docker-compose à la rescousse, avec des différences

docker-compose-traefik.yml

services:
  traefik:
    image: traefik:latest
    ports:
      - target: 80
        published: 80
        mode: host
        protocol: tcp
      - target: 8080
        published: 8080
        mode: host
        protocol: tcp
    networks:
      - traefik-net
    command:
      - --api.insecure=true
      - --api.dashboard=true
      - --providers.swarm.exposedbydefault=false
      - --providers.swarm.network=traefik-net
      - --entrypoints.web.address=:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      placement:
        constraints:
          - node.role == manager

networks:
  traefik-net:
    driver: overlay
    name: traefik-net

docker-compose-service.yml

services:

  monservice:
    image: ma.registry.tld/monprojet/monimage:X.X.X
    networks:
      - traefik-net
    deploy:
      placement:
        constraints:
          - node.role == worker
      labels:
          - traefik.http.routers.monservice.rule=Host(‘monservice.mondomaine.tld’)
          - traefik.http.services. monservice.loadbalancer.server.port=5000

networks:
  traefik-net:
    external: true
$ docker stack deploy -c docker-compose-traefik.yml traefik

$ docker service ls
ID             NAME              MODE         REPLICAS   IMAGE          PORTS
k3oi4d5xtmax   traefik_traefik   replicated   1/1        traefik:v2.6   *:80->80/tcp, *:8080->8080/tcp

$ docker stack ls
NAME      SERVICES
traefik   1

puis

$ docker stack deploy -c docker-compose-service.yml monservice

$ docker stack ls
NAME         SERVICES
monservice   1
traefik      1

$ docker service ls
ID             NAME                    MODE         REPLICAS   IMAGE            PORTS
vttbqjgsrzq2   monservice_monservice   replicated   1/1        nginx:latest
q5j19bba8p82   traefik_traefik         replicated   1/1        traefik:latest

Network : VxLAN (Virtual Extensible LAN)

Stratégies de distribution

Attention à l’usage et à na pas aller vers un antipattern

Mise à l’échelle

0:00
/0:10

Pattern & statefull

Anti-pattern Configuration mount point

Docker Swarm : déclaration de Config ou de Secret

Cas d’un Config
0:00
/0:20

docker-compose.yml

services:
  web:
    image: nginx:latest
    deploy:
      replicas: 2
    configs:
      - source: my_config
        target: /etc/nginx/conf.d/default.conf

configs:
  my_config:
    file: ./nginx.conf

nginx.conf

server {
    listen 80;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

pour déployer

$ docker stack deploy -c docker-compose.yml my_stack

Un container est une unité volatile

 il faut donc externaliser & centraliser les logs

docker-compose.yml

services:
  nginx:
    image: nginx:latest
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./logs:/var/log/nginx
    ports:
      - "80:80"
    depends_on:
      - fluentd

  fluentd:
    image: fluent/fluentd:v1.14-1
    volumes:
      - ./fluentd.conf:/fluentd/etc/fluent.conf
      - ./logs:/var/log/nginx
    depends_on:
      - opensearch

  opensearch:
    image: opensearchproject/opensearch:latest
    environment:
      - discovery.type=single-node
    ports:
      - "9200:9200"
      - "9600:9600"

  kibana:
    image: kibana:latest
    environment:
      - ELASTICSEARCH_HOSTS=http://opensearch:9200
    ports:
      - "5601:5601"
    depends_on:
      - opensearch

nginx.conf

server {
    listen 80;
    server_name example.com;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        proxy_pass http://backend_server;
    }
}

fluent.conf

<source>
  @type tail
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx-access.log.pos
  tag nginx.access
  <parse>
    @type nginx
  </parse>
</source>

<match nginx.access>
  @type elasticsearch
  host opensearch
  port 9200
  index_name fluentd
  logstash_format true
  include_tag_key true
  type_name access_log
  logstash_prefix fluentd
  flush_interval 5s
</match>

Superviser son application dans un monde de container

Rendre exploitable son application, les bases

Superviser Docker avec Prometheus et des exporters

Ecosystème Prometheus

Podman une alternative à Docker


Vidéo suivante

Kubernetes ? une visite « guidée…. À thème »
Parler de Kubernetes et présenter Kubernetes c’est comme visiter le Louvres !