Une présentation de systemd-nspawn

Dans Gérer plusieurs versions de certains outils en ligne de commande, Seboss666 y détaille comment il gère ce besoin. J’ai attendu un peu pour voir si d’autres solutions que Docker étaient présentées mais non. On va y remédier.

systemd peut gérer des conteneurs, peu de personnes s’en servent. Quand on parle conteneur, le gagnant (la norme) : Docker. Il s’agit de conteneur « applicatif » ou conteneur d’application, on y fait généralement tourner une seule application de type MariaDB ou nginx par exemple. systemd-nspawn a un positionnement particulier, une sorte de chroot sous stéroïdes, un conteneur « système ». On va démarrer une Debian dans un conteneur, se connecter dedans en console, installer des paquets, tester une configuration.

Quelques précisions

Je suis sur une Debian Sid, les commandes suivantes fonctionneront pour Debian/Ubuntu/Mint et dérivés. systemd-nspawn fonctionnera très bien et très facilement si vous lancez des conteneurs ayant la même base (ici Debian) que le système hôte. En revanche attendez-vous à des problèmes/difficultés pour lancer des conteneurs d’une autre base comme Arch ou Fedora même si c’est possible.

Le but premier de cet article est de répondre au besoin de Seboss666, il manquera parfois d’explications. Je reste dans la présentation, j’espère avoir mis suffisamment d’exemples pour que vous compreniez comment prendre en main systemd-nspawn. Je réponds aux questions dans les commentaires mais n’oubliez pas, le mieux pour comprendre est de pratiquer.

Arrivé à la fin de l’article, vous vous demanderez peut-être pourquoi j’ai présenté systemd-nspawn alors que machinectl est bien plus facile et rapide. Pour être exhaustif, vous avez ainsi la liste des différents outils nécessaires et « bas niveau ».

Lorsque vous êtes dans un conteneur pour en sortir : Press ^] three times within 1s to kill container => Ctrl + Alt Gr + ]. Pour éteindre le conteneur à l’intérieur du conteneur poweroff, pour éteindre le conteneur à partir de votre système hôte machinectl poweroff buster1.

Une Debian Buster avec explications

On installe les paquets nécessaires.
sudo apt install --no-install-recommends debootstrap systemd-container debian-archive-keyring

On crée un répertoire où seront stockés les conteneurs et on se déplace dedans.
mkdir -p ~/tmp/container && cd $_

À effectuer si votre /home est chiffré, ce qui est mon cas.
sudo mount -i -o remount,exec,dev /home/cascador

On debootstrap notre Debian.
sudo debootstrap --arch amd64 --include=systemd-container buster template.buster http://deb.debian.org/debian/

On effectue une copie, avoir un template qu’on ne touche plus une fois récupéré/téléchargé est une bonne pratique, on travaille uniquement sur des copies.
sudo cp -a template.buster buster1

On se connecte au conteneur, on supprime le fichier /etc/securetty, on modifie le mot de passe root, on sort du conteneur.
sudo systemd-nspawn -D buster1
rm /etc/securetty
passwd
exit

On boote le conteneur, on accède à sa console.
sudo systemd-nspawn -bD buster1

Une Debian Jessie avec main,contrib,non-free

sudo apt install --no-install-recommends debootstrap systemd-container debian-archive-keyring
mkdir -p ~/tmp/container && cd $_
sudo mount -i -o remount,exec,dev /home/cascador # Éventuellement
sudo debootstrap --arch amd64 --include=systemd-container --components=main,contrib,non-free jessie template.jessie http://deb.debian.org/debian/
sudo cp -a template.jessie jessie1
sudo systemd-nspawn -D jessie1
rm /etc/securetty
passwd
exit
sudo systemd-nspawn -bD jessie1

Une Debian sid avec main,contrib,non-free et git,zsh,openssh-server installé

sudo apt install --no-install-recommends debootstrap systemd-container debian-archive-keyring
mkdir -p ~/tmp/container && cd $_
sudo mount -i -o remount,exec,dev /home/cascador # Éventuellement
sudo debootstrap --arch amd64 --include=systemd-container,git,zsh,openssh-server --components=main,contrib,non-free sid template.sid http://deb.debian.org/debian/
sudo cp -a template.sid sid1
sudo systemd-nspawn -D sid1
passwd
exit
sudo systemd-nspawn -bD sid1

Une Ubuntu Focal

sudo apt install --no-install-recommends debootstrap systemd-container ubuntu-archive-keyring
mkdir -p ~/tmp/container && cd $_
sudo mount -i -o remount,exec,dev /home/cascador # Éventuellement
sudo debootstrap --arch amd64 --include=systemd-container focal template.focal http://archive.ubuntu.com/ubuntu/
sudo cp -a template.focal focal1
sudo systemd-nspawn -D focal1
passwd
exit
sudo systemd-nspawn -bD focal1

Une Debian sid facile et rapide avec machinectl

L’emplacement (/var/lib/machines) est primordial sans quoi machinectl ne pourra pas gérer le conteneur. Il s’agit de la solution que je recommande à Seboss.

sudo apt install --no-install-recommends debootstrap systemd-container debian-archive-keyring
sudo debootstrap --arch amd64 --include=systemd-container --components=main,contrib,non-free sid /var/lib/machines/sid http://deb.debian.org/debian/
sudo machinectl clone sid sid1
screen -dmS sid1 sudo systemd-nspawn -bM sid1 # Un petit hack nettement plus simple/rapide que configurer au propre systemd-nspawn@.service pour avoir du réseau dans le conteneur avec machinectl start
sudo machinectl shell sid1

machinectl

machinectl va permettre de gérer les conteneurs et machines virtuelles (VM), voici les principales commandes utiles.

machinectl ou machinectl list # Lister les conteneurs actifs (running/online)
machinectl list-images # Montrer une liste des images des conteneurs présentes dans /var/lib/machines/
sudo machinectl start sid1 # Démarrer le conteneur sid1
sudo machinectl poweroff sid1 ou sudo machinectl stop sid1 # Éteindre le conteneur sid1 proprement (shut down cleanly), stop est un alias de poweroff
sudo machinectl terminate sid1 # Éteindre le conteneur sid1 immédiatemment (immediately terminates a virtual machine or container, without cleanly shutting it down)
sudo machinectl clone sid sid1 # Cloner le conteneur sid en sid1
sudo machinectl remove sid1 # Supprimer le conteneur sid1
sudo machinectl clean --all # Supprimer toutes les images des conteneurs
sudo machinectl login sid1 # Open an interactive terminal login session, à utiliser pour être connecté dans le conteneur, la commande exit déconnecte l’utilisateur mais ne le fait pas sortir du conteneur
sudo machinectl shell sid1 # Open an interactive shell session, l’intérêt est d’être connecté en root sans avoir besoin de se loguer (taper le mot de passe) par contre la commande exit fait sortir du conteneur. À utiliser pour lancer quelques commandes rapidement
sudo machinectl copy-to sid1 ~/Documents/proc.jpeg /root/image.jpg # Copier un fichier dans le conteneur sid1
sudo machinectl copy-to sid1 ~/Images /root/Images # Copier un dossier dans le conteneur sid1
sudo machinectl copy-from sid1 /root/xyz abc # Récupérer le fichier /root/xyz du conteneur sid1 dans le dossier courant de l’hôte
sudo machinectl copy-from sid1 /root/xyz # Récupérer le fichier /root/xyz du conteneur sid1 dans /root (par défaut) de l’hôte

Et Manjaro alors ??

Seboss n’utilise pas un système Debian, il n’a pas encore vu la lumière. Il est jeune, pardonnez-lui. En attendant si vous êtes sur Arch/Manjaro, la page systemd-nspawn sur l’ArchWiki vous donnera toutes les infos pour faire la même chose et même davantage car à partir de Arch on peut facilement lancer une Debian dans un conteneur mais à partir de Debian compliqué de lancer une Arch dans un conteneur.

J’utilise très régulièrement systemd-nspawn et j’en suis satisfait :

  • Il ne faut pas le comparer directement à Docker, ils répondent à des besoins/usages différents
  • Comme chroot sous stéroïdes, pour tester un truc, vérifier le fichier de configuration d’un paquet sous une autre version de Debian, lancer une commande d’un outil particulier, une approche très orientée système
  • machinectl enable permet de lancer un conteneur au démarrage, systemd-nspawn permet d’utiliser des applications graphiques et des images Docker (1, 2)
  • L’outil souffre encore de pas mal de défauts, je trouve machinectl list peu clair, on rencontre de nombreux petits problèmes (/etc/securetty, si on utilise du chiffrement sur l’hôte, si on veut faire tourner une autre « base » comme Fedora, etc.) mais avec cette présentation vous devriez gagner suffisamment de temps pour le tester et lui donner sa chance ;)

Déjà 5 avis pertinents dans Une présentation de systemd-nspawn

  • sebt3
    Bon article sur nspawn.
    un petit détail « debianneux » : `debootstrap` est prévu à la base pour installer une debian complète (avec un kernel et tout ; c’est ce qu’utilise debian-installer pour démarrer l’install) ce qui n’es pas utile dans un container. Dans la commande, je rajouterais `–variant=minbase` histoire de sauver du disque.

    Quant à la difficulté sur debian de faire tourner une arch (ou une centos) : soit les outils de base ne sont pas là (contrairement à dans l’autre sens puisque debootstrap est dispo dans ces 2 distrib), mais ca se fait et ca marche bien. Pour une fedora/centos, ce vieux guide marche encore très bien: https://www.lucas-nussbaum.net/blog/?p=385 . Je connais pas bien arch, mais je suis convaincu qu’un équivalent est possible et marcherait sans problème… La solution est probablement la derrière : https://wiki.archlinux.org/index.php/Install_Arch_Linux_from_existing_Linux#From_a_host_running_another_Linux_distribution

  • Marmotte
    Bonjour :)

    Article sympa qui pointe un élément assez méconnu de Systemd. J’ai remplacé LXC par systemd-nspawn depuis un peu plus d’un an, et pour mon utilisation, c’est bien mieux et surtout plus simple à mettre en place.

    Par contre, il y a une phrase qui me dérange dans ton article :
    « Docker. Il s’agit de conteneur « applicatif » ou conteneur d’application, on y fait généralement tourner une seule application de type MariaDB ou nginx par exemple. systemd-nspawn a un positionnement particulier, une sorte de chroot sous stéroïdes, un conteneur « système ». »

    Même si ton article est destiné à des débutants/bidouilleurs, pour lesquels il sera plus simple de conteneuriser un OS entier, cette affirmation est fausse et je trouve ça dommage.
    systemd-nspawn permet de faire aussi bien des conteneurs « système » que des conteneurs « applicatifs » avec juste ce qu’il faut dedans pour faire tourner une unique application sans avoir un OS complet :)

Les commentaires sont fermés.