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 CSS (CalculateLinux Server Scratch), avec le noyau 3.14.22.
LXC a besoin des fonctionnalités CGROUP du noyau linux.
Ces valeurs de configuration doivent être positionnées à y :
On peut trouver ces valeurs via la commande suivante :
Si tout n'est pas sur "y" :
Désactiver le FLAG minimal :
Puis réémerger le noyau :
Se rendre dans les sources :
Nettoyer les compilations précédentes :
Copier la configuration actuelle dans .config :
On met à jour la config du kernel:
Vérifier que les valeurs suivantes sont à y :
Voici une commande sympathique pour vérifier tout d'un coup :
Puis éditer avec l'éditeur de son choix le fichier .config pour placer chaque valeur à y.
J'ai opté personnellement pour sed :
On peut configurer d'autres options avec :
Puis on recompile le noyau :
On met à jour le fichier initramfs ainsi :
Exemple:
On n'oublie pas de mettre à jour GRUB2 :
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 enp0s3), 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.
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.
lxc est archtildé sur Calculate Linux, donc on l'ajoute au fichier packages.keywords :
Puis 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 :
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 :
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
- Prérequis pour l'installation
- Installation de LXC
- 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.
Prérequis pour l'installation
Tout le long de l'article, j'ai utilisé une CSS (CalculateLinux Server Scratch), avec le noyau 3.14.22.
Partie kernel
LXC a besoin des fonctionnalités CGROUP du noyau linux.
Ces valeurs de configuration doivent être positionnées à y :
Code BASH :
CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_CGROUPS=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y CONFIG_CGROUP_FREEZER=y CONFIG_VETH=y CONFIG_MACVLAN=y CONFIG_MACVTAP=y CONFIG_BRIDGE=y
On peut trouver ces valeurs via la commande suivante :
Code BASH :
zcat /proc/config.gz
Si tout n'est pas sur "y" :
Désactiver le FLAG minimal :
Code BASH :
echo "sys-kernel/calculate-sources -minimal -build" >> /etc/portage/package.use/custom
Puis réémerger le noyau :
Code BASH :
emerge -q sys-kernel/calculate-sources
Se rendre dans les sources :
Code BASH :
cd /usr/src/linux
Nettoyer les compilations précédentes :
Code BASH :
make distclean
Copier la configuration actuelle dans .config :
Code BASH :
zcat /proc/config.gz > .config
On met à jour la config du kernel:
Code BASH :
make silentoldconfig
Vérifier que les valeurs suivantes sont à y :
Voici une commande sympathique pour vérifier tout d'un coup :
Code BASH :
grep CONFIG_NAMESPACES .config ; \ grep CONFIG_UTS .config ; \ grep CONFIG_IPC .config ; \ grep CONFIG_USER_NS .config ; \ grep CONFIG_PID_NS .config ; \ grep CONFIG_NET_NS .config ; \ grep CONFIG_CGROUPS .config ; \ grep CONFIG_CGROUP_DEVICE .config ; \ grep CONFIG_CPUSETS .config ; \ grep CONFIG_DEVPTS_MULTIPLE_INSTANCES .config ; \ grep CONFIG_CGROUP_FREEZER .config ; \ grep CONFIG_VETH .config ; \ grep CONFIG_MACVLAN .config ; \ grep CONFIG_MACVTAP .config ; \ grep CONFIG_BRIDGE .config
Puis éditer avec l'éditeur de son choix le fichier .config pour placer chaque valeur à y.
J'ai opté personnellement pour sed :
Code BASH :
sed -e 's/# CONFIG_CGROUP_DEVICE is not set/CONFIG_CGROUP_DEVICE=y/g' -i .config sed -e 's/# CONFIG_CPUSETS is not set/CONFIG_CPUSETS=y/g' -i .config sed -e 's/# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set/CONFIG_DEVPTS_MULTIPLE_INSTANCES=y/g' -i .config sed -e 's/# CONFIG_CGROUP_FREEZER is not set/CONFIG_CGROUP_FREEZER=y/g' -i .config sed -e 's/# CONFIG_VETH is not set/CONFIG_VETH=y/g' -i .config sed -e 's/# CONFIG_MACVLAN is not set/CONFIG_MACVLAN=y/g' -i .config sed -e 's/# CONFIG_MACVTAP is not set/CONFIG_MACVTAP=y/g' -i .config sed -e 's/CONFIG_BRIDGE=m/CONFIG_BRIDGE=y/g' -i .config
On peut configurer d'autres options avec :
Code BASH :
make menuconfig
Puis on recompile le noyau :
Code BASH :
make make modules_install make install
On met à jour le fichier initramfs ainsi :
Code BASH :
mkinitrd /boot/initramfs-$version.img $version
Exemple:
Code BASH :
mkinitrd /boot/initramfs-3.14.33-calculate.img 3.14.33-calculate
On n'oublie pas de mettre à jour GRUB2 :
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 enp0s3), on indique à null sa configuration et on créée le pont nommé br0 :
Code BASH :
#config_enp0s3="dhcp" config_enp0s3="null" # Pont réseau config_br0="10.21.27.253/24" routes_br0="default via 10.21.27.254" dns_servers="10.21.27.250" brctl_br0="setfd 0 sethello 10 stp off" bridge_br0="enp0s3"
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.
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
lxc est archtildé sur Calculate Linux, donc on l'ajoute au fichier packages.keywords :
Code BASH :
echo "app-emulation/lxc #LXC" >> /etc/portage/package.keywords/custom
Puis 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/sqlitecachec #LXC" >> /etc/portage/package.keywords/custom echo "dev-lang/python sqlite #LXC" >> /etc/portage/package.use/custom echo "dev-libs/libxml2 python #LXC" >> /etc/portage/package.use/custom echo "app-arch/rpm lua python #LXC" >> /etc/portage/package.use/custom
On installe ensuite yum :
Code BASH :
emerge -aqv sys-apps/yum
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
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.27.201/24 lxc.network.ipv4.gateway = 10.21.27.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.27.201/24 : adresse IPv4 du conteneur
- lxc.network.ipv4.gateway = 10.21.27.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.27.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 1
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 2
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) 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 ...