Apprendre à utiliser LXC

LXC (LinuX Containers) est une technologie isolant un ou plusieurs processus sur un système. Ainsi on isole et limite les effets de bords. Par exemple, on peut limiter un process à n'utiliser qu'un certain pourcentage du processus ou de mémoire.

Ci-dessous je présente deux versions qui sont un peu différentes de part leur conception mais aussi via leurs commande.

Ressources :

Installation

Verson 1.x

apt install lxc bridge-utils debootstrap

C'est la version encore bien présente sur les système Debian. Elles à l’inconvénient de ne pas embarqué les connecteurs réseau par défaut. Ainsi sa configuration est un peu plus compliqué mais ça marche tout aussi bien.

Version 2.x

Pour cela on a besoin de renseigner les backports :

echo "deb http://ftp.debian.org/debian jessie-backports main" > /etc/apt/sources.list.d/backports.list
apt-get update && apt-get -t jessie-backports install lxc

Lors de la création des conteneurs, ils seront tous enregistré à l'emplacement /var/lib/lxc.

Joindre le conteneur au réseau

Version 1.x

On édite le fichier de configuration où l'on déclare les cartes réseaux :

nano /etc/network/interfaces

On créé notre bridge :

auto br0
iface br0 inet static
        address 192.168.1.254
        netmask 255.255.255.0
        pre-up brctl addbr br0
        post-down brctl delbr br0
        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-down echo 0 > /proc/sys/net/ipv4/ip_forward
        post-up iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
        post-down iptables -F POSTROUTING -t nat

Un fois fait, on peut lancer la commande suivante pour monter l'interface:

ifup br0

En fait, celle-ci aura pour rôle de “routeur” virtuel.

A son lancement (lors d'un ifup br0 ) :

  1. Il créer une nouvelle interface
  2. Il lui attribue une IP
  3. On indique au kernel que l'on veut faire du routage
  4. On applique un réseau NAT pour que le conteneur se comporte comme un serveur dans un réseau privé.

A son arrêt (lors d'un ifdown br0 ) :

  1. Il supprime l'interface
  2. Il enlève le routage
  3. Il supprime la règle NAT

Pour savoir quel interface sélectionner, il faut appliquer cette règle sur l'interface par défaut. Ici j'ai pris l'exemple de eth0.

Concernant le conteneur, on ajoutera ces directives dans le fichier suivants :

nano /var/lib/lxc/container/config
lxc.network.type = veth
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.110/24
lxc.network.ipv4.gateway = 192.168.1.254
lxc.network.name = eth0
lxc.network.flags = up

Au démarrage du container, il aura l'IP ci-dessus et depuis la machine hôte, on verra une nouvelle interface de type veth.

Version 2.x et plus

Si ce n'est pas déjà fait, vérifier que le paquet “dnsmasq-base” soit bien installé car LXC aura seulement besoin du binaire et si le service dnsmasq est installé alors le mettre à l'arrêt.

apt install dnsmasq-base
systemctl stop dnsmasq
systemctl disable dnsmasq

Définir une interface par défaut

Adapter et Ajouter ces directives dans le fichier /etc/lxc/default.conf

lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx

Editer la configuration réseau

Notons que c'est le service lxc-net qui s'en occupe:

systemctl restart lxc-net

Certaines valeur doivent être renseigné dans le fichier /etc/default/lxc-net

  • Activer le mode bridge pour que le routage soit effectif:
USE_LXC_BRIDGE="true"
  • Indiquer le fichier de conf si l'on veut du DHCP:
LXC_DHCP_CONFILE=/etc/lxc/dhcp.conf
  • Renseigner le domaine de gestion:
LXC_DOMAIN="labasemarseille.org"
  • Définir une plage d'adresse DHCP:
LXC_ADDR="10.0.42.42"
LXC_NETWORK="10.0.42.0/24"
LXC_DHCP_RANGE="10.0.42.100,10.0.42.200"
  • Définir des adresses IP statiques:

Notons que la plage par défaut de LXC est 10.0.3.0/24. Editer le fichier en y ajoutant /etc/lxc/dhcp.conf

dhcp-host=$NOM-DU-CONTENEUR1,10.0.3.x
dhcp-host=$NOM-DU-CONTENEUR2,10.0.3.x

Commandes disponible

  • Voir la configuration utilisé par LXC :
lxc-checkconfig
  • Créer un conteneur Debian :
lxc-create -n mon-conteneur -t debian
  • Démarrer un conteneur et le placer en arrière plan :
lxc-start -n mon-conteneur -d
  • Se connecter au container :
lxc-attach -n mon-container
  • Démarrer un conteneur au boot de l'OS :
lxc config set mon-container boot.autostart true

Pour LXC 2 et + , il y a besoin de mettre la directive dans la config du conteneur:

lxc.start.auto = 1
  • Arréter un conteneur :
lxc-stop -n mon-container
  • Se connecter à la console du conteneur :
lxc-console -n mon-conteneur
  • Pour se détacher de la console :
Taper sur <Ctrl>+<a> puis indépendamment la touche <q>
  • Copier un conteneur :
lxc-copy -n $mon-container -N $mon-nouveau-container

Configuration disponible

Dans le fichier suivant on peut ajouter ces directives :

nano /var/lib/lxc/$CONTAINER/config
  • Limiter la taille mémoire :
lxc.cgroup.memory.limit_in_bytes = 100M
  • Déployer un conteneur opensuse, ubuntu ou une version précise de Debian:
lxc-create -n monContainer -t opensuse
lxc-create -n monContainer -t ubuntu
lxc-create -n monContainer -t debian -- -r bullseye --arch amd64

Ces version sont présenté sous forme de template qui se situent dans ce dossier : /usr/share/lxc/templates/

  • Version 3.1

Cliquez pour afficher ⇲

Cliquez pour masquer ⇱

# Template used to create this container: /usr/share/lxc/templates/lxc-debian
# Parameters passed to the template: -r buster
# Template script checksum (SHA-1): d5aa397522e36a17c64c014dd63c70d8607c9873
# For additional config options, please look at lxc.container.conf(5)

# Uncomment the following line to support nesting containers:
#lxc.include = /usr/share/lxc/config/nesting.conf
# (Be aware this has security implications)

#
# Manual page lxc.container.conf(5)
# et
# https://help.ubuntu.com/lts/serverguide/lxc.html
#
################################################################################
lxc.net.0.type = veth
lxc.net.0.hwaddr = 00:16:3e:f2:37:70
lxc.net.0.link = brExt
lxc.net.0.name = ethExt
lxc.net.0.flags = up
lxc.net.0.ipv4.address = 10.0.52.2/16
lxc.net.0.ipv4.gateway = 10.0.0.1
# Set none to disable private network
#lxc.net.1.type = none
lxc.net.1.type = veth
lxc.net.1.link = brInt
lxc.net.1.name = ethInt
lxc.net.1.flags = up
lxc.net.1.ipv4.address = 192.168.52.2/16
################################################################################
# lxc.mount.entry = /lib /root/myrootfs/lib none ro,bind 0 0
lxc.mount.entry = /srv/lxc/mobilizon-dev srv/lxc none rw,bind,create=dir 0 0
################################################################################
# Default memory
# 256M
lxc.cgroup.memory.limit_in_bytes = 512M
################################################################################
# UID/GID MAPPING
# This configuration will map both user and group ids in the range 0-9999 in the container to the
# ids 100000-109999 on the host.
#lxc.idmap = u 0 100000 10000
#lxc.idmap = g 0 100000 10000
################################################################################
lxc.start.auto = 1
lxc.start.order = 10
# lxc.start.delay = 5
################################################################################
# Voir Doc Debian
# /usr/share/doc/lxc/README.Debian
lxc.apparmor.profile = lxc-container-default-cgns
lxc.apparmor.profile = unconfined
################################################################################
lxc.rootfs.path = zfs:datapool/lxc/mobilizon-dev

# Common configuration
lxc.include = /usr/share/lxc/config/debian.common.conf

# Container specific configuration
lxc.tty.max = 4

Bugs

Il se peut que l'on rencontre quelques bugs pas compréhensible mais voici quelque solutions.

  • mktemp: impossible de créer le fichier à partir du modèle « /tmp/user/0/tmp.XXXXXXXXXX

A faire dans le container :

mkdir -p /tmp/user/0/ && chmod 711 /tmp/user/ && chmod 700 /tmp/user/0/