Installer et utiliser LXC sur Gentoo / Calculate Linux
Table des matières
LXC, contraction de l’anglais LinuX Containers est un système de virtualisation, utilisant l'isolation comme méthode de cloisonnement au niveau du système d'exploitation. Il est utilisé pour faire fonctionner des environnements Linux isolés les uns des autres dans des conteneurs partageant le même noyau et une plus ou moins grande partie du système hôte. Le conteneur apporte une virtualisation de l'environnement d'exécution (Processeur, Mémoire vive, réseau, système de fichier… ) et non pas de la machine. Pour cette raison, on parle de « conteneur » et non de machine virtuelle.
Ce système est similaire aux autres systèmes de virtualisations au niveau du système d'exploitation comme openVZ.
Tout le long de l'article, j'ai utilisé une Gentoo Linux, avec le noyau 4.4.6.
Aucun FLAG par défaut n'est activé.
On va activer deux FLAG : examples et doc vont nous fournir des modèles de base tout prêt pour déployer rapidement nos conteneurs.
Les dernières versions de lxc sont archtildées sur Gentoo. Si on veut du plus récent, on ajoute LXC au fichier packages.keywords :
On lance l'installation :
Voilà, c'est installé.
Si on souhaite par la suite installer un conteneur fonctionnant sous Debian, il est nécessaire d'installer dev-util/debootstrap :
Si on souhaite par la suite installer un conteneur fonctionnant sous Fedora ou CentOS, il est nécessaire d'installer sys-apps/yum qui installera aussi en dépendance app-arch/rpm .
On ajoute quelques paquets au fichier package.keywords et ajoutons les USE lua et python à RPM :
On installe ensuite yum :
LXC a besoin des fonctionnalités CGROUP du noyau linux.
Pour vérifier ce qui manque comme fonctionnalités dans le noyau, on peut utiliser la commande :
Normalement, si on utilise Calculate Linux, tout est "enabled".
Se rendre dans les sources :
Et configurer les options manquantes avec :
On enregistre puis on recompile le noyau :
Si initramfs il y a (ce n'est pas mon cas) :
On n'oublie pas de mettre à jour GRUB2 si la version du noyau est différente :
On redémarre ensuite pour démarrer sur le nouveau noyau :
Une fois redémarré, on vérifie que la config est bonne :
Pour utiliser nos conteneurs, on a besoin d'une interface réseau en mode pont (bridge).
On installe les modules réseau nécessaires :
On édite ensuite le fichier de configuration des interfaces réseaux :
On commente la configuration de l'interface en cours (chez moi eno1), on indique à null sa configuration et on créée le pont nommé br0 :
On n'oublie pas de créer le lien symbolique qui va bien et de lancer cette connexion au démarrage :
On redémarre pour vérifier le bon fonctionnement du pont réseau :
On vérifie avec ifconfig que l'interface br0 ait bien son adresse IP et que les communications réseaux fonctionnent correctement.
Tous les fichiers sont stockés dans /etc/lxc.
Un dossier sera créé par conteneur, et contient :
La commande pour créer un conteneur est lxc-create et s'utilise de cette manière :
Voici quelques syntaxes :
Pour un conteneur nommé alpha de type Gentoo :
Pour un conteneur nommé beta de type Debian :
Pour un conteneur nommé gamma de type Fedora :
Pour un conteneur nommé delta de type CentOS :
Pour un conteneur nommé delta7 de type CentOS 7 (on veut préciser la version) :
En fait, il faut, pour préciser des options au template utiliser le code "--" puis les arguments propres au conteneur
La configuration est localisée dans /home/lxc/nomduconteneur/config.
Par défaut, le réseau est sur :
Commenter cette ligne si on souhaite avoir du réseau dans le conteneur.
Voici un exemple de configuration, avec un conteneur LXC connecté directement au réseau local :
Quelques explications...
Il est possible d'imposer des points de montage dans le conteneur via la ligne lxc.mount.entry.
La syntaxe :
En vrac, mais commentés :
Pour lister les conteneurs installés, on utilise la commande lxc-ls :
Si on souhaite lister les conteneurs démarrés, on utilise l'option --active :
Pour démarrer un conteneur, on utilise la commande lxc-start avec l'option -n pour spécifier le nom et -d pour lancer le conteneur en tant que démon :
Pour se connecter sur un conteneur en cours d'exécution, on utilise la commande lxc-console :
Pour sortir de la console tout en laissant le conteneur démarré, saisir Ctrl+a q.
Il est possible d'obtenir quelques informations sur un conteneur lancé grâce à la commande lxc-info :
Voici un exemple :
Pour un conteneur arrêté :
Pour cela, deux solutions :
Cloner un conteneur, c'est possible ! Dans ce cas, l'arrêter avant, puis, utiliser la commande lxc-clone :
Voici un exemple :
Par défaut, tout le conteneur est cloné, le nom d'hôte change, l'adresse MAC de l'interface aussi.
En cas d'utilisation en tant que "sauvegarde" utiliser les options K et M :
Pour démarrer un conteneur à l'initialisation du système hôte, il suffit de créer un lien symbolique de LXC dans /etc/init.d avec le nom du conteneur.
Voici la suite de commandes pour créer le lien symbolique et activer le conteneur au démarrage :
Démonstration avec le conteneur testfedo :
Il est aussi possible de créer un script terminant par .start pour lancer les conteneurs voulus dans /etc/local.d, par exemple 01-lxc.start :
Le rendre exécutable :
Vérifier que le service local démarre bien :
On fait de même un script pour arrêter proprement les LXC démarrés avec un script terminant par .stop dans /etc/local.d, par exemple 01-lxc.stop :
Et on le rend exécutable :
Prendre des instantané de conteneurs, c'est aussi possible. Néanmoins, les conteneurs doivent être arrêtés.
Pour effectuer un snapshot, on utilise la commande ... lxc-snapshot :
Pour voir les snapshots réalisés :
Exemple avec le conteneur, et création de snapshot et de listage des snapshots :
Pour restaurer un snapshot :
Pour supprimer un snapshot :
Pour supprimer un conteneur, celui-ci doit être arrêté. Ensuite, utiliser la commande ... il y a un piège ... lxc-destroy et non pas lxc-delete !
Pour sauvegarder un conteneur, il est possible d'effectuer une archive tar du conteneur en question :
Et voila, LXC n'a plus de mystères ...
- Présentation de LXC
- Installation de LXC
- Prérequis pour le bon fonctionnement
- Utiliser LXC
- Où sont les fichiers
- Créer un conteneur
- Personnaliser la configuration
- Lister les conteneurs
- Démarrer un conteneur
- Se connecter à un conteneur démarré
- Avoir des informations sur le conteneur
- Arrêter un conteneur
- Cloner un conteneur
- Démarrer un conteneur au lancement du système hôte
- Instantanés de conteneurs
- Supprimer un conteneur
- Sauvegarder un conteneur
Présentation de LXC
LXC, contraction de l’anglais LinuX Containers est un système de virtualisation, utilisant l'isolation comme méthode de cloisonnement au niveau du système d'exploitation. Il est utilisé pour faire fonctionner des environnements Linux isolés les uns des autres dans des conteneurs partageant le même noyau et une plus ou moins grande partie du système hôte. Le conteneur apporte une virtualisation de l'environnement d'exécution (Processeur, Mémoire vive, réseau, système de fichier… ) et non pas de la machine. Pour cette raison, on parle de « conteneur » et non de machine virtuelle.
Ce système est similaire aux autres systèmes de virtualisations au niveau du système d'exploitation comme openVZ.
Tout le long de l'article, j'ai utilisé une Gentoo Linux, avec le noyau 4.4.6.
Installation de LXC
Installation commune
Aucun FLAG par défaut n'est activé.
On va activer deux FLAG : examples et doc vont nous fournir des modèles de base tout prêt pour déployer rapidement nos conteneurs.
Code BASH :
echo "app-emulation/lxc examples doc #LXC" >> /etc/portage/package.use/custom
Les dernières versions de lxc sont archtildées sur Gentoo. Si on veut du plus récent, on ajoute LXC au fichier packages.keywords :
Code BASH :
echo "app-emulation/lxc #LXC" >> /etc/portage/package.keywords/custom
On lance l'installation :
Code BASH :
emerge -avq app-emulation/lxc
Voilà, c'est installé.
Installations optionnelles
Cas Debian
Si on souhaite par la suite installer un conteneur fonctionnant sous Debian, il est nécessaire d'installer dev-util/debootstrap :
Code BASH :
emerge -aqv dev-util/debootstrap
Cas Fedora/CentOS
Si on souhaite par la suite installer un conteneur fonctionnant sous Fedora ou CentOS, il est nécessaire d'installer sys-apps/yum qui installera aussi en dépendance app-arch/rpm .
On ajoute quelques paquets au fichier package.keywords et ajoutons les USE lua et python à RPM :
Code BASH :
echo "sys-apps/yum #LXC" >> /etc/portage/package.keywords/custom echo "dev-python/pyliblzma #LXC" >> /etc/portage/package.keywords/custom echo "app-arch/rpm lua python #LXC" >> /etc/portage/package.use/custom echo "dev-lang/python sqlite #LXC" >> /etc/portage/package.use/custom echo "dev-libs/libxml2 python #LXC" >> /etc/portage/package.use/custom
On installe ensuite yum :
Code BASH :
emerge -aqv sys-apps/yum
Prérequis pour le bon fonctionnement
Partie kernel
LXC a besoin des fonctionnalités CGROUP du noyau linux.
Pour vérifier ce qui manque comme fonctionnalités dans le noyau, on peut utiliser la commande :
Code BASH :
lxc-checkconfig
Code TEXT :
.--- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: missing Network namespace: enabled Multiple /dev/pts instances: missing .--- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: missing Cgroup sched: missing Cgroup cpu account: missing Cgroup memory controller: missing Cgroup cpuset: missing .--- Misc --- Veth pair device: missing Macvlan: enabled Vlan: enabled File capabilities: enabled Note : Before booting a new kernel, you can check its configuration usage : CONFIG=/path/to/config /usr/sbin/lxc-checkconfig
Normalement, si on utilise Calculate Linux, tout est "enabled".
Se rendre dans les sources :
Code BASH :
cd /usr/src/linux
Et configurer les options manquantes avec :
Code BASH :
make menuconfig
Code TEXT :
General setup ---> [*] Control Group support ---> [*] Freezer cgroup subsystem [*] PIDs cgroup subsystem [*] Device controller for cgroups [*] Cpuset support [*] Include legacy /proc/<pid>/cpuset file [*] Simple CPU accounting cgroup subsystem [*] Resource counters [*] Memory Resource Controller for Control Groups [*] Memory Resource Controller Swap Extension [*] Memory Resource Controller Swap Extension enabled by default [*] Enable perf_event per-cpu per-container group (cgroup) monitoring [*] Group CPU scheduler ---> [*] Group scheduling for SCHED_OTHER [*] Group scheduling for SCHED_RR/FIFO <*> Block IO controller -*- Namespaces support [*] UTS namespace [*] IPC namespace [*] User namespace [*] PID Namespaces [*] Network namespace [*] Networking support ---> Networking options ---> <M> 802.1d Ethernet Bridging <M> 802.1Q VLAN Support Device Drivers ---> [*] Network device support ---> <M> MAC-VLAN support <M> Virtual ethernet pair device Character devices ---> -*- Unix98 PTY support [*] Support multiple instances of devpts
On enregistre puis on recompile le noyau :
Code BASH :
make -j5 make modules_install make install
Si initramfs il y a (ce n'est pas mon cas) :
Code BASH :
mkinitrd /boot/initramfs-$noyau.img $noyau
On n'oublie pas de mettre à jour GRUB2 si la version du noyau est différente :
Code BASH :
grub-mkconfig -o /boot/grub/grub.cfg
On redémarre ensuite pour démarrer sur le nouveau noyau :
Code BASH :
reboot
Une fois redémarré, on vérifie que la config est bonne :
Code BASH :
lxc-checkconfig
Code BASH :
.--- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Network namespace: enabled Multiple /dev/pts instances: enabled .--- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled .--- Misc --- Veth pair device: enabled Macvlan: enabled Vlan: enabled File capabilities: enabled Note : Before booting a new kernel, you can check its configuration usage : CONFIG=/path/to/config /usr/sbin/lxc-checkconfig
Partie réseau
Pour utiliser nos conteneurs, on a besoin d'une interface réseau en mode pont (bridge).
On installe les modules réseau nécessaires :
Code BASH :
emerge -q net-misc/bridge-utils
On édite ensuite le fichier de configuration des interfaces réseaux :
Code BASH :
nano /etc/conf.d/net
On commente la configuration de l'interface en cours (chez moi eno1), on indique à null sa configuration et on créée le pont nommé br0 :
Code BASH :
#config_eno1="dhcp" config_eno1="null" # Pont réseau config_br0="10.21.21.242/24" routes_br0="default via 10.21.21.254" dns_servers="10.21.21.253" brctl_br0="setfd 0 sethello 10 stp off" bridge_br0="eno1"
On n'oublie pas de créer le lien symbolique qui va bien et de lancer cette connexion au démarrage :
Code BASH :
ln -s /etc/init.d/net.lo /etc/init.d/net.br0 rc-update add net.br0 default
On redémarre pour vérifier le bon fonctionnement du pont réseau :
Code BASH :
reboot
On vérifie avec ifconfig que l'interface br0 ait bien son adresse IP et que les communications réseaux fonctionnent correctement.
Utiliser LXC
Où sont les fichiers
Tous les fichiers sont stockés dans /etc/lxc.
Un dossier sera créé par conteneur, et contient :
- Un dossier rootfs (le / du conteneur)
- Un fichier config (la configuration du conteneur).
Créer un conteneur
La commande pour créer un conteneur est lxc-create et s'utilise de cette manière :
Code BASH :
lxc-create -n $NomDuConteneur -t $TypeDuConteneur
Voici quelques syntaxes :
Pour un conteneur nommé alpha de type Gentoo :
Code BASH :
lxc-create -n alpha-t gentoo
Pour un conteneur nommé beta de type Debian :
Code BASH :
lxc-create -n beta -t debian
Pour un conteneur nommé gamma de type Fedora :
Code BASH :
lxc-create -n gamma -t fedora
Pour un conteneur nommé delta de type CentOS :
Code BASH :
lxc-create -n delta -t centos
Pour un conteneur nommé delta7 de type CentOS 7 (on veut préciser la version) :
Code BASH :
lxc-create -t centos -n delta7 -- --release 7
En fait, il faut, pour préciser des options au template utiliser le code "--" puis les arguments propres au conteneur
Personnaliser la configuration
La configuration est localisée dans /home/lxc/nomduconteneur/config.
Partie réseau
Par défaut, le réseau est sur :
Code BASH :
lxc.network.type = empty
Commenter cette ligne si on souhaite avoir du réseau dans le conteneur.
Voici un exemple de configuration, avec un conteneur LXC connecté directement au réseau local :
Code BASH :
lxc.network.type = veth lxc.network.name = veth0 lxc.network.veth.pair = veth-test lxc.network.flags = up lxc.network.link = br0 lxc.network.ipv4 = 10.21.21.201/24 lxc.network.ipv4.gateway = 10.21.21.254
Quelques explications...
- lxc.network.type=veth : utilisation d’un bridge. Ce mode veth permet de créer deux interfaces : l’une est ajouté au bridge de l’hôte, l’autre est utilisée par le conteneur LXC. Les communications entre le conteneur et les autres de même configuration ainsi que l'extérieur sont possible.
- lxc.network.name = veth0 : nom de l'interface réseau dans le conteneur LXC.
- lxc.network.veth.pair = veth-test : nom de l'interface réseau du conteneur LXC sur l'hôte.
- lxc.network.flags = up : active l'interface.
- lxc.network.link = br0 : fait le lien sur le bridge br0 de l'hôte.
- lxc.network.ipv4 = 10.21.21.201/24 : adresse IPv4 du conteneur
- lxc.network.ipv4.gateway = 10.21.21.254 : passerelle pour le conteneur.
Points de montage
Il est possible d'imposer des points de montage dans le conteneur via la ligne lxc.mount.entry.
La syntaxe :
Code BASH :
lxc.mount.entry=/chemin/absolu/du/dossier chemin/relatif/dans/le/conteneur none rw,bind 0 0
D'autres attributs
En vrac, mais commentés :
Code BASH :
#Chemin de la racine du conteneur lxc.rootfs = /home/lxc/test/rootfs #Nom d'hôte du conteneur lxc.utsname = test
Lister les conteneurs
Pour lister les conteneurs installés, on utilise la commande lxc-ls :
Code BASH :
lxc-ls
debiantest test testcentos testfedo
Si on souhaite lister les conteneurs démarrés, on utilise l'option --active :
Code BASH :
lxc-ls --active test
Démarrer un conteneur
Pour démarrer un conteneur, on utilise la commande lxc-start avec l'option -n pour spécifier le nom et -d pour lancer le conteneur en tant que démon :
Code BASH :
lxc-start -n $NomDuConteneur
Se connecter à un conteneur démarré
Pour se connecter sur un conteneur en cours d'exécution, on utilise la commande lxc-console :
Code BASH :
lxc-console -n $NomDuConteneur
Pour sortir de la console tout en laissant le conteneur démarré, saisir Ctrl+a q.
Avoir des informations sur le conteneur
Il est possible d'obtenir quelques informations sur un conteneur lancé grâce à la commande lxc-info :
Code BASH :
lxc-info -n $NomDuConteneur
Voici un exemple :
Code BASH :
lxc-info -n testfedo Name: testfedo State: RUNNING PID: 3779 IP: 10.21.21.203 CPU use: 477.60 seconds Memory use: 1.27 MiB Link: veth-fedo TX bytes: 648 bytes RX bytes: 3.38 KiB Total bytes: 4.02 KiB
Pour un conteneur arrêté :
Code BASH :
lxc-info -n testcentos
Name: testcentos
State: STOPPED
Arrêter un conteneur
Pour cela, deux solutions :
- Se connecter dans le conteneur via la console, et saisir la commande halt.
- Utiliser la commande lxc-stop.
Code BASH :
lxc-stop -n $NomDuConteneur
Cloner un conteneur
Cloner un conteneur, c'est possible ! Dans ce cas, l'arrêter avant, puis, utiliser la commande lxc-clone :
Code BASH :
lxc-clone $NOM $NOUVEAUNOM
Voici un exemple :
Code BASH :
lxc-clone test testclone Created container testclone as copy of test
Par défaut, tout le conteneur est cloné, le nom d'hôte change, l'adresse MAC de l'interface aussi.
En cas d'utilisation en tant que "sauvegarde" utiliser les options K et M :
Code BASH :
lxc-clone -KM $NOM $NOUVEAUNOM
Démarrer un conteneur au lancement du système hôte
Solution native
Pour démarrer un conteneur à l'initialisation du système hôte, il suffit de créer un lien symbolique de LXC dans /etc/init.d avec le nom du conteneur.
Voici la suite de commandes pour créer le lien symbolique et activer le conteneur au démarrage :
Code BASH :
cd /etc/init.d/ ln -sv lxc /etc/init.d/lxc.$NOM rc-update add lxc.$NOM default
Démonstration avec le conteneur testfedo :
Code BASH :
cd /etc/init.d ln -sv lxc lxc.testfedo « lxc.testfedo » -> « lxc » rc-update add lxc.testfedo default * service lxc.testfedo added to runlevel default
Solution script
Il est aussi possible de créer un script terminant par .start pour lancer les conteneurs voulus dans /etc/local.d, par exemple 01-lxc.start :
Code BASH :
#! /bin/bash for lxc in cont1 cont2 cont3 do lxc-start -n $lxc -d sleep 2 done
Le rendre exécutable :
Code BASH :
chmod +x /etc/local.d/01-lxc.start
Vérifier que le service local démarre bien :
Code BASH :
rc-update -v | grep local local | default
On fait de même un script pour arrêter proprement les LXC démarrés avec un script terminant par .stop dans /etc/local.d, par exemple 01-lxc.stop :
Code BASH :
#! /bin/bash for lxc in $(lxc-ls --active) do lxc-stop $lxc sleep 1 done
Et on le rend exécutable :
Code BASH :
chmod +x /etc/local.d/01-lxc.stop
Instantanés de conteneurs
Prendre des instantané de conteneurs, c'est aussi possible. Néanmoins, les conteneurs doivent être arrêtés.
Pour effectuer un snapshot, on utilise la commande ... lxc-snapshot :
Code BASH :
lxc-snapshot -n $NOM
Pour voir les snapshots réalisés :
Code BASH :
lxc-snapshot -n $NOM -L
Exemple avec le conteneur, et création de snapshot et de listage des snapshots :
Code BASH :
lxc-snapshot -n debiantest lxc_container: Snapshot of directory-backed container requested. lxc_container: Making a copy-clone. If you do want snapshots, then lxc_container: please create an aufs or overlayfs clone first, snapshot that lxc_container: and keep the original container pristine. lxc-snapshot -n debiantest -L snap0 (/home/lxcsnaps/debiantest) 2014:11:07 07:45:23 snap1 (/home/lxcsnaps/debiantest) 2014:11:07 13:03:57
Pour restaurer un snapshot :
Code BASH :
lxc-snapshot -n $NOM -r $NOMDUSNAPSHOT
Pour supprimer un snapshot :
Code BASH :
lxc-snapshot -n $NOM -d $NOMDUSNAPSHOT
Supprimer un conteneur
Pour supprimer un conteneur, celui-ci doit être arrêté. Ensuite, utiliser la commande ... il y a un piège ... lxc-destroy et non pas lxc-delete !
Code BASH :
lxc-destroy -n $NOM
Sauvegarder un conteneur
Pour sauvegarder un conteneur, il est possible d'effectuer une archive tar du conteneur en question :
Code BASH :
cd /home/lxc tar cjf sauvegarde-conteneur.tar.bz2 conteneur
Et voila, LXC n'a plus de mystères ...