aegir

Gestion des conteneurs

L’organisation des conteneurs repose sur les concepts de Compose. Les conteneurs sont organisés par application, le moins de mutualisation possible est effectuée. Par exemple, chaque application dispose de son serveur de bases de données, de son serveur Redis si besoin, etc.

L’ensemble des données spécifiques aux applications, donc l’ensemble des données des conteneurs est stocké dans /srv sur une partition chiffrée.

Le /srv lui-même est découpé en fonction des usages :

La configuration et les données de chaque application est stockée dans un dossier dédié dans /srv/apps ou /srv/users. Par exemple, /srv/apps/mastodon, /srv/apps/mumble. Ce dossier abrite ensuite idéalement un fichier compose docker-compose.yml, un dossier pour les éventuels fichiers de configuration ./conf et un dossier de données, ./data. Les applications plus complexes disposent d’une arborescence adaptée.

Le fichier docker-compose.yml ne doit pas contenir de données spécifiques à TeDomum et doit être publiable. Les données spécifiques sont importées par variables depuis un fichier .env situé dans le dossier de l’application.

Démarrage

Fiche réflexe pour le démarrage d’un hyperviseur. Ces opérations n’ont pas vocation à être automatisées puisqu’une intervention humaine est requise quoi qu’il arrive.

Monter les systèmes de fichiers

  1. déchiffrer le LUKS : cryptsetup luksOpen /dev/mdX data
  2. monter le volume métier : mount /srv
  3. vérifier : ls /srv

Démarrer Docker et vérifier l’état

  1. démarrer Docker systemctl start docker
  2. par service : cd /srv/<service> (core en priorité)
  3. vérifier l’état docker-compose ps

Services centraux

Les services mutualisés sont regroupés dans des projets compose dans /srv/core. À titre d’exemple, les services traefik (reverse proxy Web) et fw (gestion du firewall) sont dans /srv/core/front. Ils doivent être démarrés avant le reste de l’infrastructure.

Adressage

L’ensemble de l’infrastructure est dual stack IPv4 et IPv6, les communications internes privilégient IPv6, notamment les tunnels IPSec entre hôtes routent les préfixes IPv6.

Chaque hôte dispose d’une adresse IPv4 d’administration, d’une ou plusieurs adresses IPv4 exposant des services, et d’un /56 IPv6. Sur ce préfixe sont choisies une adresse d’administration, autant d’adresses exposant des services qu’en IPv4, et chaque conteneur dispose d’une adresse globale routable.

Plan DNS

Trois domaines principaux sont exploités par l’infrastructure :

tedomum.net contient un enregistrement CNAME par service, pointant vers l’enregistrement tedomum.in correspondant. Pour les services ne supportant pas l’emploi de CNAME (MX, Matrix, Jabber, etc.) les enregistrements A et AAAA sont répliqués dans tedomum.net.

tedomum.org contient les enregistrements accessoires, tels que les reverse DNS de bouncers IRC, les noms de services non publics, etc.

Exposition des services

L’exposition des services a fait l’objet de nombreuses expérimentations. L’exposition de ports utilisant le proxy userland de Docker est exclue car les conteneurs ne disposent plus de l’adresse source de la connexion ; l’apport pour la vie privée est intéressant mais plusieurs conteneurs font usage de cette adresse, notamment l’antispam à la réception des mails.

L’exposition grâce aux règles iptables configurées par Docker n’est pas satisfaisante car ne couvrant pas IPv6. La doctrine classique consiste à assigner des adresses fixes IPv6 par conteneur, l’approche nécessiterait toutefois une maintenance alourdie, en termes d’assignation d’adresses, de DNS, etc.

Le support des règles d’exposition Docker Compose incluant des adresses IPv6 a été contribué au projet et publié dans la version 1.15. Ce support est couplé à un script docker-jinja parcourant régulièrement la liste des conteneurs pour mettre à jour une configuration nftables et l’appliquer. La configuration complète est documentée dans core/front.

Filtrage

Le filtrage déployé est modérément strict : les hôtes sont limités aux flux légitimes entrants et sortants. Les conteneurs peuvent établir des flux entre eux et vers Internet.

Les connexions entrantes sont autorisées exclusivement à destination des ports exposés explicitement par chaque conteneur. L’ensemble du filtrage est assuré par le script nftables décrit ci-dessus.

Mise à jour

Les serveurs sont basés sur Debian pour l’essentiel. Les mises à jour sont déployées via apt :

apt update
apt upgrade

Avant chaque validation de mise à jour, les paquets causant des redémarrages du démon Docker ou d’un démon crucial dont l’objet d’une revue. Les utilisateurs sont avertis avant mise à jour.

Récupérer de l’espace disque

Nettoyer le stockage Docker

Docker conserve de nombreux fichiers inutilisés : anciens volumes, anciennes images, etc.

Pour les nettoyer :

docker system prune

Toutefois, Docker ne supprime pas les images taggées mais non utilisées. A cette fin, on force la suppression de toutes les images non utilisées :

docker images -q | xargs docker rmi

Services

La récupération d’espace dique par service est documentée sur chaque service, principalement pour :

Bases de données MySQL

Les bases de données MySQL génèrent des journaux WAL rapidement volumineux, pour vérifier le volume :

du -sh wal/

Ou pour vérifier et classer tous les WAL :

du -sh /srv/*/*/wal | sort -h

Un script de configuration permet de prendre un snapshot de base et de réinitialiser le WAL, qui est sauvegardé par ailleurs. Ce script interrompt la base, une annonce de brève interruption est donc nécessaire, et certains services doivent être redémarrés ensuite :

/srv/config/mysql_checkpoint.sh <path> <basedir> <db>

Le chemin à employer est celui vers l’application, si possible le chemin complet. Généralement, le basedir et le db peuvent être omis. Le basedir doit être précisé lorsque le répertoire de base est différent de celui de l’application, et le db précisé lorsque la base de données n’est pas stockée dans le répertoire db.

Dans le cas général donc :

/srv/config/mysql_checkpoint /srv/apps/<app>