Files
blog/posts/incus.org
Evrard Van Espen fb6c11b7ec Patch typos
2025-11-14 14:04:40 +00:00

359 lines
12 KiB
Org Mode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#+TITLE: Incus pour gérer vos VM et CT
#+DATE: 2025-11-14T00:00:00Z
#+DRAFT: false
#+AUTHOR: Evrard Van Espen
#+DESCRIPTION: Présentation d'Incus, une alternative à Proxmox pour gérer les VMs et les CTs
#+SLUG: incus
#+TAGS: système
#+HERO: ./incus.png
* /Incus/, c'est quoi ?
/Incus/ est une solution moderne de virtualisation et de gestion de conteneurs, conçue comme un /fork/ communautaire de /LXD/ après le changement de licence de /Canonical/.
*/Open source/* et axé sur la simplicité, /Incus/ permet de créer et gérer des *conteneurs* et des *machines virtuelles*, le tout avec une intégration fluide sur /Linux/.
Il se distingue par sa *légèreté*, sa *sécurité renforcée* et sa *compatibilité* avec les technologies /cloud/, tout en offrant une *interface en ligne de commande* intuitive et une /API REST/.
Idéal pour les développeurs et les administrateurs système, /Incus/ facilite le déploiement denvironnements isolés, que ce soit pour le développement, les tests ou la production, tout en restant performant et facile à prendre en main.
Son approche modulaire et sa communauté active en font un outil de choix pour ceux qui recherchent une alternative flexible et transparente aux solutions propriétaires.
* Installation
#+BEGIN_INFO
/Incus/ est compatible et disponible sur la majorité des distributions /Linux/.
#+END_INFO
Dans mon cas, j'ai installé /Incus/ sur une machine /Fedora 43/.
Ma machine hôte est dotée de 2 cartes réseau, une qui sera utilisée pour la connexion à la machine et une autre qui sera utilisée comme pont pour les machines invitées.
** Installer le paquet /incus/ sur la machine
#+BEGIN_SRC
dnf install -y incus
#+END_SRC
** Activer et démarrer le service /Incus/
#+BEGIN_SRC
systemctl enable --now incus
systemctl start incus
#+END_SRC
** Configuration du /kernel/
Ces modifications sont nécessaires pour permettre au /kernel linux/ de lancer les machines virtuelles et les conteneurs.
Pour aller plus loin, vous pouvez consulter [[https://docs.rockylinux.org/10/books/incus_server/01-install/#environment-set-up][cette page]].
Mettre le contenu suivant dans =/etc/sysctl.d/90-incus-override.conf=
#+BEGIN_SRC
## The following changes have been made for LXD ##
# fs.inotify.max_queued_events specifies an upper limit on the number of events that can be queued to the corresponding inotify instance - (default is 16384)
fs.inotify.max_queued_events = 1048576
# fs.inotify.max_user_instances This specifies an upper limit on the number of inotify instances that can be created per real user ID - (default value is 128)
fs.inotify.max_user_instances = 1048576
# fs.inotify.max_user_watches specifies an upper limit on the number of watches that can be created per real user ID - (default is 8192)
fs.inotify.max_user_watches = 1048576
# vm.max_map_count contains the maximum number of memory map areas a process may have. Memory map areas are used as a side-effect of calling malloc, directly by mmap and mprotect, and also when loading shared libraries - (default is 65530)
vm.max_map_count = 262144
# kernel.dmesg_restrict denies container access to the messages in the kernel ring buffer. Please note that this also will deny access to non-root users on the host system - (default is 0)
kernel.dmesg_restrict = 1
# This is the maximum number of entries in ARP table (IPv4). You should increase this if you create over 1024 containers.
net.ipv4.neigh.default.gc_thresh3 = 8192
# This is the maximum number of entries in ARP table (IPv6). You should increase this if you plan to create over 1024 containers.Not needed if not using IPv6, but...
net.ipv6.neigh.default.gc_thresh3 = 8192
# This is a limit on the size of eBPF JIT allocations which is usually set to PAGE_SIZE * 40000. Set this to 1000000000 if you are running Rocky Linux 9.x
net.core.bpf_jit_limit = 1000000000
# This is the maximum number of keys a non-root user can use, should be higher than the number of containers
kernel.keys.maxkeys = 2000
# This is the maximum size of the keyring non-root users can use
kernel.keys.maxbytes = 2000000
# This is the maximum number of concurrent async I/O operations. You might need to increase it further if you have a lot of workloads that use the AIO subsystem (e.g. MySQL)
fs.aio-max-nr = 524288
#+END_SRC
#+BEGIN_WARNING
*Redémarrer la machine*
#+END_WARNING
Une fois que la machine a redémarré, lancer
#+BEGIN_SRC
sysctl net.core.bpf_jit_limit
#+END_SRC
Et vérifier que le retour est bien
#+BEGIN_SRC
net.core.bpf_jit_limit = 1000000000
#+END_SRC
** Initialisation d'/Incus/
Lancer la commande =incus admin init=.
Le processus permet de choisir la configuration qui sera appliquée.
#+BEGIN_SRC
Would you like to use clustering? (yes/no) [default=no]:
#+END_SRC
Ce choix permet d'activer ou non le mode /cluster/, je laisse le choix par défaut (/no/) car je n'ai qu'une seule machine pour le moment.
#+BEGIN_SRC
Do you want to configure a new storage pool? (yes/no) [default=yes]:
#+END_SRC
Ici, laisser le choix par défaut (/yes/) pour configurer le stockage d'/Incus/.
#+BEGIN_SRC
Name of the new storage pool [default=default]:
#+END_SRC
Ici, il est possible de choisir le nom pour le stockage, je laisse la valeur par défaut.
#+BEGIN_SRC
Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
#+END_SRC
Ici, il est possible de choisir le système de stockage qui sera utilisé. Dans mon cas, j'ai choisi =dir=.
#+BEGIN_INFO
=dir= n'est pas recommandé pour la production, mais permet d'accéder facilement aux fichiers présents dans les conteneurs sans passer par /Incus/.
#+END_INFO
#+BEGIN_SRC
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=incusbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
#+END_SRC
Laisser ces choix à leurs valeurs par défaut, il s'agit ici de configurer le réseau qui sera utilisé par nos invités.
#+BEGIN_SRC
Would you like the Incus server to be available over the network? (yes/no) [default=no]: yes
#+END_SRC
Ici, il est possible de permettre (ou non) d'accéder au serveur depuis le réseau.
Je choisi /yes/ car je veux pouvoir gérer /Incus/ depuis ma machine de travail.
#+BEGIN_SRC
Address to bind Incus to (not including port) [default=all]:
Port to bind Incus to [default=8443]:
#+END_SRC
Laisser ces choix à leurs valeurs par défaut aussi, il s'agit de configurer le port et l'interface sur laquelle l'/API/ d'/Incus/ se mettra en écoute.
#+BEGIN_SRC
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
#+END_SRC
Ici, il est possible d'activer (ou non) la mise à jour automatique des images de VM ou CT.
Laisser le choix par défaut (/yes/).
#+BEGIN_SRC
Would you like a YAML "incus admin init" preseed to be printed? (yes/no) [default=no]:
#+END_SRC
Laisser le choix par défaut (/no/).
** Configurer l'utilisateur d'administration
Il est possible et recommandé de créer un utilisateur spécifique pour l'administration du serveur /Incus/.
Dans mon cas, cet utilisateur sera =balin=.
Ajouter l'utilisateur aux groupes /Incus/ :
#+BEGIN_SRC
usermod -aG incus-admin balin
usermod -aG incus balin
#+END_SRC
Configurer les =subuid= et =subgid= pour l'utilisateur =root= :
Dans les fichiers =/etc/subuid= et =/etc/subgid=, ajoutez la ligne suivante :
#+BEGIN_SRC
root:1000000:1000000000
#+END_SRC
#+BEGIN_WARNING
*Redémarrer la machine*
#+END_WARNING
** Configuration du pare-feu / réseau
#+BEGIN_INFO
Les commandes données utiliseront =firewalld= car c'est le programme par défaut de /Fedora/.
#+END_INFO
Ajouter une zone pour le pont réseau
#+BEGIN_SRC
firewall-cmd --new-zone=bridge --permanent
firewall-cmd --reload
#+END_SRC
Ajouter le pont réseau à la nouvelle zone
#+BEGIN_SRC
firewall-cmd --zone=bridge --add-interface=incusbr0 --permanent
firewall-cmd --zone=bridge --set-target=ACCEPT --permanent
firewall-cmd --reload
#+END_SRC
Lancer =firewall-cmd --zone=bridge --list-all= et vérifier le résultat
#+BEGIN_SRC
bridge (active)
target: ACCEPT
icmp-block-inversion: no
interfaces: incusbr0
sources:
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
#+END_SRC
Créer une zone pour le réseau local
#+BEGIN_SRC
firewall-cmd --new-zone=local --permanent
firewall-cmd --reload
#+END_SRC
Accepter le trafic local dans la nouvelle zone
#+BEGIN_SRC
firewall-cmd --zone=local --add-source=127.0.0.1/8 --permanent
firewall-cmd --zone=local --set-target=ACCEPT --permanent
firewall-cmd --reload
#+END_SRC
Vérifier la configuration de la nouvelle zone =firewall-cmd --zone=local --list all=
#+BEGIN_SRC
local (active)
target: ACCEPT
icmp-block-inversion: no
interfaces:
sources: 127.0.0.1/8
services:
ports:
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
#+END_SRC
Ajouter le réseau local dans la zone =trusted= ainsi que le service =ssh= (si pas déjà fait)
#+BEGIN_SRC
firewall-cmd --zone=trusted --add-source=192.168.1.0/24
firewall-cmd --zone=trusted --add-service=ssh
firewall-cmd --runtime-to-permanent
firewall-cmd --reload
#+END_SRC
*** Configuration d'un pont physique
J'ai choisi d'utiliser la deuxième interface réseau de ma machine (=enp5s0f1=) pour permettre aux VMs et CTs d'accéder en direct à mon réseau local.
#+BEGIN_SRC
incus network create localnet --type=physical parent=enp5s0f1
#+END_SRC
Pour que cela fonctionne, il est aussi nécessaire d'installer et démarrer =openvswitch=
#+BEGIN_SRC
dnf install -y openvswitch
systemctl enable --now openvswitch
systemctl start openvswitch
#+END_SRC
* Commandes utiles
- =incus list= :: Lister toutes les instances (conteneurs et machines virtuelles).
- =incus launch images:ubuntu/22.04 <nim>= :: Créer et démarrer un conteneur à partir dune image Ubuntu 22.04.
- =incus start <nom>= :: Démarrer une instance existante.
- =incus stop <nom>= :: Arrêter une instance en cours dexécution.
- =incus restart <nom>= :: Redémarrer une instance.
- =incus delete <nom>= :: Supprimer définitivement une instance.
- =incus exec <nom> -- bash= :: Ouvrir un shell interactif dans un conteneur.
- =incus file pull <nom>/chemin/vers/fichier ./= :: Copier un fichier depuis un conteneur vers la machine hôte.
- =incus file push ./fichier <nom>/chemin/= :: Copier un fichier de la machine hôte vers un conteneur.
- =incus config show <nom>= :: Afficher la configuration dune instance.
- =incus image list= :: Lister les images disponibles localement.
- =incus profile list= :: Lister les profils de configuration disponibles.
- =incus network list= :: Lister les réseaux configurés.
* Lancer des conteneurs et tester
Nous allons maintenant lancer deux conteneurs pour vérifier que tout fonctionne et qu'ils peuvent communiquer entre eux.
Lancer les conteneurs
#+BEGIN_SRC
incus launch images:fedora/43 foo
incus launch images:fedora/43 bar
#+END_SRC
Dans un premier terminal, lancer
#+BEGIN_SRC
incus exec foo -- bash
#+END_SRC
Et dans un second
#+BEGIN_SRC
incus exec bar -- bash
#+END_SRC
Normalement le =ping= entre les deux devrait fonctionner.
Les deux conteneurs devraient avoir des adresses /IP/ similaires à =10.123.111.40/24=, donc des adresses /IP/ qui ne sont pas dans le réseau local mais dans le réseau d'/Incus/.
* Lancer un conteneur dans le réseau local
Précédemment, un pont "physique" a été créé pour permettre de connecter des VMs et CTs directement au réseau local.
Créer un conteneur sans interface réseau
#+BEGIN_SRC
incus init images:fedora/43 testlocal
#+END_SRC
Lui ajouter une interface réseau
#+BEGIN_SRC
incus config device add testlocal eth0 nic nictype=macvlan parent=enp5s0f1 name=eth0
#+END_SRC
Puis le démarrer
#+BEGIN_SRC
incus start testlocal
#+END_SRC
Finalement, ouvrir un /shell/ dans le conteneur
#+BEGIN_SRC
incus exec testlocal -- bash
#+END_SRC
Et vérifier son adresse /IP/.
Il devrait avoir une interface =eth0= avec une adresse /IP/ dans le réseau local et attribuée par le routeur.
* Sources
- [[https://linuxcontainers.org/incus/docs/main/tutorial/first_steps/][Documentation officielle]]
- [[https://docs.rockylinux.org/10/books/incus_server/00-toc/][Documentation sur /RockyLinux/]]