Odroid C4 : la conteneurisation via LXD
Rédigé par Alexandre le 2023-08-03
Je profite de l'actualisation de mon article décrivant ma configuration système sur mes hôtes LXD pour publier cet article qui traîne depuis un bon moment en brouillon.
Cet article décrit la mise en place de LXD sur l'ensemble des mes hôtes. Ici l'installation se concentre sur un seul hôte, le premier d'un cluster ou un hôte en standalone. Je ne pense pas faire d'article décrivant la mise en cluster, la documentation officielle étant plutôt bien faite sur le sujet.
Installation
Bien que le paquet lxd
soit maintenant présent dans les dépôts Debian, je préfère continuer d'utiliser le gestionnaire de paquet snap.
Installation de l'ensemble des pré-requis :
- snapd : gestionnaire de paquet indépendant du système
- bridge-utils : permet de créer des interfaces de type pont
- vlan : permet d'utiliser des vlan
- btrfs-progs : prendre en charge le BTRFS
sudo apt install snapd bridge-utils vlan btrfs-progs nfs-common
Installer LXD :
sudo snap install lxd
Permettre à l'utilisateur courant d'utiliser LXD :
sudo adduser $(whoami) lxd
Se déconnecter puis se reconnecter.
Configuration
Réseau
Modifier la configuration du serveur pour créer deux interfaces de type pont. La première interface permettra aux conteneurs d'utiliser le réseau de l'hôte, tandis que la seconde sera le réseau local des conteneurs.
Attention à bien repérer le nom de l'interface physique, ici end0
Nettoyer le fichier de configuration des interfaces :
sudo tee /etc/network/interfaces <<EOF
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
EOF
Créer le fichier de configuration de l'interface de loopback :
sudo tee /etc/network/interfaces.d/1-lo.network <<EOF
auto lo
iface lo inet loopback
EOF
Créer le fichier de configuration de l'interface physique :
sudo tee /etc/network/interfaces.d/2-end0.network <<EOF
auto end0
iface end0 inet manual
EOF
Ajouter la première interface de type pont :
sudo tee /etc/network/interfaces.d/3-lxdbr0.network <<EOF
# Bridge interface for LXD (WAN)
auto lxdbr0
iface lxdbr0 inet static
address 192.168.1.6/24
gateway 192.168.1.254
dns-nameservers 80.67.169.12 80.67.169.40
bridge_ports end0
bridge_hw $(cat /sys/class/net/end0/address)
bridge_stp off
bridge_fd 0
EOF
Créer le VLAN permettant d'isoler le réseau des conteneurs du reste du réseau :
sudo tee /etc/network/interfaces.d/4-end0.50.network <<EOF
auto end0.50
allow-hotplug end0.50
iface end0.50 inet manual
vlan_raw_device eth0
EOF
Créer la seconde interface de pont qui sera utilisé pour les conteneurs :
sudo tee /etc/network/interfaces.d/5-lxdbr50.network <<EOF
auto lxdbr50
allow-hotplug lxdbr50
iface lxdbr50 inet manual
bridge_ports end0.50
bridge_hw $(cat /sys/class/net/end0/address)
bridge_stp off
bridge_fd 0
EOF
Redémarrer le réseau :
sudo systemctl restart networking
Stockage
Ayant choisi une petite eMMC, j'ai ajouté un disque dur externe qu'il faut préparer à recevoir nos conteneurs.
Effacer le disque dur externe :
sudo wipefs -a /dev/sda
Le reste sera fait lors de l'initialisation de LXD.
Initialisation
Avant de créer un premier conteneur, il est nécessaire d'initialiser LXD :
sudo /snap/bin/lxd init
Si le message suivant apparaît, l'ignorer (source) :
WARNING: cgroup v2 is not fully supported yet, proceeding with partial confinement
Voici comment j'ai répondu aux questions :
Would you like to use LXD clustering? (yes/no) [default=no]: yes
What name should be used to identify this node in the cluster? [default=erebe]:
What IP address or DNS name should be used to reach this node? [default=192.168.1.6]:
Are you joining an existing cluster? (yes/no) [default=no]:
Setup password authentication on the cluster? (yes/no) [default=yes]:
Trust password for new clients:
Again:
Do you want to configure a new local storage pool? (yes/no) [default=yes]:
Name of the storage backend to use (dir, lvm, btrfs) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: yes
Path to the existing block device: /dev/sda
Do you want to configure a new remote storage pool? (yes/no) [default=no]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: yes
Name of the existing bridge or host interface: lxdbr50
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
Configuration par défaut
Afin de s'économiser du travail lors de la création d'un nouveau conteneur, j'édite le profil par défaut :
- désactiver le démarrage automatique
- définir l'ordre de démarrage à 25
- un seul vCPU
- 512 Mo de RAM
- disque dur de 3Go
Cela se traduit par cette ligne de commande :
lxc profile set default boot.autostart=false boot.autostart.priority=25 limits.cpu=1 limits.memory=512MB && lxc profile device set default root size=3GB
NB : La valeur de boot.autostart.priority
est totalement arbitraire, mais j'ai choisi de me mettre sur une échelle de 100 afin de faciliter la lecture. Une valeur haute (100) sera prioritaire sur une valeur basse (99).
Sauvegarde
Récupérer le dépôt :
sudo git clone https://gitea.ykn.fr/chaos/tools.git /opt/tools
Créer des liens vers le point de montage :
sudo ln -s /mnt/pumbaa/backup/containers /opt/tools/backup/containers; \
sudo ln -s /mnt/pumbaa/backup/$(hostname) /opt/tools/backup/host
Créer le service qui exécutera le script de sauvegarde :
sudo tee /etc/systemd/system/ykn-backup.service <<EOF
[Unit]
Description=Exécuter le script de sauvegarde
ConditionFileIsExecutable=/opt/tools/backup/run.bash
[Service]
Type=oneshot
Nice=15
IOSchedulingClass=best-effort
IOSchedulingPriority=7
ExecStart=/opt/tools/backup/run.bash
[Install]
WantedBy=multi-user.target
EOF
Créer la planification :
sudo tee /etc/systemd/system/ykn-backup.timer <<EOF
[Unit]
Description=Planifier le script de sauvegarde
ConditionFileIsExecutable=/opt/tools/backup/run.bash
[Timer]
OnCalendar=*-*-* 2:00:00
Persistent=true
[Install]
WantedBy=timers.target
EOF
Activer la planification :
sudo systemctl enable ykn-backup.timer
Épilogue
Exécuter la commande suivante...
lxc list
...qui liste les conteneurs :
+------+-------+------+------+------+-----------+----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | LOCATION |
+------+-------+------+------+------+-----------+----------+