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 :
/srv/conf
: configurations générales ;/srv/docker
: données internes de Docker ;/srv/templates
: modèles de configuration de services ;/srv/core
: projets compose d’infrastructure ;/srv/apps
: projets compose des applications ;/srv/users
: projets compose des services hébergés pour les utilisateurs.
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
- déchiffrer le LUKS :
cryptsetup luksOpen /dev/mdX data
- monter le volume métier :
mount /srv
- vérifier :
ls /srv
Démarrer Docker et vérifier l’état
- démarrer Docker
systemctl start docker
- par service :
cd /srv/<service>
(core
en priorité) - 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
pour le coeur de l’infrastructure et les services ;tedomum.org
pour le reste.
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 :
- Mastodon
- Matrix
- Peertube
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>