Skip to content
Extraits de code Groupes Projets
Valider c3278ec6 rédigé par Frédéric Minne's avatar Frédéric Minne
Parcourir les fichiers

infra : final

parent d5ac8c92
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -19,17 +19,19 @@ L’infrastructure à déployer mettra à disposition un swarm Docker pour hébe ...@@ -19,17 +19,19 @@ L’infrastructure à déployer mettra à disposition un swarm Docker pour hébe
![schema de l'infrastructure](./Images/arch-swarm-v2.drawio.png) ![schema de l'infrastructure](./Images/arch-swarm-v2.drawio.png)
Éléments de l'infrastructure : Éléments constitutifs de l'infrastructure :
- **Pool de managers** : machines qui assurent la gestion du swarm et servent les applications de gestion, de monitoring… - **Pool de managers** : machines qui assurent la gestion du swarm et servent les applications de gestion, de monitoring…
- **Pool de workers** : machines qui servent les applications exécutées sur le swarm - **Pool de workers** : machines qui servent les applications exécutées sur le swarm
À cela s'ajoute le **load balancer/Proxy** (géré par SIPR) qui permet la répartition de charge entre les machines du swarm, redirige les requêtes sur les bonnes machines en fonction du fqdn et assure également la liaison sécurisée https avec les machines clients À cela s'ajoute le **load balancer/Proxy** (géré par SIPR) qui permet la répartition de charge entre les machines du swarm, redirige les requêtes sur les bonnes machines en fonction du fqdn et assure également la liaison sécurisée https avec les machines clientes
### Dimensionnement des machines virtuelles et points de montage ### Dimensionnement des machines virtuelles et points de montage
Il y a 3 machines virtuelles pour mon infrastructure. Il y a 3 machines virtuelles pour mon infrastructure.
Voici leur spécification technique.
#### Manager (1 machine) #### Manager (1 machine)
- 4 coeurs - 4 coeurs
...@@ -46,6 +48,12 @@ Il y a 3 machines virtuelles pour mon infrastructure. ...@@ -46,6 +48,12 @@ Il y a 3 machines virtuelles pour mon infrastructure.
- 22 (git via ssh sur gitlab.sisg.ucl.ac.be et forge.uclouvain.be) - 22 (git via ssh sur gitlab.sisg.ucl.ac.be et forge.uclouvain.be)
- 11371 (key server) - 11371 (key server)
> **Notes** :
> - Le point de montage `/dockerdata-ceph` est destiné à contenir les fichiers partagés entre les services déployés sur l'infrastructure et qui seront montés en tant que volumes. Ces données devront être disponibles sur tous les noeuds du cluster et seront dès lors exportées depuis le manager via NFS.
> - Le point de montage `/var/lib/docker` est destiné au stockage des données propres à Docker
> - L'usage a montré que le répertoire `/var/lib/docker.bk` pouvait grandir rapidement et consommer de l'espace sur le système de fichier racine de la machine. J'ai donc décidé de l'externaliser via un point de montage séparé.
> - Le choix de Debian 11 était le choix fait à l'origine, mais il n'est en rien obligatoire. Les étapes décrites dans ce chapitre fonctionnent sur n'importe qu'elle distribution basée sur Debian (par exemple Ubuntu) et, avec un peu d'adaptation, sur n'importe quelle distribution Linux. Pour des infrastructures plus récentes, j'ai tendance à lui préférer Ubuntu dans sa dernière version LTS (la 22.04 au moment d'écrire ce texte) qui offre une plus grande stabilité et des paquets plus régulièrement mis à jour que Debian.
#### Workers (2 machines) #### Workers (2 machines)
- 4 coeurs - 4 coeurs
...@@ -65,9 +73,9 @@ Voici les étapes préliminaires nécessaires avant de pouvoir installer Docker ...@@ -65,9 +73,9 @@ Voici les étapes préliminaires nécessaires avant de pouvoir installer Docker
### Génération de la locale fr_BE.UTF-8 ### Génération de la locale fr_BE.UTF-8
Sur les machines Debian 11 fournies par SIPR, la locale par défaut `fr_BE.UTF-8` n'est pas générée. Sur les machines Debian 11 fournies par SIPR, la locale par défaut `fr_BE.UTF-8` n'est pas générée. Cela provoque l'affichage d'avertissements lors de l'exécution de nombreuses commandes.
Pour y remédier : Pour y remédier, il suffit de générer cette locale :
```bash ```bash
sudo dpkg-reconfigure locales sudo dpkg-reconfigure locales
...@@ -80,9 +88,9 @@ sudo dpkg-reconfigure locales ...@@ -80,9 +88,9 @@ sudo dpkg-reconfigure locales
### Configuration du proxy (optionnel) ### Configuration du proxy (optionnel)
Si les machines, ne sont pas sur le bon gateway, il peut être nécessaire de configurer le passage par le proxy de SIPR pour accéder à l'Internet et pouvoir installer les paquets requis. Ce proxy doit être configuré pour différentes applications. Si les machines ne sont pas sur le bon gateway, ou si elles ne sont pas encore autorisées à sortir sur les ports nécessaires sur le load balancer HAProxy de SIPR, il peut être nécessaire de configurer le passage par le proxy HTTP(S) des Data Center afin d'accéder à l'Internet et pouvoir installer les paquets requis. Ce proxy doit être configuré pour différentes applications.
> **Note** : Attention toutefois que les machines devront être capables de faire des requêtes vers l'extérieur sur les ports 22 et 11371 qui ne sont pas pris en charge par le proxy. > **Note** : Attention toutefois que pour l'utilisation de Docker, les machines devront être capables de faire des requêtes vers l'extérieur sur les ports 22 et 11371 qui ne sont pas pris en charge par le proxy du Data Center. Configurer le proxy HTTP(S) permet toutefois l'installation des paquets nécessaires sur les machines en attendant que la configuration sur le load balancer HAProxy de SIPR soient terminées.
#### Apt (normalement pas nécessaire) #### Apt (normalement pas nécessaire)
...@@ -107,9 +115,9 @@ Acquire::https::Proxy "http://proxy.sipr.ucl.ac.be:889/"; ...@@ -107,9 +115,9 @@ Acquire::https::Proxy "http://proxy.sipr.ucl.ac.be:889/";
#### Wget #### Wget
Contrairement à `curl` qui utilise les variables d’environnement pour le proxy, `wget`utilise sa propre configuration. Il faut ajouter le proxy au fichier `/etc/wgetrc`. Contrairement à `curl` qui utilise les variables d’environnement pour le proxy, `wget` utilise sa propre configuration. Il faut ajouter le proxy au fichier `/etc/wgetrc`.
Les wildcards n'étant pas supportées par la config, il est nécessaire de scripter l'ajout des IP de machine du sous-réseau Portail `echo 10.1.4.{1..255},`. Les wildcards n'étant pas supportées par la configuratuion, il est nécessaire de scripter l'ajout des IP de machine du sous-réseau de mon infrastructure `echo 10.1.4.{1..255},`.
```bash ```bash
# vim /etc/wgetrc # vim /etc/wgetrc
...@@ -120,7 +128,7 @@ no_proxy = `echo 10.1.4.{1..255},`localhost,127.0.0.1,.sipr-dc.ucl.ac.be ...@@ -120,7 +128,7 @@ no_proxy = `echo 10.1.4.{1..255},`localhost,127.0.0.1,.sipr-dc.ucl.ac.be
#### Bash #### Bash
Les wildcards n'étant pas supportées par Bash, il est nécessaire de scripter l'ajout des IP de machine du sous-réseau Portail `echo 10.1.4.{1..255},`. Les wildcards n'étant pas supportées par Bash, il est nécessaire de scripter l'ajout des IP de machine du sous-réseau de mon infrastructure `echo 10.1.4.{1..255},`.
```bash ```bash
vim ~/.bashrc vim ~/.bashrc
...@@ -134,7 +142,7 @@ export no_proxy=`echo 10.1.4.{1..255},`localhost,127.0.0.1,.sipr-dc.ucl.ac.be ...@@ -134,7 +142,7 @@ export no_proxy=`echo 10.1.4.{1..255},`localhost,127.0.0.1,.sipr-dc.ucl.ac.be
### Installation des paquets de base ### Installation des paquets de base
Installation des paquets requis pour la suite des opérations et la gestion de la machine. Installation des paquets requis pour la suite des opérations.
```bash ```bash
# Mise à jour de la liste des paquets # Mise à jour de la liste des paquets
...@@ -165,7 +173,7 @@ git config http.proxy http://proxy.sipr.ucl.ac.be:889 ...@@ -165,7 +173,7 @@ git config http.proxy http://proxy.sipr.ucl.ac.be:889
### Ajouts des groupes "admin" ### Ajouts des groupes "admin"
Par facilité, on ajoute l'utilisateur courant aux groupes `adm` et `staff` afin d'éviter de devoir utiliser `sudo` pour certaines actions. Le groupe `adm` donne accès aux logs, le groupe `staff` permet de modifier le contenu du répertoire `/usr/local` Par facilité, on peut ajouter l'utilisateur courant, ainsi que les autres utilisateurs amenés à gérer la machine, aux groupes `adm` et `staff` afin d'éviter de devoir utiliser `sudo` pour certaines actions. Le groupe `adm` donne accès aux logs, le groupe `staff` permet de modifier le contenu du répertoire `/usr/local`
```bash ```bash
# Accès aux logs # Accès aux logs
...@@ -174,15 +182,15 @@ sudo usermod -aG adm $USER ...@@ -174,15 +182,15 @@ sudo usermod -aG adm $USER
sudo usermod -aG staff $USER sudo usermod -aG staff $USER
``` ```
Il faudra se déconnecter et se reconnecter à la session pour que cela soit actif. Il faudra se déconnecter et se reconnecter à la session pour que cela soit actif ou utiliser la commande `newgrp`.
## Installation et configuration de Docker ## Installation et configuration de Docker
Cette section constitue un mode d’emploi pour la mise en place d’une infrastructure Docker, Cette section constitue un mode d’emploi pour la mise en place d’une infrastructure Docker, Certaines opérations sont à réaliser sur tous les types de noeuds du cluster alors que certaines sont spécifiques aux noeuds managers ou workers.
### Installation de l'environnement Docker (tous les nœuds) ### Installation de l'environnement Docker (tous les nœuds)
La procédure d'installation de Docker est celle décrite sur le site officiel : La procédure d'installation des paquets de Docker est simplement celle décrite sur le site officiel :
```bash ```bash
# Suppression des versions précédentes de Docker # Suppression des versions précédentes de Docker
...@@ -205,9 +213,15 @@ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin ...@@ -205,9 +213,15 @@ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
### Configuration de Docker (tous les nœuds) ### Configuration de Docker (tous les nœuds)
Une fois Docker installé, il reste à le configurer correctement.
#### Créer un fichier pour systemctl #### Créer un fichier pour systemctl
Créer un fichier d'override de configuration pour le service `docker.service` de systemd. Par défaut, Docker se lance avec une série d'options que je veux modifier dans mon infrastructure. De plus j'aimerais fournir une partie de ces options via le fichier `/etc/docker/daemon.json`. Or certaines de ces options risques d'entrer en conflit avec les options par défaut de Docker et le daemon refusera de se lancer.
Pour contourner ce problème, il suffit de modifier les options par défaut passées au service Docker par systemd.
Cela se fait relativement simplement en créant un fichier d'override de configuration pour le service `docker.service` dans lequel je vais retirer toutes les options passées au daemon Docker (puisqu'elles seront définies dans mon fichier `daemon.json`). Cela peut se faire soit à la main, soit en utilisant `systemctl`, l'outil de gestion de systemd.
**À la main** **À la main**
...@@ -224,8 +238,6 @@ ExecStart= ...@@ -224,8 +238,6 @@ ExecStart=
ExecStart=/usr/bin/dockerd ExecStart=/usr/bin/dockerd
``` ```
> **Attention** Cette étape est nécessaire afin de permettre au daemon Docker de démarrer lorsqu’on lui spécifie des options dans `/etc/docker/daemon.json` ! Si cette étape n'est pas remplie, le service Docker refusera de redémarrer !
**Avec systemctl** **Avec systemctl**
```bash ```bash
...@@ -242,7 +254,7 @@ ExecStart=/usr/bin/dockerd ...@@ -242,7 +254,7 @@ ExecStart=/usr/bin/dockerd
#### Configurer Docker via daemon.json #### Configurer Docker via daemon.json
Configuration dans daemon.json, `sudo vim /etc/docker/daemon.json ` : Configuration de base dans daemon.json, `sudo vim /etc/docker/daemon.json ` :
```json ```json
{ {
...@@ -252,11 +264,9 @@ Configuration dans daemon.json, `sudo vim /etc/docker/daemon.json ` : ...@@ -252,11 +264,9 @@ Configuration dans daemon.json, `sudo vim /etc/docker/daemon.json ` :
} }
``` ```
> Options du driver local pour les logs : https://docs.docker.com/config/containers/logging/local/ > **Note** : Les options du driver local pour les logs sont décrites dans la [documentation de Docker](https://docs.docker.com/config/containers/logging/local/)
Recharger le daemon via `sudo systemctl reload docker` ##### Activer l'accès à l'API du daemon Docker via tcp
#### Activer l'accès à l'API du daemon Docker via tcp
Deux ports sont possibles : 2375 (HTTP uniquement) ou 2376 (HTTP avec ou sans TLS). Deux ports sont possibles : 2375 (HTTP uniquement) ou 2376 (HTTP avec ou sans TLS).
...@@ -270,10 +280,10 @@ Dans `/etc/docker/daemon.json` ajouter la configuration des sockets pour `docker ...@@ -270,10 +280,10 @@ Dans `/etc/docker/daemon.json` ajouter la configuration des sockets pour `docker
``` ```
> **Notes** : > **Notes** :
> - L'utilisation de `tcp://0.0.0.0:2376` n'est en théorie pas sécurisée car elle permet à n'importe quel machine de parler au daemon Docker. Néanmoins, dans le cadre de mon infrastructure, cela ne pose pas de problème, puisqu'il est facile de limiter les accès aux machines du cluster elles-mêmes via des règles de firewall. j’ajouterais également, que le port 2376 n'étant accessible que via le VLAN des noeuds Docker, les risques sont assez réduis surtout en comparaison de la simplification qu'ils permettent dans la gestion du cluster. > - L'utilisation de `tcp://0.0.0.0:2376` n'est en théorie pas sécurisée car elle permet à n'importe quelle machine de parler au daemon Docker. Néanmoins, dans le cadre de mon infrastructure, cela ne pose pas de problème, puisquil est facile de limiter les accès aux machines du cluster elles-mêmes via des règles de firewall. j’ajouterais également, que le port 2376 n'étant accessible que via le VLAN des noeuds Docker, les risques sont assez réduis surtout en comparaison de la simplification qu'ils permettent dans la gestion du cluster.
> - Je n'ai pas activé le TLS sur le port 2376 à ce stade et ce principalement pour 2 raisons : il n'est pas nécessaire pour les raisons citées plus haut (VLAN + firewall), il requiert un certificat pour lequel il me semble préférable d'attendre qu'une CA "interne" aux Data Center SIPR soit disponible (l'alternative étant un certificat auto-signé). > - Je n'ai pas activé le TLS sur le port 2376 à ce stade et ce principalement pour 2 raisons : il n'est pas nécessaire pour les raisons citées plus haut (VLAN + firewall), il requiert un certificat pour lequel il me semble préférable d'attendre qu'une CA "interne" aux Data Center SIPR soit disponible (l'alternative étant un certificat auto-signé).
#### Configurer un registry non sécurisé ##### Configurer un registry non sécurisé
Par défaut, Docker refuse d'utiliser un registry qui ne serait pas accessible via HTTPS. Il est toutefois possible de définir des regitries non sécurisé directement dans la configuration du daemon. Par défaut, Docker refuse d'utiliser un registry qui ne serait pas accessible via HTTPS. Il est toutefois possible de définir des regitries non sécurisé directement dans la configuration du daemon.
...@@ -286,9 +296,9 @@ Dans `/etc/docker/daemon.json` ajouter la configuration du registry (l'installat ...@@ -286,9 +296,9 @@ Dans `/etc/docker/daemon.json` ajouter la configuration du registry (l'installat
} }
``` ```
#### Configurer les métriques pour le monitoring ##### Configurer les métriques pour le monitoring
Dans `/etc/docker/daemon.json` ajouter la configuration pour l'accès aux métriques qui seront nécessaires pour un futur monitoring : Dans `/etc/docker/daemon.json` ajouter la configuration pour l'accès aux métriques via une API REST. Cet accès sera nécessaire pour la mise en place du monitoring :
```json ```json
{ {
...@@ -301,7 +311,7 @@ Dans `/etc/docker/daemon.json` ajouter la configuration pour l'accès aux métri ...@@ -301,7 +311,7 @@ Dans `/etc/docker/daemon.json` ajouter la configuration pour l'accès aux métri
> **Note** : la question du monitoring sera abordée dans le chapitre Perspectives > **Note** : la question du monitoring sera abordée dans le chapitre Perspectives
#### Fichier daemon.json complet ##### Mon fichier daemon.json complet
Voici le fichier `daemon.json` complet : Voici le fichier `daemon.json` complet :
...@@ -392,7 +402,7 @@ Pour appliquer ce changement, il reste alors à recharger la session, soit en qu ...@@ -392,7 +402,7 @@ Pour appliquer ce changement, il reste alors à recharger la session, soit en qu
newgrp docker newgrp docker
``` ```
> **Note** : `newgrp` lance une nouvelle session `bash` au sein de la session actuelle. Il faudra donc utiliser la commande `exit` deux fois pour quitter la session. > **Note** : `newgrp` lance une nouvelle session du shell au sein de la session actuelle. Il faudra donc utiliser la commande `exit` deux fois pour quitter la session.
### Installation de Docker Compose (managers uniquement) ### Installation de Docker Compose (managers uniquement)
...@@ -516,7 +526,7 @@ Pour obtenir d'un consensus sur l'état du cluster, il faut un nombre impair de ...@@ -516,7 +526,7 @@ Pour obtenir d'un consensus sur l'état du cluster, il faut un nombre impair de
Comme ici on sait déjà quels nœuds seront les managers, ils sont ajoutés au swarm directement avec ce rôle en exécutant la commande affichée par `docker swarm join-token manager` sur chacun d'entre eux : Comme ici on sait déjà quels nœuds seront les managers, ils sont ajoutés au swarm directement avec ce rôle en exécutant la commande affichée par `docker swarm join-token manager` sur chacun d'entre eux :
```bash ```bash
# Afficher la commande à exécute sur les workers # Afficher la commande à exécuter sur les workers
docker swarm join-token manager docker swarm join-token manager
# Retourne une commande du type à exécuter sur chacun des noeuds manager supplémentaires # Retourne une commande du type à exécuter sur chacun des noeuds manager supplémentaires
docker swarm join --token <UN_LONG_TOKEN> <IP_DU_MANAGER>:2377 docker swarm join --token <UN_LONG_TOKEN> <IP_DU_MANAGER>:2377
...@@ -540,7 +550,7 @@ Si on ne sait pas encore quels nœuds seront manager ou si on veut donner le rô ...@@ -540,7 +550,7 @@ Si on ne sait pas encore quels nœuds seront manager ou si on veut donner le rô
Il suffit joindre les autres nœuds au swarm en exécutant la commande affichée par `docker swarm join-token worker` sur chacun d'entre eux : Il suffit joindre les autres nœuds au swarm en exécutant la commande affichée par `docker swarm join-token worker` sur chacun d'entre eux :
```bash ```bash
# Afficher la commande à exécute sur les workers # Afficher la commande à exécuter sur les workers
docker swarm join-token worker docker swarm join-token worker
# Retourne une commande du type à exécuter sur chacun des noeuds worker # Retourne une commande du type à exécuter sur chacun des noeuds worker
docker swarm join --token <UN_LONG_TOKEN> <IP_DU_MANAGER>:2377 docker swarm join --token <UN_LONG_TOKEN> <IP_DU_MANAGER>:2377
...@@ -974,7 +984,7 @@ networks: ...@@ -974,7 +984,7 @@ networks:
Le fichier de configuration de nginx a dû être adapté afin de permettre la récupération de l'adresse IP du client: Le fichier de configuration de nginx a dû être adapté afin de permettre la récupération de l'adresse IP du client:
```nginx ```conf
# config/nginx/nginx.conf # config/nginx/nginx.conf
user nginx; user nginx;
worker_processes auto; worker_processes auto;
...@@ -1024,7 +1034,7 @@ http { ...@@ -1024,7 +1034,7 @@ http {
Un fichier de configuration SSL/TLS fournit la configuration commune à toutes les applications : Un fichier de configuration SSL/TLS fournit la configuration commune à toutes les applications :
```nginx ```conf
# config/nginx/includes/ssl.conf # config/nginx/includes/ssl.conf
ssl_session_timeout 1d; ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
...@@ -1054,11 +1064,46 @@ Avant de lancer le service, il faut également créer le réseau overlay sur leq ...@@ -1054,11 +1064,46 @@ Avant de lancer le service, il faut également créer le réseau overlay sur leq
Il reste alors à lancer le proxy via `docker stack deploy -c proxy-compose.yml proxy` Il reste alors à lancer le proxy via `docker stack deploy -c proxy-compose.yml proxy`
Les fichiers de configuration des différents sites n'ont plus qu'à être placés dans le répertoire `./config/nginx/sites` et seront chargés soit au démarrage du service, soit lors de son rechargement via `docker service update proxy_proxy`.
Voici par exemple le fichier donnant accès à l'instance de Portainer sur mon infrastructure :
```conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
access_log /var/log/nginx/portainer.log main;
server_name
portainer.dckr.sisg.ucl.ac.be;
include /etc/nginx/includes/ssl.conf;
location / {
include /etc/nginx/includes/access.conf;
proxy_pass http://portainer_portainer:9000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
}
# replace with the IP address of your resolver
# resolver 127.0.0.1;
}
```
### Une commande pour générer les configurations des sites automatiquement ### Une commande pour générer les configurations des sites automatiquement
Afin de déployer plus rapidement les applications sur mon infrastructure, j'ai écrit une petite commande permettant la génération des fichiers de configuration de site sur base d'un template et de variables d'environnement.
Template de configuration de site : Template de configuration de site :
```nginx ```conf
# Basic site configuration template # Basic site configuration template
server { server {
listen 443 ssl http2; listen 443 ssl http2;
...@@ -1134,4 +1179,8 @@ Exécution de la commande ...@@ -1134,4 +1179,8 @@ Exécution de la commande
newsite /path/to/site/envfile newsite /path/to/site/envfile
``` ```
Le nouveau site est alors accessible sur l'infrastructure.
> **Note** : Cette commande est encore expérimentale et ne fonctionne pas dans 100% des cas, mais elle permet de simplifier les déploiements en attendant de passer à une solution plus solide comme `nginx-proxy` que j'aborderai dans le chapitre sur les Perspectives.
<!-- REFS --> <!-- REFS -->
\ No newline at end of file
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter