Conversion LXC vers LXD

J'utilisais déjà les containers LXC depuis pas mal de temps, ce qui me semblait une solution intéressante pour une virtualisation légère, par rapport à du KVM et bien avant Docker (et tout le foin qu'on fait autour de ça).

J'ai donc une dizaine de containers LXC, que j'utilisais sur un disque externe, sous Ubuntu 14.04 LTS.

Depuis cette année, j'ai fait l'upgrade en Ubuntu 16.06 LTS, qui embarque maintenant LXD, le successeur de LXC. Malheureusement, la nouvelle version n'est pas strictement compatible avec l'ancienne, et il faut passer par une phase de migration.

Parmi les nouveautés de LXD, les containers peuvent maintenant être lancés en mode utilisateur (alors qu'auparavant cela se faisait généralement sous root).

Heureusement, il existe un script python, disponible sur le GitHub du projet, permettant de migrer.

Cependant, venant d'un upgrade 14.04 / 16.04, j'ai du quelque peu adapter les fichiers de configuration et l'installation.

Installation et activation LXD

Avant de pouvoir utiliser le script, il faut installer lxd et le client (lxc) :

$ sudo apt install lxd lxd-client

Puis lancer l'init

$ sudo lxd init

Transfert manuel

Comme dit plus haut, il n'est pas possible de récupérer directement un container LXC. Par contre, on peut procéder en 2 étapes :

  • Créer un nouveau container LXD
  • Remplacer l'arborescence rootfs du nouveau container LXDpar l'arborescence de l'ancien container LXC.

Par exemple, si je veux convertir un container wordpress, qui était stocké dans /var/lib/lxc/wordpress, les actions à faire sont :

lxc launch 3e4d9bea32dc wordpress # création du nouveau container LXD
lxc stop wordpress # arrêt du container
cd /var/lib/lxd/containers
rm -rf wordpress/rootfs # on supprimer la nouvelle arborescence
cp -R /var/lib/lxc/wordpress/rootfs wordpress/. # copie de l'ancien file system

lxc config set wordpress security.privileged true # si l'ancien container était lancé en root

lxc start wordpress

Dans l'exemple, j'utilise une image LXC déjà présente sur disque.

Adaptation de l'installation pour le script

Une fois le script récupéré sur GitHub, on peut tenter de le lancer, mais on se heurte vite à des soucis de librairie non connue (pylxd).

La solution est d'installer via pip. Souci : c'est le python 2.7 qui est utilisé, alors que le script demande python 3. Il faut donc tout d'abord installer pip3, puis relancer l'installation de pylxd:

$ sudo apt install python3-pip
$ pip3 install --upgrade pip
$ sudo pip3 install pylxd
$ ls /usr/local/lib/python3.5/dist-packages
cffi                                           pbr-1.10.0.dist-info      python_dateutil-2.5.3.dist-info
cffi-1.8.3.dist-info                           pip                       requests_unixsocket
_cffi_backend.cpython-35m-x86_64-linux-gnu.so  pip-8.1.2.dist-info       requests_unixsocket-0.1.5.dist-info
cryptography                                   pycparser                 ws4py
cryptography-1.5.2.dist-info                   pycparser-2.17.dist-info  ws4py-0.3.4.dist-info
dateutil                                       pylxd
pbr                                            pylxd-2.1.2.dist-info

A ce stade, on a tous les éléments pour lancer la migration.

Note : j'ai eu des soucis lors de l'installation de pylxd, avec la cryptographie.

build/temp.linux-x86_64-3.5/_openssl.c:434:30: fatal error: openssl/opensslv.h: Aucun fichier ou dossier de ce type
  compilation terminated.
  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
Failed building wheel for cryptography

en fait il manquait la libss-dev, ce qui a été résolu par :

$ sudo apt install libssl-dev

Modification des fichiers de configuration LXC

Une fois qu'on a réussi à installer les libs, j'ai remarqué que quelques paramètres des fichiers de configuration LXC posaient problème.

Pour chaque container à migrer, je mets en commentaires certains éléments :

Il s'agit notamment des paramètres :

  • lxc.mount.entry pour les éléments ne concernant pas directement des fichiers ou répertoires (en clair, proc et sysfs)
  • lxc.seccomp
  • lxc.cap.drop

Par exemple :

#lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
#lxc.mount.entry = sysfs sys sysfs defaults 0 0
#lxc.seccomp = /usr/share/lxc/config/common.seccomp
#lxc.cap.drop = sys_module
#lxc.cap.drop = mac_admin
#lxc.cap.drop = mac_override
#lxc.cap.drop = sys_time

Une fois ces éléments mis en commentaires, on peut lancer la migration :

$ sudo /home/vliefooghe/bin/lxc-to-lxd openldap
==> Processing container: openldap
Parsing LXC configuration
Checking for existing containers
Validating container name
Validating container mode
Validating container rootfs
Processing network configuration
Processing environment configuration
Processing container boot configuration
Processing container apparmor configuration
Processing container seccomp configuration
Processing container SELinux configuration
Processing container capabilities configuration
Converting container architecture configuration
Creating the container
Container is ready to use

La commande lxc list permet de lister les containers LXD existants :

 $ lxc list
+----------+---------+------------------+------+------------+-----------+
|   NAME   |  STATE  |       IPV4       | IPV6 |    TYPE    | SNAPSHOTS |
+----------+---------+------------------+------+------------+-----------+
| mysql    | RUNNING | 10.0.8.41 (eth0) |      | PERSISTENT | 0         |
+----------+---------+------------------+------+------------+-----------+
| opendj   | STOPPED |                  |      | PERSISTENT | 0         |
+----------+---------+------------------+------+------------+-----------+
| openidm1 | STOPPED |                  |      | PERSISTENT | 0         |
+----------+---------+------------------+------+------------+-----------+
| openldap | STOPPED |                  |      | PERSISTENT | 0         |
+----------+---------+------------------+------+------------+-----------+
| tomcat   | STOPPED |                  |      | PERSISTENT | 0         |
+----------+---------+------------------+------+------------+-----------+

On peut se connecter à la VM via la commande

$ lxc exec mysql -- /bin/bash

Le démarrage et l'arrêt se font via les commande lxc start / stop :

$ lxc start mysql

$ lxc stop mysql

Accès réseau

Les containers LXD utilisent un nouveau device réseau : lxdbr0, à la différence des containers LXC qui utilisaient lxcbr0.

Il faut donc également modifier la configuration des nouveaux containers, via la commande lxc config, et changer lxcbr0 en lxdbr0 :

$ lxc config edit CONTAINER

  convert_net0:
    hwaddr: 00:16:3e:16:31:7e
    nictype: bridged
    parent: lxdbr0
    type: nic

Répertoire partagé

A la mode LXC

Avec mes containers LXC, j'utilisais un répertoire partagé entre le host et les containers. Ceci était défini dans le fichier config du container :

lxc.mount = /var/lib/lxc/nginx/fstab

Le fichier fstab contenait :

# Shared folder
/data/Xchange xchange none bind

Dans l'exemple, je montaint le répertoire /data/Xchange sur le host dans le répertoire /xchange du container.

A la mode LXD

Avec LXD, la syntaxe a changé. Il faut passer par la commande lxc config qui permet maintenant de gérer la configuration des containers

$ lxc config device add nginx sdb disk source=/data/www path=/opt/www

La commande va ajouter un device (add device) à mon container nginx, de type disk, avec la source /data/www sur la machine host, et le path /opt/www dans le container. Après avoir lancé la commande, on peut vérifier :

$ lxc exec nginx "df"
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/sdb1       38314312  15403884  20941072  43% /
none                 492         0       492   0% /dev
udev             4003468         0   4003468   0% /dev/fuse
udev             4003468         0   4003468   0% /dev/net/tun
/dev/sdb1       38314312  15403884  20941072  43% /dev/lxd
/dev/sda1      330148460 292982708  20372152  94% /xchange
/dev/sdb1       38314312  15403884  20941072  43% /dev/.lxd-mounts
tmpfs             804824        36    804788   1% /run
tmpfs               5120         0      5120   0% /run/lock
tmpfs            3171840         0   3171840   0% /run/shm
/dev/sda1      330148460 292982708  20372152  94% /opt/www

On a bien un nouveau point de montage dans le container.

Visualisation de la configuration du container

LXD introduit une nouvelle option pour gérer la configuration : lxc config.

Pour afficher la configuration, on utilise lxc config show CONTAINER. Par exemple :

lxc config show drupal8
name: drupal8
profiles:
- default
config:
  security.privileged: "true"
  volatile.convert_net0.name: eth0
  volatile.last_state.idmap: '[]'
devices:
  convert_mount0:
    path: /xchange
    source: /data/Xchange
    type: disk
  convert_mount1:
    optional: "true"
    path: /sys/fs/fuse/connections
    source: /sys/fs/fuse/connections
    type: disk
  convert_net0:
    hwaddr: 00:16:3e:8b:00:40
    nictype: bridged
    parent: lxcbr0
    type: nic
  eth0:
    type: none
  root:
    path: /
    type: disk
  sdb:
    path: /opt/www
    source: /data/www
    type: disk
ephemeral: false

Troubleshooting

Par défaut maintenant les containers tournent en mode "unprivileged". Ceci renforce la sécurité, mais peut avoir des effets de bord.

J'ai eu un souci en installant un package httpd sur une image CentOS7, avec le message d'erreur suivant :

sudo rpm -ivh httpd-2.4.6-40.el7.centos.4.x86_64.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:httpd-2.4.6-40.el7.centos.4      ################################# [100%]
error: unpacking of archive failed on file /usr/sbin/suexec: cpio: cap_set_file failed - Operation not permitted
error: httpd-2.4.6-40.el7.centos.4.x86_64: install failed

Après avoir testé différents paramétrages, le problème a été résolu en modifiant le paramétrage du container :

$ lxc stop centos7
$ lxc config set centos7 security.privileged true
$ lxc config get centos7 security.privileged
true
$ lxc start centos7

On peut alors tenter une installation :

lxc exec centos7 /bin/bash
[root@centos7 ~]#
[root@centos7 ~]#
[root@centos7 ~]# rpm -ivh httpd-2.4.6-40.el7.centos.4.x86_64.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:httpd-2.4.6-40.el7.centos.4      ################################# [100%]

 

 

 

Catégorie
Tag