virli/tutorial/lxc/lxc.md

7.6 KiB

\newpage

Utiliser lxc

Le but de cette première partie est d'appréhender la virtualisation légère au travers d'un programme, lxc, qui va mettre en place pour nous tout un environnement distinct.

Lancer un conteneur

Avec le paquet lxc que nous avons précédemment installé, nous avons également récupéré un certain nombre de modèles de système (souvent installés dans le dossier /usr/share/lxc/templates/) : il s'agit d'une suite de commandes (principalement des wget, chroot ou debootstrap) permettant d'obtenir un système basic fonctionnel, en suivant les étapes d'installation habituelle de la distribution.

La méthode la plus simple pour lancer un conteneur lxc est d'utiliser l'un de ces modèles pour obtenir un nouveau système. On utilise pour cela la commande lxc-create :

```bash lxc-create --name toto_first --template debian ```

Ce modèle va créer un dossier dans /var/lib/lxc/ (pouvant varier d'une distribution à l'autre) portant le nom que nous avons précisé. Ce dossier va contenir la configuration lxc du conteneur (config), la table des partitions (fstab) s'il y a besoin de faire des montages particuliers et enfin le dossier rootfs contenant le système en lui-même.

Une fois l'installation terminée, on peut démarrer le conteneur :

```bash lxc-start --name toto_first ```

lxc va appeler /sbin/init et démarrer tous les services que l'on peut s'attendre à trouver dans n'importe quelle machine virtuelle (et même physique) plus classique (la seule différence réside donc dans le fait que le noyau est partagé avec l'hôte).

Généralement on lance lxc-start avec l'option --daemon, car on n'a pas vraiment envie d'avoir un conteneur bloquant un terminal. En mode daemon, on va utiliser la commande lxc-console pour nous attacher aux conteneurs. À tout moment, nous pouvons nous détacher de la console (sans que cela n'affecte l'état du conteneur) en pressant les touches : ^A q.

Connectons-nous, lançons quelques commandes puis éteignons la machine en lançant la commande poweroff dans le conteneur. Il est également possible de lancer la commande lxc-stop --name toto_first dans un autre terminal, depuis la machine hôte.

Le réseau

Le modèle Debian, que nous avons utilisé, préremplit un fichier de configuration sans définir de paramètre pour le réseau. Il n'y a donc pas d'interface dans le conteneur pour le connecter :

```lxc lxc.network.type = empty ```

Un excellent article détaillant les différents types de configuration réseau est accessible à https://blog.flameeyes.eu/2010/09/linux-containers-and-networking.

N'ayant qu'une seule interface physique sur la machine et n'ayant pas accès à la configuration des VLAN de la pièce, il ne nous reste que deux méthodes pour obtenir du réseau dans nos conteneurs : Virtual Ethernet ou MACVLAN.

MACVLAN

Cette méthode est la plus simple : le noyau va orienter les paquets en fonction de leur adresse MAC de destination. Le conteneur sera donc comme une machine supplémentaire sur le réseau.

Modifions notre fichier de configuration afin qu'il ressemble à quelque chose comme :

```lxc lxc.network.type = macvlan lxc.network.macvlan.mode = bridge lxc.network.flags = up lxc.network.link = eth0 ```

Après avoir démarré le conteneur, il devrait avoir obtenu une IP du serveur DHCP de l'école. L'inconvénient dans cette configuration est qu'il faille un client netsoul dans chaque conteneur, puisque chacun est considéré comme une machine différente aux yeux du routeur.

Virtual Ethernet

Virtual Ethernet est la configuration la moins optimale, mais sans doute la plus flexible.

Voici un extrait de configuration correspondant au paramétrage d'une interface virtuelle pour un conteneur donné :

```lxc lxc.network.type = veth lxc.network.ipv4 = 172.23.42.2/24 lxc.network.flags = up ```

Dans cette situation, au démarrage du conteneur, lxc va créer une interface veth, avec un côté placé dans la machine hôte et l'autre côté placé dans le conteneur. lxc configure l'interface dans le conteneur, il nous appartient ensuite de configurer la machine hôte.

Commençons par attribuer une IP à cette nouvelle interface, en adaptant à votre identifiant d'interface :

```bash ip addr add 172.23.42.1/24 dev vethYJWD6R ```

À partir de là, nous devrions pouvoir pinger notre conteneur depuis notre machine hôte : ping 172.23.42.2.

Notre conteneur ne peut cependant pas encore accéder à Internet. Pour cela, la machine hôte doit faire office de routeur et donc router les paquets d'un réseau à l'autre : en l'occurence, du réseau 172.23.42.1 vers Internet via 10.0.0.0/8, le réseau de l'école.

Pour que notre machine hôte route les paquets, exécuter la commande :

```bash sysctl -w net.ipv4.ip_forward=1 ```

Cette variable, que nous retrouvons dans /proc/sys/net/ipv4/ip_forward, indique au noyau qu'il peut faire passer les paquets réseau d'une interface à l'autre. Sans plus de directives, les paquets vont conserver leur adresse source (172.23.42.2 pour les paquets en provenance du conteneur). Cette adresse est une adresse privée, non routable sur Internet, ni même par le bocal. Il faut donc ajouter une couche de NAT/PAT pour réécrire les adresses sources avant d'envoyer les paquets sur internet :

```bash iptables -t nat -A POSTROUTING ! -o vethYJWD6R -s 172.23.42.0/24 -j MASQUERADE ```

Dernière étape, dans notre conteneur, nous devons indiquer la route à utiliser pour accéder à internet :

```bash ip route add default via 172.23.42.1 ```

Nous avons maintenant internet dans notre conteneur !

Utilisation du conteneur

Installation de InfluxDB

```bash apt-get update apt-get install wget wget https://s3.amazonaws.com/influxdb/influxdb_0.9.4.2_amd64.deb dpkg -i influxdb_0.9.4.2_amd64.deb ```

Test de l'installation

``` /opt/influxdb/influxd ```

Une fois que le service est démarré, vous devriez pouvoir accéder à l'interface à : http://172.23.42.2:8083/

Créons une nouvelle base de données "metrics", elle nous servira dans la partie suivante.

Rendu

Configuration du conteneur

En plus des modifications que vous avez effectuées durant le TP, modifiez la configuration du conteneur afin qu'il ne puisse pas utiliser plus que 256 MB de RAM et 512 MB de swap.

Limitez ensuite les capabilities(7) de ce conteneur afin qu'il s'exécute avec le strict minimum de droits, nécessaires au bon fonctionnement des programmes installés.

Rendez le fichier config de ce premier conteneur. N'hésitez pas à laisser des commentaires justifiant vos éventuels choix.

Questions

  1. Quels sont les autres types de virtualisation réseau existants ? Expliquez leurs particularités en une phrase.

  2. Quel fichier de configuration devriez-vous changer pour rendre persistante la valeur d'ip_forward ?

  3. Dans quel langage InfluxDB a-t-il été écrit ? Quelle est la particularité des binaires générés par ce langage ?

  4. Quels sont les avantages et les inconvénients associés au linkage statique et au linkage dynamique ? (pas forcément que dans le cadre de la virtualisation légère).

  5. J'ai utilisé la méthode Virtual Ethernet pour relier mes conteneurs à Internet, via l'interface br0. Quelle(s) règle(s) iptables devrais-je écrire sur mon hôte afin de permettre l'accès à InfluxDB depuis une autre machine ?