Mémento 5.21 - Conteneurs LXC
LXC = LinuX Container
En virtualisation, l’isolation des VM se fait au niveau matériel (CPU/RAM/Disque ...) avec un accès virtuel aux ressources de l'hôte via un hyperviseur tel VirtualBox.
En conteneurisation type LXC, l'isolation des conteneurs se fait au niveau de l'OS. Ceux-ci s'exécuteront de manière native en utilisant le noyau de l'hôte et en ne prenant pas plus de mémoire que tout autre exécutable.
LXC va permettre d'approcher l'architecture standard d'Open vSwitch en utilisant des interfaces réseau virtuelles de type Veth pour la liaison des conteneurs avec le switch virtuel.
La partie 1 aborde le conteneur LXC de base dit privilégié dont root sera l'utilisateur interne.
La partie 2 aborde un conteneur plus sécurisé dit non privilégié, celui-ci devant éviter qu'une faille de sécurité donne à l'utilisateur root du conteneur la possibilité d'obtenir les privilèges complets sur l'hôte LXC.
1 - LXC (Création d'un conteneur privilégié)
1.1 - Installation de LXC
Installez les paquets lxc et lxc-templates :
[switch@ovs:~$] sudo apt install lxc lxc-templates
Vérifiez ensuite l'activation du routage au sein de la VM :
[switch@ovs:~$] sudo sysctl net.ipv4.ip_forward
La valeur retournée doit être égale à 1.
Vérifiez aussi la bonne activation des services LXC :
[switch@ovs:~$] sudo systemctl status lxc [switch@ovs:~$] sudo systemctl status lxc-net
Les statuts retournés doivent être : active(exited).
LXC a besoin que cgroup soit monté pour fonctionner.
Control groups (cgroup) est une fonctionnalité du noyau Linux pour limiter, compter et isoler l'utilisation des ressources (processeur, mémoire, disque, etc...).
Vérifiez le montage automatique de cgroup version 2 :
[switch@ovs:~$] mount | grep cgroup
Retour :
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid...)
Pour finir, vérifiez la nouvelle configuration réseau :
[switch@ovs:~$] ip address
Un nouveau bridge de nom lxcbr0 a fait son apparition :
Ce bridge fourni par défaut avec LXC sera non exploité au profit des bridges br0 et br2 d'OVS.
1.2 - Création d'un conteneur de nom ctn1
Préambule :
Les configurations LXC seront stockées dans /etc/lxc qui contient pour l'instant un unique default.conf.
Des modèles de configuration sont disponibles dans /usr/share/doc/lxc/examples/.
La création de conteneurs peut être réalisée à l'aide de templates situés dans /usr/share/lxc/templates/ ou en téléchargeant une distribution spécifique sur Internet.
C'est la méthode de téléchargement qui sera utilisée ici.
Créez le conteneur de nom ctn1 comme suit :
[switch@ovs:~$] sudo lxc-create -n ctn1 -t download -- \ -d debian -r bullseye -a amd64
Le caractère \ indique d'écrire le tout sur une seule ligne.
Si Unable to fetch GPG key ..., utilisez le dépôt Ubuntu :
[switch@ovs:~$] sudo \ DOWNLOAD_KEYSERVER="keyserver.ubuntu.com" \ lxc-create -n ctn1 -t download -- -d debian -r bullseye -a amd64
Le résultat de la Cde lxc-create doit donner ceci :
La distribution téléchargée a été mise en cache dans /var/cache/lxc/download/.
Vérifiez la création et le statut stoppé du conteneur :
[switch@ovs:~$] sudo lxc-ls -f
et afficher sa configuration par défaut :
[switch@ovs:~$] sudo cat /var/lib/lxc/ctn1/config
1.3 - Configuration réseau du conteneur
La partie réseau doit être traitée avant de démarrer ctn1.
LXC configure de base une connexion virtuelle de type veth pour raccorder ctn1 au bridge lxcbr0.
Le type veth permet de créer une interface réseau sur le bridge lxcbr0 et une autre sur ctn1.
La configuration de ctn1 doit être modifiée pour raccorder celui-ci sur le bridge br0 d'OVS.
Configuration à créer :
Pour cela, éditez la configuration du conteneur :
[switch@ovs:~$] sudo nano /var/lib/lxc/ctn1/config
et modifiez la partie réseau comme suit :
# Network configuration
lxc.net.0.type = veth
#lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.script.up = /etc/lxc/ovsup-ctn1
lxc.net.0.script.down = /etc/lxc/ovsdown-ctn1
lxc.net.0.ipv4.address = 192.168.3.6/24
lxc.net.0.ipv4.gateway = 192.168.3.15 # IP enp0s3 VM ovs
Créez ensuite le script ovsup-ctn1 :
[switch@ovs:~$] sudo nano /etc/lxc/ovsup-ctn1
et entrez le contenu suivant :
#!/bin/bash
BRIDGE="br0"
ovs-vsctl --may-exist add-br $BRIDGE
ovs-vsctl --if-exists del-port $BRIDGE $5
ovs-vsctl --may-exist add-port $BRIDGE $5
Au démarrage de ctn1, le script attachera celui-ci à OVS.
Créez le script ovsdown-ctn1 :
[switch@ovs:~$] sudo nano /etc/lxc/ovsdown-ctn1
et entrez le contenu suivant :
#!/bin/bash
BRIDGE="br0"
ovs-vsctl --if-exists del-port $BRIDGE $5
A l'arrêt de ctn1, le script détachera celui-ci d'OVS.
Rendez les 2 scripts exécutables :
[switch@ovs:~$] sudo chmod +x /etc/lxc/ovs*
La configuration réseau de ctn1 est maintenant prête.
1.4 - Démarrage du conteneur
Pour démarrer ctn1, lancez la Cde suivante :
[switch@ovs:~$] sudo lxc-start -n ctn1
et vérifiez ensuite le statut du conteneur :
[switch@ovs:~$] sudo lxc-ls -f
Vérifiez aussi la création d'une interface réseau veth :
[switch@ovs:~$] ip address
Remarque : Depuis Debian 11.3, l'adresse IPv4 peut ne pas apparaître du fait de l'intervention du service systemd-networkd activé par défaut dans le conteneur.
Pour régler ce problème, procédez comme suit :
[switch@ovs:~$] sudo lxc-attach -n ctn1 [root@ctn1:/#] systemctl stop systemd-networkd [root@ctn1:/#] systemctl disable systemd-networkd [root@ctn1:/#] exit [switch@ovs:~$] sudo reboot [switch@ovs:~$] sudo lxc-start -n ctn1 [switch@ovs:~$] sudo lxc-ls -f
L'adresse IPv4 192.168.3.6 doit cette fois apparaître.
1.5 - Exécution de Cdes dans le conteneur
Le conteneur a été créé par défaut sans MDP root.
La Cde lxc-attach permet d’exécuter des Cdes dans un conteneur, ceci en tant que root.
Utilisez celle-ci pour vous connecter sur ctn1 :
[switch@ovs:~$] sudo lxc-attach -n ctn1
Un prompt root@ctn1:/# doit s'afficher.
Affichez ensuite la configuration réseau de ctn1 :
[root@ctn1:/#] ip address
Il faut, afin que ctn1 accède à Internet, lui préciser l'IP du serveur DNS à utiliser.
Pour cela, éditez le fichier DNS resolv.conf de ctn1 :
[root@ctn1:/#] vim /etc/resolv.conf
et ajoutez la ligne suivante :
nameserver 192.168.x.z # IP de votre Box Internet
Instructions pour utiliser l'éditeur de textes vim :
Touche i (mode insertion) > Pour entrez nameserv... .
Touche Escape > Pour quitter le mode insertion.
Touches :wq suivies de Entrée > Pour sauvegarder.
Pour tester l'accès à Internet, installez l'éditeur nano :
[root@ctn1:/#] apt install nano
Enfin, utilisez la Cde exit pour quitter le conteneur.
Remarque : Depuis Debian 11.3, le nameserver peut être par la suite écrasé du fait de l'intervention du service systemd-resolved activé par défaut dans le conteneur.
Pour régler ce problème, procédez comme suit :
[switch@ovs:~$] sudo lxc-attach -n ctn1 [root@ctn1:/#] systemctl stop systemd-resolved [root@ctn1:/#] systemctl disable systemd-resolved [root@ctn1:/#] rm /etc/resolv.conf [root@ctn1:/#] nano /etc/resolv.conf
Entrez ce contenu dans le nouveau fichier resolv.conf :
nameserver 192.168.x.z # IP de votre Box Internet
Puis, quittez ctn1, rebootez ovs et redémarrez ctn1 :
[root@ctn1:/#] exit [switch@ovs:~$] sudo reboot [switch@ovs:~$] sudo lxc-start -n ctn1 [switch@ovs:~$] sudo lxc-ls -f
Entrez ensuite dans ctn1 et vérifiez si le nameserver du fichier resolv.conf est correct.
1.6 - Démarrage automatique du conteneur
Il est possible de démarrer automatiquement ctn1 au boot de l'hôte LXC soit la VM ovs.
Pour cela, éditez la configuration du conteneur :
[switch@ovs:~$] sudo nano /var/lib/lxc/ctn1/config
et ajoutez ce contenu à la fin du fichier :
# Démarrage auto du conteneur au bout de 10s
lxc.start.auto = 1
lxc.start.delay = 10
Puis rebootez la VM ovs et contrôlez le statut de ctn1 :
[switch@ovs:~$] sudo lxc-ls -f
Retour :
1.7 - Quelques Cdes LXC utiles
lxc-stop -n ctn1 > Stoppe ctn1
lxc-snapshot -n ctn1 > Crée un snapshot de ctn1
lxc-destroy -s -n ctn1 > Détruit ctn1 et ses snapshots
lxc-info -n ctn1 > Fournit des informations sur ctn1
lxc-copy -n ctn1 > Crée un clone de ctn1
Utilisez la Cde man lxc pour en découvrir d'autres.
1.8 - Tests divers sur le réseau virtuel
Testez depuis l'intérieur de ctn1 les pings suivants :
[root@ctn1:/#] ping mappy.fr # Internet [root@ctn1:/#] ping 192.168.2.1 # VM srvsec [root@ctn1:/#] ping 192.168.4.2 # VM srvdmz [root@ctn1:/#] ping 192.168.3.4 # VM debian11-vm2
Tous doivent recevoir une réponse positive.
Pour finir, testez un ping depuis la VM srvsec sur ctn1 :
[root@srvsec:~#] ping 192.168.3.6 # Conteneur ctn1
Si retour OK, la partie 1 est alors terminée.
Voilà, première étape franchie !
La partie 2 vous attend à présent
pour la création d'un conteneur
LXC dit non privilégié.
Bonjour,
Petits soucis pour obtenir une @ip au point 1.4-démarrage du container
Bien suivi le mémento et revérifier toutes les étapes, mais lorsque je lance la commande :
sudo lxc-ls -f
J’obtiens bien ctn1 RUNNING mais ipv4: vide
de même pour l interface réseau veth
Remerciements
Bonjour,
Au premier abord, votre souci semble provenir d’un problème de configuration réseau dans le paragraphe 1.3.
1) Fichier config sur mes serveurs :
Le contenu des fichiers config est identique au contenu du mémento mais sans le commentaire « # IP enp0s3 VM ovs ». Enlevez celui-ci si vous l’avez laissé au cas ou lxc n’aime pas cette syntaxe.
2) Plus important, revérifiez la syntaxe des fichiers ovsup et ovsdown en faisant bien attention aux tirets simples ou doubles et revérifiez le côté exécutable.
La Cde ls -l /etc/lxc renverra :
-rwxr-xr-x 1 root root … ovsdown-ctn1
-rwxr-xr-x 1 root root … ovsup-ctn1
3) Vérifiez les logs de démarrage de ctn1.
Pour cela, stoppez le conteneur :
$ sudo lxc-stop -n ctn1
$ sudo lxc-ls -f
Observez la fin du fichier syslog :
$ sudo cat /var/log/syslog
Attendez 2mn et redémarrez ctn1 :
$ sudo lxc-start -n ctn1
$ sudo lxc-ls -f
Observez de nouveau la fin de syslog :
$ sudo cat /var/log/syslog
Celui-ci doit montrer ce contenu :
Jun 21 20:28:25 ovs kernel: [823874.506193] audit: type=1400 audit(1655836105.468:21): apparmor= »STATUS » operation= »profile_load » profile= »/usr/bin/lxc-start » name= »lxc-ctn1_ » pid=10524 comm= »apparmor_parser »
Jun 21 20:28:25 ovs systemd-udevd[10532]: ethtool: autonegotiation is unset or enabled, the speed and duplex are not writable.
Jun 21 20:28:25 ovs systemd-udevd[10532]: Using default interface naming scheme ‘v247’.
Jun 21 20:28:25 ovs ovs-vsctl: ovs|00001|vsctl|INFO|Called as ovs-vsctl –may-exist add-br br0
Jun 21 20:28:25 ovs ovs-vsctl: ovs|00001|vsctl|INFO|Called as ovs-vsctl –if-exists del-port br0 veth4bahiN
Jun 21 20:28:25 ovs ovs-vsctl: ovs|00001|vsctl|INFO|Called as ovs-vsctl –may-exist add-port br0 veth4bahiN
Jun 21 20:28:25 ovs kernel: [823874.579224] device veth4bahiN entered promiscuous mode
Jun 21 20:28:25 ovs kernel: [823874.587304] eth0: renamed from vethvsMbfe
Jun 21 20:28:25 ovs kernel: [823874.588547] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
Jun 21 20:28:25 ovs kernel: [823874.588581] IPv6: ADDRCONF(NETDEV_CHANGE): veth4bahiN: link becomes ready
Jun 21 20:28:25 ovs kernel: [823874.635291] Not activating Mandatory Access Control as /sbin/tomoyo-init does not exist.
Jun 21 20:28:28 ovs ntpd[894]: Listen normally on 19 veth4bahiN [fe80::fd15:2dff:fa4f:8673%12]:123
Jun 21 20:28:28 ovs ntpd[894]: new interface(s) found: waking up resolver
Les chaînes en gras permettent de vérifier la syntaxe et le résultat de la configuration incluse dans les fichiers ovsup et ovsdown.
Aucune erreur de doit apparaître dans les lignes de log ci-dessus.
Si tout est OK, l’IP fixe 192.168.3.6 doit s’afficher dans le statut du conteneur.
Dernier conseil pour la syntaxe, je me suis souvent fait piéger par un simple espace ajouté malencontreusement en fin d’une instruction. Dans bien des cas cela n’a pas d’importance, dans d’autres si.
Merci de me tenir au courant.
InfoLoup
Bonjour,
je ne sais pas si cela à une incidence?? mais ne pouvant obtenir une @ip dans le container ctn1 sur Debian 11..
J ai testé avec une VM Ubuntu 22.04 même résultat quelques soit le container créer ubuntu/debian,etc , aucune adresse ip après avoir réussi à démarrer le container avec ces commandes:
#lxc-start -n ctn1
#lxc-ls –fancy
Ensuite refait le test avec une ancienne VM Ubuntu 18.04 et là bingo! ..j’obtient une adresse ipv4 (10.0.3.2) dans ctn1, VM en NAT avec une seule carte configurée pour test.
Remerciement
Bonjour,
Bizarre, la parenthèse retirée du fichier interfaces d’ovs devait régler ce problème d’IP dans ctn1.
J’ai vérifié plusieurs fois.
Essayez ceci depuis la vm ovs :
$ cd /home/switch
$ sudo lxc-stop -n ctn1
$ sudo lxc-ls -f
$ sudo systemctl restart networking
$ sudo systemctl status networking
Le retour ne doit montrer aucune erreur.
Si OK :
$ sudo lxc-start -n ctn1 –logfile=ctn1-start.log –logpriority=INFO
$ sudo lxc-ls -f
$ sudo cat ctn1-start.log
Observez le contenu du fichier log et vérifiez qu’il n’y a pas en dehors de INFO, NOTICE ou WARN une ligne contenant ERROR.
Bon courage
InfoLoup
Bonjour, voici le résultat des commandes (aucune ip dans le ctn1)
switch@fab-VirtualBox:~$ cd /home/switch
switch@fab-VirtualBox:~$ sudo lxc-ls -f
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
container_xenial STOPPED 0 – – – false
ctn1 STOPPED 0 – – – false
ctn2 STOPPED 0 – – – false
switch@fab-VirtualBox:~$ sudo lxc-start -n ctn1
switch@fab-VirtualBox:~$ sudo lxc-ls -f
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
container_xenial STOPPED 0 – – – false
ctn1 RUNNING 0 – – – false
ctn2 STOPPED 0 – – – false
switch@fab-VirtualBox:~$ sudo cat ctn1-start.log
cat: ctn1-start.log: Aucun fichier ou dossier de ce type
Bonjour,
Difficile de vous aider.
Je vois dans vos traces qu’ovs est sous Ubuntu.
Ubuntu ne fonctionne pas comme Debian 11.
Votre Ubuntu utilise peut-être NETPLAN pour sa configuration réseau ainsi que LXD en complément de LXC.
Essayez de démarrer le conteneur créé par défaut de nom container_xenial pour voir s’il récupère une adresse IPv4 et utilisez de la documentation concernant la gestion LXC sous Ubuntu.
Pour ma part, je ne rencontre aucun problème de gestion sous Debian 11 (J’utilise 4 VM intégrant openvswitch et des conteneurs LXC reliés à openvswitch).
Pour le fichier log, celui-ci est normalement créé dans le dossier d’où la Cde lxc-start est lancée.
Si c’est depuis /home/switch, il sera créé dans /home/switch.
Essayez la Cde sans le paramètre –logpriority :
$ sudo lxc-start -n ctn1 –logfile=ctn1-start.log (double tiret devant logfile)
Cordialement.
InfoLoup
Pour le problème d’IPV4 static, il semble que cela vienne des releases > à 11.3 de Debian Bullseye et plus particulière du service networkd.
La solution est de desactiver le service :
root@ctn1:/etc# systemctl list-units | grep network
systemd-networkd.service loaded active running Network Service
systemd-networkd.socket loaded active running Network Service Netlink Socket
network.target loaded active active Network
root@ctn1:/etc# systemctl stop systemd-networkd
Warning: Stopping systemd-networkd.service, but it can still be activated by:
systemd-networkd.socket
root@ctn1:/etc# systemctl disable systemd-networkd
Removed /etc/systemd/system/sockets.target.wants/systemd-networkd.socket.
Removed /etc/systemd/system/multi-user.target.wants/systemd-networkd.service.
Removed /etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service.
Removed /etc/systemd/system/dbus-org.freedesktop.network1.service.
root@ctn1:/etc# systemctl list-units | grep network
systemd-networkd.socket loaded active listening Network Service Netlink Socket
network.target loaded active active Network
root@ctn1:/etc#
oot@ctn1:/etc# reboot
root@ctn1:/etc#
laurent@ovs:/var/log$ sudo lxc-ls -f
[sudo] Mot de passe de laurent :
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
ctn1 RUNNING 0 – 192.168.3.6 – false
Merci pour l’information.
Il faut effectivement que le service systemd-networkd soit désactivé.
Mon mémento traite uniquement pour le réseau du fichier /etc/network/interfaces soit le service networking.
Je n’ai jamais eu à activer et lancer le service systemd-networkd encore moins à le désactiver.
Mes conteneurs sont en version Debian 11.5.
Votre commentaire peut aider d’autres personnes qui auraient pour une raison ou une autre le service systemd-networkd activé.
Bonne journée.
InfoLoup