Odroid C4 : la conteneurisation via LXD

Rédigé par Alexandre le 2023-08-03

#auto-hébergement #debian #loisir

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 |
+------+-------+------+------+------+-----------+----------+