Docker SWARM : clusterisation
La clusterisation simple avec Swarm
Vidéo précédante
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 :

•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
Pour le moment servons nous d’Ansible CE
Nous allons faire un tour d’horizon d’Ansible

Principe d'Ansible
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 :
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-netdocker-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
Pattern & statefull

Anti-pattern Configuration mount point

Docker Swarm : déclaration de Config ou de Secret
Cas d’un Config
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.confnginx.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

