lxc
Installation
Creation d’un container
apt install lxc
Verifier la config
lxc-checkconfig
Pour créer un conteneur :
lxc-create -t download -n [name]
Si vous aussi vous avez une erreur GPG
ERROR: Unable to fetch GPG key from keyserver.
Vous pouvez ignorer la valisation avec la commande (C’est pas ouf mais j’ai la flemme):
lxc-create -t download -n [name] -- --no-validate
Lister les conteneurs :
lxc-ls -f
Lancer un container :
lxc-start -n [name]
Stopper un container
lxc-stop -n [name]
Rentrer dans le container :
lxc-attach -n [name]
Configuration réseau
Pour l’instant votre conteneur n’a pas accès à internet, il faut lui attribuer une ip. Pour avoir accès à internet, les conteneurs doivent se connecter à une interface bridge sur l’hôte. Celle-ci peut avoir été créée par le paquetage (Ubuntu, paquetage lxc-net), alors on peu la créer manuellement. Pour la créer manuellement faut continuer le tuto ;)
brctl show : permet d’obtenir la liste des interfaces bridges sur l’hôte. La commande est accessible via le paquet bridge-utils
On veut obtenir ceci :
[routeur physique]
[ 192.168.0.1 ]
|
eth0
192.168.0.2
|
laptop
|
lxcbr0
10.0.30.1
/ \
containr0 containr1
10.0.30.2 10.0.30.3
Pour arriver à ce resultat il faut que ton pc reagisse comme un routeur. Pour savoir s’il est déjà, tape cette commande si ça renvoie … = 1 c’est bon
sysctl net.ipv4.ip_forward
Sinon
sysctl -w net.ipv4.ip_forward=1
et pour faire de façon permanent, modifiez le fichier /etc/sysctl.conf :
net.ipv4.ip_forward = 1
Ou lancer la commande :
sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
et lance la commande :
sysctl -p /etc/sysctl.conf
Configurer votre brige
Maintenant il faut créer l’interface bridge et on lui assigne une ip :
brctl addbr lxcbr0
ip addr add 10.0.30.1 brd + dev lxcbr0
Il faut rendre le bridge persistant au démarage. Sur debian on fait :
Pour créer une interface, il faut créer un fichier avec la configuration de l’interface dans le repertoire /etc/network/interfaces.d. Normalement le fichier /etc/network/interfaces fait le lien avec ce repertoire (include). Vérifier au cas où par exemple sur certaines version le fichier doit porter l’extension .cfg
Créer un fichier /etc/network/interfaces.d/lxcbr0 qui contient :
auto lxcbr0
iface lxcbr0 inet static
bridge_ports none
address 10.0.30.1
netmask 255.255.255.0
Si vous n’avez pas de repertoire interfaces.d, installez net-tools
apt install ifupdown net-tools
On peut ensuite contrôler l’interface avec les scripts ifup et ifdown:
ifup lxcbr0
ifdown lxcbr0
Si ya pas de fichier /etc/network/interfaces reinstall ifupdown
apt autoremove --purge ifupdown && apt install ifupdown
Pour voir l’etat du bridge, tapez la commande
brctl show
Normalement vous avez votre bridge ;)
Ubuntu
Sur ubuntu, le bridge est déjà configuré avec lxc-net. La configuration de lxc est dans /etc/default/lxc. et elle est override par /etc/default/lxc-net.
LXC_BRIDGE="lxcbr0"
LXC_ADDR="10.0.33.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.33.0/24"
#LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
#LXC_DHCP_MAX="253"
Sur le fichier de config vous pouvez changer la config réseau de lxc et activer ou pas le DHCP
systemctl restart lxc
Configurer votre container
Votre container de situe dans le dossier /var/lib/lxc/[name]
Dans ce repertoire vous trouverez le rootfs qui est le dossier de votre container, et le fichier config. Vous l’aurez compris c’est dans ce fichier que nous allons spécifier la configuration réseau de votre container.
Je vous met ici un exemple de configuration d’un de mes container, à vous de prendre ce que vous souhaitez
!!! Attention !!! quand vous modifiez votre fichier de config il est fortement recommandé de le stopper.
Il est important de changer l’adresse MAC pour chaque container sinon vous aurez des problèmes par la suite.
Parameters passed to the template: --release buster
# Template script checksum (SHA-1): b290eda01b21f9818fcf1402b2749c4c218500ed
# 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)
lxc.net.0.type = veth
lxc.net.0.hwaddr = 00:16:3e:d2:3e:5f
lxc.net.0.flags = up
lxc.net.0.name = eth1
# ip du container
lxc.net.0.ipv4.address = 10.0.30.4/24
# L'interface bridge est le link
lxc.net.0.link = lxcbr0
lxc.rootfs.path = /var/lib/lxc/nextcloud/rootfs
lxc.net.0.ipv4.gateway = 10.0.30.1
# Common configuration
lxc.include = /usr/share/lxc/config/common.conf
# Container specific configuration
lxc.tty.max = 4
lxc.uts.name = nextcloud
lxc.arch = amd64
lxc.apparmor.profile = unconfined
lxc.start.auto = 1
memory.limit_in_bytes=512M
documentation : https://linuxcontainers.org/lxc/manpages/man5/lxc.container.conf.5.html
Ancienne version
lxc.network.type = veth
lxc.network.hwaddr = 00:16:3e:d2:3e:5f
lxc.network.flags = up
lxc.network.name = eth1
# ip du container
lxc.network.ipv4.address = 10.0.30.4/24
# L'interface bridge est le link
lxc.network.link = lxcbr0
Votre configuration sera valide quand vous pourrez lancer votre container et en tappant la commande
ip a
Vous verrez aparaitre l’ip que vous lui avez renseigné. Mais à cette étape vos containers ne peuvent pas encore se connecter à “l’internet des objects”
Regle IPTABLE
Pour pourvoir se connecter à internet depuis vos containers, il faut rajouter cette rêgle iptables sur la machine hôte :
apt install iptables
iptables -t nat -A POSTROUTING -s 10.0.30.0/24 -j MASQUERADE
Pour voir la liste des rêgles iptables, tapez la commande
iptables -L -t nat
Attention, les rêgles iptables ne sont pas permanente, il faudra la remettre au à chaque redemarrage de la machine hôte. Cependant il existe un moyen de les rendre permanente :
apt install iptables-persistent
Les sauvegardes sont dans les fichiers : /etc/iptables/rules.v4, /etc/iptables/rules.v6
La commande iptables-save exporte la config iptables. Il faut juste rediriger la sortie dans les sauvegardes :
iptables-save > /etc/iptables/rules.v4
iptables-save > /etc/iptables/rules.v6
Supprimer toutes les rêgles iptables :
iptables -F POSTROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
Le dns
Sur votre containers se trouve souvent dans le fichier /etc/resolv.conf la configuration dns. Vous devez mettre la même que la machine hôte ou cas spécifique votre propre dns.
Pour ovh c’est
nameserver 127.0.0.1
nameserver 213.186.33.99
search ovh.net
Tester les erreurs
Pour voir les logs du container :
journalctl -f
Pour voir les requete sur le bridge tapez sur la machine hote
tcpdump -i lxcbr0 -v
Déplacer un container sur une autre machine
Déplacer un container c’est déplacer le rootfs vers une autre machine possédant une installation de lxc. Il faudra sur cette autre machine recréer le fichier de config.
Première méthode (envoyer une archive)
lxc-stop -n $NAME
cd /var/lib/lxc/$NAME/
tar --numeric-owner -czvf container_fs.tar.gz ./*
The --numeric-owner flag is very important! Without it, the container may not boot because the uid/gids get mangled in the extracted filesystem. When tar creates an archive, it preserves user / group ownership information. By default, when extracting, tar tries to resolve the archive user/group ownership names with the ids on the system running tar. This is intended to ensure that user ownership is resolved on the new system, in case the UID numeric values differ between systems.
This is bad for an LXC filesystem because the numeric uid/gid ownership is intended to be preserved for the whole filesystem. If it gets resolved to a different value, bad things happen.
rsync -avh container_fs.tar.gz user@newserver:/var/lib/lxc/
mkdir /var/lib/lxc/$NAME/
cd /var/lib/lxc/$NAME/
tar --numeric-owner -xzvf container_fs.tar.gz .
If you’re using an overlay backed container, you’ll also need to migrate the container this new one is based off of. Lastly, you might see a few warnings about skipped socket files:
tar: /var/lib/lxc/$NAME/rootfs/dev/log: socket ignored
I’ve ignored this error, and haven’t had any issues with any of the containers I manage. If you have further issues, add your error messages to the original post and I’ll elaborate.
Deuxième méthode (plus pratique)
rsync -arAXDx --numeric-ids --delete --progress root@arkalo.ovh:/var/lib/lxc/gitea/rootfs/ /home/omer/Documents/backup/
Normalement c’est bon mais j’ai eu un bug avec mariadb :
● mariadb.service - MariaDB 10.3.15 database server
Loaded: loaded (/etc/systemd/system/mariadb.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2019-08-13 08:55:56 UTC; 8s ago
Docs: man:mysqld(8)
https://mariadb.com/kb/en/library/systemd/
Process: 88 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=226/NAMESPACE)
Aug 13 08:55:56 gitea systemd[1]: Starting MariaDB 10.3.15 database server...
Aug 13 08:55:56 gitea systemd[88]: mariadb.service: Failed to set up mount namespacing: Permission denied
Aug 13 08:55:56 gitea systemd[88]: mariadb.service: Failed at step NAMESPACE spawning /usr/bin/install: Permission denied
Aug 13 08:55:56 gitea systemd[1]: mariadb.service: Control process exited, code=exited, status=226/NAMESPACE
Aug 13 08:55:56 gitea systemd[1]: mariadb.service: Failed with result 'exit-code'.
Aug 13 08:55:56 gitea systemd[1]: Failed to start MariaDB 10.3.15 database server.
Your workaround is working but it seems that removing only these 3 lines is sufficient:
vim /etc/systemd/system/mariadb.service
ProtectSystem=full
PrivateDevices=true
ProtectHome=true
Faire une snapshot
lxc-snapshot -n [containername] [snapshot-name]
Renommer un container
hostnamectl set-hostname [hostname]
Après avoir changer le hostname, n’oubliez pas le mettre à jour le fichier /etc/hosts au niveau du 127.0.1.1
bugs :
Failed to create bus connection: No such file or directory
:
apt install -y dbus
Could not set property: Connection timed out
:
Modifier le fichier /etc/hostname
and reboot
Configurer la date
dpkg-reconfigure tzdata
/bin/ln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime
Enlever les recommandations apt
En gros sur debian 10 apt install plein de truc en plus quand vous faites un apt install et c’est chiant.
cat > /etc/apt/apt.conf.d/01norecommend << EOF
APT::Install-Recommends "0";
APT::Install-Suggests "0";
EOF
Redirection de port
Vous l’aurez remarqué, quand on fait tourner une application sur le port 80, elle n’est pas disponible en publique (avec votre adresse publique). Vous avez 2 solutions :
- Votre application est une application web, il faut créer un reverse proxy sur la machine hôte
Voir tuto nginx
- Ouvrir le port sur la machine hôte avec iptables
Par exemple pour ssh, vous voulez vous connecter en ssh directement dans le container :
Il faut avoir au préalable
- Un utilisateur sur le container (voir plus haut)
- Installer openssh-server
- Ajouter la rêgle iptables sur la machine hote
iptables -t nat -A PREROUTING -p tcp --dport [port d'entrée] -j DNAT --to [ip container]:22
ex :
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to 10.0.30.7:22
Pour se connecter, il faut lancer :
ssh omer@[adresse publique] -p [port d'entrée]
Attention je le rappel les rêgles iptables ne sont pas permannent et je sais plus comment on fait pour les rendre permannente OK !
Gestion des utilisateurs
Cette partie est plus propre à linux qu’a lxc mais j’arrete pas d’oublier les commandes ça me casse les c******* !!! Alors je le met ici.
- Ensuite créer un utilisateur dans le container :
useradd -s /bin/bash -m [username]
- lui attribuer un password
passwd [username]
- On lui ajouter des droit sudo
usermod -aG sudo omer
Sur debian sudo n’est pas installé
apt install sudo
- Installer openssh pour l’utilisateur
su [username]
sudo apt install openssh-server
Ya un petit soucis avec les utiliateurs dans un container lxc. Quand on se connecte en lxc-attach et su [username], on ne met pas de mot de passe. Le petit soucis c’est que quand on fait sudo … on a cette erreur :
sudo: no tty present and no askpass program specified
J’ai pas trop de solution pour le moment, il faut soit se connecter en ssh direct avec l’user ou ajouter cette ligne :
visudo
[username] ALL=(ALL) NOPASSWD:ALL
Pour faire plus propre, le mieux c’est de créer un fichier /etc/sudoer.d/[username] avec cette ligne dedans et decomenter cette ligne dans le visudo :
includedir /etc/sudoers.d/
Alors très important, quand vous modifiez le fichier sudoer, faites le toujours en passant par la commande visudo. Cette commande fait une verification de votre modification avant de valider. Car en cas d’erreur de syntaxe c’est la merdouille.
Inotify
Alors une erreurs que j’ai rencontré sur linux c’est les inotify. En gros à force de créer des containers vous tomberez surement sur cette erreur : failed to create inotify: Too many op en files. Ce message signifi que la limite à été atteinte.
Le mécanisme inotify permet de mettre ce que l’on appel un watch descriptor sur un fichier, qui enverra des notifications au système lorsque des événements sur le fichier.
Pour connaitre ces limites, tapez la commande :
sysctl fs.inotify.max_user_instances
Pour modifier cette valeur de façon permaenente il faut modifier le fichier /etc/sysctl.conf
Par defaut j’était à 128.
fs.inotify.max_queued_events=1048576
fs.inotify.max_user_instances=1048576
fs.inotify.max_user_watches=1048576
sysctl --system
Superviser
Il est possible de récupérer des données sur les conteneur tel que la consommationo CPU. Ces données se situe sur la machine hote dans le repertoire /sys/fs/cgroup/cpuacct/lxc/
Exemple :
Le cpu se situe dans le fichier : /sys/fs/cgroup/cpuacct/lxc/discord/cpuacct.usage
Ram utilisé en nanoseconde depuis que le container est lancé