OVS – LXC / Debian 11 : 1/2

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 :

Capture - LXC : Bridge lxcbr0 ajouté sur la VM ovs
LXC : Bridge lxcbr0 ajouté sur la VM ovs

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 :

Capture - LXC : Conteneur créé sans échec
LXC : Conteneur ctn1 créé sans échec

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
Capture - LXC : Statut du conteneur ctn1
LXC : Statut du conteneur ctn1

et afficher sa configuration par défaut :

[switch@ovs:~$] sudo cat /var/lib/lxc/ctn1/config
Capture - LXC : Configuration de base du conteneur ctn1
LXC : Configuration de base du conteneur ctn1

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 :

Image - LXC : Configuration conteneur ctn1 vers bridge br0 d'OVS
LXC : Configuration conteneur ctn1 vers bridge br0 d'OVS

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
Capture - LXC : Conteneur ctn1 démarré
LXC : Conteneur ctn1 démarré

Vérifiez aussi la création d'une interface réseau veth :

[switch@ovs:~$] ip address
Capture - LXC : Interface réseau veth...@if2 créée sur la VM ovs
LXC : Interface réseau veth...@if2 créée sur la VM ovs

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
Capture - LXC : Le conteneur montre une interface réseau eth0@if10
LXC : Le conteneur montre une interface réseau eth0@if10

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 :

Capture - LXC : Démarrage automatique  du conteneur ctn1
LXC : Démarrage automatique du conteneur ctn1

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.

Image - Rédacteur satisfait


Voilà, première étape franchie !
La partie 2 vous attend à présent
pour la création d'un conteneur
LXC dit non privilégié.

8 réflexions au sujet de “OVS – LXC / Debian 11 : 1/2”

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

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

  8. 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

Laisser un commentaire