Installer et utiliser LXC sur Gentoo / Calculate Linux




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


Il est possible de changer le chemin par défaut des conteneurs. Editer le fichier /etc/lxc/lxc.conf et y ajouter la ligne lxc.lxcpath, comme par exemple :
Code BASH :
lxc.lxcpath = /home/lxc



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


Par défaut, sur le conteneur de type gentoo, certains points de montage sont actifs. Les commenter (portage, calculate et eix).


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


Par défaut, l'option -d est active. Elle permet de lancer le conteneur en mode démon (ne pas l'attacher à la console en cours.
Si on souhaite attacher la console dès le démarrage du conteneur, utiliser l'option -F la console sera alors "capturée". Par contre, seul l'extinction du conteneur permettra de retrouver la main.



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


Par défaut, ceci fonctionne si le chemin par défaut des conteneurs est conservé dans /etc/lxc.
Si le chemin a été changé ,éditer le fichier/etc/init.d/lxc et replacer dans la fonction lxc_get_configfile le chemin des conteneurs. Un BOGUE est signalé chez gentoo



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.

Les snapshots sont des copies complètes du conteneur; et ce à chaque snapshot. Il faut donc prévoir de la place et du temps en fonction du volume de celui-ci.

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


Cette action est irréversible et ne demande pas de conformation !
Elle n'efface pas non plus les snapshots précédemment effectués.



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 ... :winner:
Cette page a été vue 11263 fois