Installer un serveur Eclair dans un conteneur LXC
Table des matières
- 1. Créer et paramétrer un conteneur Ubuntu (presque) standard
- 1.1. Créer un conteneur Ubuntu
- 1.2. Configurer le conteneur
- 1.3. Créer des périphériques dans le conteneur
- 1.4. Installer la clef SSH publique pour se connecter en root
- 1.5. Configurer les sources APT
- 1.6. Configurer le proxy temporairement pour APT
- 1.7. Configurer le proxy pour Wget
- 1.8. Configurer apparmor pour autoriser le montage NFS dans LXC
- 1.9. Démarrer le conteneur éclair
- 2. Transformer le conteneur en serveur EOLE
- 2.1. Se connecter dans le conteneur
- 2.2. Installer la clef GPG qui signe les paquets EOLE
- 2.3. Mettre à jour les indexes de paquets
- 2.4. Installer les paquets Eclair
- 2.5. Désactiver les services rng-tools et gpm
- 2.6. Terminer l’installation
- 2.7. Vérifier qu’il ne reste plus rien à installer
- 2.8. Désactiver la détection automatique des noms de carte réseau
- 3. Préparer le serveur Scribe
- 4. Configurer le serveur Eclair
- 4.1. Connectez vous à votre serveur AmonEcole avec le transfert X11
- 4.2. Connectez vous au conteneur Eclair avec le transfert X11
- 4.3. Autoriser le TFTP sur l’interface eth0 en mode 2 cartes
- 4.4. Définissez votre mot de passe root (pour vous connecter à GenConfig)
- 4.5. Démarrer GenConfig
- 4.6. Configurez votre serveur
- 4.7. Exécuter instance
- 5. Gérer les erreurs systemd
- 6. Points non réglés
Nous allons faire cohabiter AmonEcole et Eclair en installant tout éclair dans un conteneur LXC dédié.
Cela va se faire en plusieurs étapes :
- Créer et paramétrer un conteneur Ubuntu (presque) standard
- Transformer ce conteneur en serveur EOLE
- Préparer le serveur Scribe
- Configurer votre serveur Eclair
- Gérer les erreurs systemd
Vous devez en premier lieu vous assurer d’avoir suffisamment de place
sur le volume /opt
, dans mon test il fait 12Go.
Vous pouvez procéder à un partitionnement personnalisé afin de vous
assurez d’avoir au moins 20Go pour /opt
.
1 Créer et paramétrer un conteneur Ubuntu (presque) standard
Nous allons utiliser l’outil lxc-create
livré avec la distribution.
1.1 Créer un conteneur Ubuntu
Vous pouvez adapter le miroir utilisé si besoin :
lxc-create -n eclair -t ubuntu -- -r xenial -u ubuntu -S ~root/.ssh/id_rsa.pub --packages 'wget' --mirror http://eole.ac-dijon.fr/ubuntu
1.2 Configurer le conteneur
Le fichier de configuration suivant contient des paramètres importants :
- Une variable est remplacée lors de l’exécution de la commande cat afin d’avoir le bon nom d’interface ;
- Un profile apparmor particulier permet à Eclair de fonctionner ;
- L’adresse IP de la seconde interface est codée en dur en utilisant une valeur de la liste prédéfinie.
cat > /var/lib/lxc/eclair/config <<EOF # Template used to create this container: /usr/share/lxc/templates/lxc-ubuntu # Common configuration lxc.include = /usr/share/lxc/config/ubuntu.common.conf # Enable mounting NFS lxc.aa_profile = lxc-container-default-for-eclair # Container specific configuration lxc.utsname = eclair lxc.arch = amd64 lxc.rootfs.backend = dir lxc.rootfs = /var/lib/lxc/eclair/rootfs # EOLE look for /dev/lxc to detect container mode and behave differently lxc.devttydir = LXC # Automatic start at bootup lxc.start.auto = 1 # Network configuration # eth0 on eth1 lxc.network.type = macvlan lxc.network.link = $(CreoleGet nom_zone_eth1) lxc.network.flags = up lxc.network.name = eth0 lxc.network.mtu = 1500 lxc.network.macvlan.mode = bridge # containers on br0 # Reuse LTSP server IP # http://eole.ac-dijon.fr/documentations/2.6/partielles/beta/EOLE/co/02-fichiers.html lxc.network.type=veth lxc.network.link=br0 lxc.network.flags=up lxc.network.name = containers lxc.network.mtu = 1500 lxc.network.veth.pair = eclair_0 lxc.network.ipv4 = 192.0.2.54/24 ## Extra devices # # /dev/fuse lxc.cgroup.devices.allow = c 10:229 rwm lxc.hook.autodev = /var/lib/lxc/eclair/devices.hook EOF
1.3 Créer des périphériques dans le conteneur
Nous avons besoin de fuse dans le conteneur, cela se fait par le
script référencé par la variable lxc.hook.autodev
dans la
configuration précédente :
cat > /var/lib/lxc/eclair/devices.hook <<'EOF' # On master /dev/fuse is owned by root:root with 666 perms mknod --mode=666 ${LXC_ROOTFS_MOUNT}/dev/fuse c 10 229 EOF chmod +x /var/lib/lxc/eclair/devices.hook
1.4 Installer la clef SSH publique pour se connecter en root
Actuellement il n’y a que le compte ubuntu
qui est accessible par la
clef publique du compte root
du maître :
mkdir /var/lib/lxc/eclair/rootfs/root/.ssh/ cp ~root/.ssh/id_rsa.pub /var/lib/lxc/eclair/rootfs/root/.ssh/authorized_keys chmod -R 600 /var/lib/lxc/eclair/rootfs/root/.ssh/
1.5 Configurer les sources APT
Nous utilisons les mêmes sources que sur le maître, sans Envole :
grep -iv envole /etc/apt/sources.list > /var/lib/lxc/eclair/rootfs/etc/apt/sources.list
1.6 Configurer le proxy temporairement pour APT
Il sera écrasé lors de l’instance :
echo "Acquire::http::Proxy \"http://$(CreoleGet adresse_ip_eth1_proxy_link):3128\";" > /var/lib/lxc/eclair/rootfs/etc/apt/apt.conf.d/02eoleproxy
1.7 Configurer le proxy pour Wget
Autrement nous ne pouvons pas télécharger la clef publique GPG qui signe les dépôts de paquets EOLE :
echo "http_proxy = http://$(CreoleGet adresse_ip_eth1_proxy_link):3128" > /var/lib/lxc/eclair/rootfs/root/.wgetrc
1.8 Configurer apparmor pour autoriser le montage NFS dans LXC
Le conteneur Eclair a besoin :
- de faire des chroots pour préparer l’image des clients légers ;
- de monter
/home
en NFS.
Nous reprenons donc le contenu de
/etc/apparmor.d/lxc/lxc-container-default-cgns
et y ajoutons les
règles nécessaires :
- Monter des systèmes de fichiers
/proc
,/sys
; - Monter en mode
bind
pour/dev
; - Monter des systèmes de fichiers
nfs
,nfs4
etrpc_pipefs
.
cat > /etc/apparmor.d/lxc/lxc-default-for-eclair <<EOF # Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which # will source all profiles under /etc/apparmor.d/lxc profile lxc-container-default-for-eclair flags=(attach_disconnected,mediate_deleted) { #include <abstractions/lxc/container-base> # the container may never be allowed to mount devpts. If it does, it # will remount the host's devpts. We could allow it to do it with # the newinstance option (but, right now, we don't). deny mount fstype=devpts, # Enable systemd cgroup mount in container mount fstype=cgroup -> /sys/fs/cgroup/**, # Allow chroot mount fstype=proc, mount fstype=sysfs, mount options=(bind), # allow NFS mount mount fstype=nfs, mount fstype=nfs4, mount fstype=rpc_pipefs, } EOF
Il faut recharger les règles :
service apparmor reload
1.9 Démarrer le conteneur éclair
Nous pouvons maintenant démarrer le conteneur afin de nous y connecter et de le configurer :
lxc-start -n eclair -d
2 Transformer le conteneur en serveur EOLE
Nous reprenons les éléments décrits dans la documentation :
2.1 Se connecter dans le conteneur
Nous faisons une connexion avec l’utilisateur root
sur l’IP
configurée en dur dans le ficher /var/lib/lxc/eclair/config
:
ssh 192.0.2.54
2.2 Installer la clef GPG qui signe les paquets EOLE
wget -qO- 'http://eole.ac-dijon.fr/eole/project/eole-2.6-repository.key' | sudo apt-key --keyring /etc/apt/trusted.gpg.d/eole-archive-keyring.gpg add -
2.3 Mettre à jour les indexes de paquets
apt-get update
2.4 Installer les paquets Eclair
La commande suivante va vous poser des questions et finira en erreur
car les paquets gpm
et rng-tools
ne supportent pas d’être dans un
conteneur LXC :
apt-get install -y eole-eclair-all
À la question quelle est l’URI du serveur LDAP vous pouvez saisir
ldap://192.0.2.50
afin de limiter le nombre de message d’erreur
avant instance.
Pour toutes les autres questions vous pouvez laisser les valeurs par
défaut, tout sera configuré par instance
.
2.5 Désactiver les services rng-tools et gpm
Nous allons désactiver les services problématiques et faire en sorte qu’ils ne puissent pas être réactivés.
Nous désactivons rng-tools
avec la commande :
systemctl disable rng-tools.service
qui vous renvoie :
rng-tools.service is not a native service, redirecting to systemd-sysv-install Executing /lib/systemd/systemd-sysv-install disable rng-tools insserv: warning: current start runlevel(s) (empty) of script `rng-tools' overrides LSB defaults (2 3 4 5). insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `rng-tools' overrides LSB defaults (0 1 6).
Nous empêchons sa réactivation future avec le système de masquage, la commande :
systemctl mask rng-tools.service
renvoie :
root@eclair:~# systemctl mask rng-tools.service Created symlink from /etc/systemd/system/rng-tools.service to /dev/null.
Nous procédons de même avec le service gpm
, la commande :
systemctl disable gpm.service
renvoie :
gpm.service is not a native service, redirecting to systemd-sysv-install Executing /lib/systemd/systemd-sysv-install disable gpm insserv: warning: current start runlevel(s) (empty) of script `gpm' overrides LSB defaults (2 3 4 5). insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `gpm' overrides LSB defaults (0 1 6).
et la commande :
systemctl mask gpm.service
renvoie :
root@eclair:~# systemctl mask gpm.service Created symlink from /etc/systemd/system/gpm.service to /dev/null.
2.6 Terminer l’installation
dpkg --configure -a
2.7 Vérifier qu’il ne reste plus rien à installer
apt-get install -y eole-eclair-all
2.8 Désactiver la détection automatique des noms de carte réseau
Cette partie de creole ne fonctionne pas dans un conteneur LXC et fait planter GenConfig:
cat > /usr/share/eole/creole/dicos/99-eole-in-lxc.xml <<EOF <creole> <files /> <containers /> <variables> <family name='Interface-0'> <variable name='nom_carte_eth0' redefine='True' remove_check='True' /> </family> <family name='Interface-1'> <variable name='nom_carte_eth1' redefine='True' remove_check='True' /> </family> <family name='Interface-2'> <variable name='nom_carte_eth2' redefine='True' remove_check='True' /> </family> <family name='Interface-3'> <variable name='nom_carte_eth3' redefine='True' remove_check='True' /> </family> <family name='Interface-4'> <variable name='nom_carte_eth4' redefine='True' remove_check='True' /> </family> </variables> <constraints> <auto name='auto_copy_val' target='nom_carte_eth0'> <param>eth0</param> </auto> <auto name='auto_copy_val' target='nom_carte_eth1'> <param>containers</param> </auto> <auto name='auto_copy_val' target='nom_carte_eth2'> <param>eth2</param> </auto> <auto name='auto_copy_val' target='nom_carte_eth3'> <param>eth3</param> </auto> <auto name='auto_copy_val' target='nom_carte_eth4'> <param>eth0</param> </auto> </constraints> <help /> </creole> EOF
3 Préparer le serveur Scribe
Sur le maître, suivez la partie AmonEcole de la documentation configuration Eclair avec un module AmonEcole avec les adaptations suivantes :
- L’accès NFS se fait par le pont interne aux conteneurs : Nfs →
Adresse IP autorisée à monter les export NFS ⮕
192.0.2.54
; - La valeur de Tftp → Adresse IP du serveur PXE/TFTP est l’IP
statique (en dehors de la plage DHCP configurée sur l’AmonEcole) que
vous prévoyez d’utiliser pour l’interface
eth0
de l’Eclair et non pas l’IP interne192.0.2.54
; - Le chemin de fichier de boot est spécifique sur Eclair : Tftp →
Chemin vers le fichier de boot PXE initial ⮕
/default/pxelinux.0
.
4 Configurer le serveur Eclair
À ce stade il serait bien de vérifier que le conteneur démarre automatiquement au démarrage de la machine :
- Redémarrer le serveur AmonEcole
4.1 Connectez vous à votre serveur AmonEcole avec le transfert X11
ssh -Y root@<amonecole>
4.2 Connectez vous au conteneur Eclair avec le transfert X11
ssh -Y 192.0.2.54
Après le redémarrage, la commande systemctl is-system-running
doit
renvoyer degraded
car certains services ne démarrent pas
correctement, nous allons les gérer après la configuration du
serveur Eclair.
4.3 Autoriser le TFTP sur l’interface eth0 en mode 2 cartes
C’est une relique de l’Eclair 2.3 qui se comportait différemment en mode 1 carte ou 2 cartes.
Nous avons deux cartes mais c’est bien par eth0
que les paquets TFTP
arrivent, nous devons donc autoriser ces flux :
cat > /usr/share/eole/creole/dicos/99-eclair-in-lxc.xml <<EOF <creole> <files /> <containers> <container name='dhcp'> <!-- 20_dhcp.xml support only one card at a time. We need to autorise TFTP on eth0 with this 2 cards setup --> <service_restriction service='tftpd'> <ip interface='eth0' netmask='0.0.0.0'>0.0.0.0</ip> </service_restriction> </container> </containers> <variables /> <constraints /> <help /> </creole> EOF
4.4 Définissez votre mot de passe root (pour vous connecter à GenConfig)
Attention à la politique de mot de passe lorsque vous utilisez la commande suivante :
passwd
4.5 Démarrer GenConfig
Démarrer GenConfig et connecter vous avec le compte root
et le mot
de passe que vous avez défini :
gen_config
4.6 Configurez votre serveur
Dans le cas spécifique d’Eclair dans un conteneur LXC, vous devez absolument :
- Passer en mode expert et activer deux interfaces : Général → Nombre d'interfaces à activer ⮕ 2
- Configurer la seconde interface avec les paramètres suivants (le
message d’avertissement est tout à fait normal) :
- Interface-1 → Adresse IP de la carte ⮕ 192.0.2.54
- Interface-1 → Masque de sous réseau de la carte ⮕ 255.255.255.0
- Autoriser les connexions SSH depuis le maître sur l’/Interface-1/ :
- Interface-1 → Autoriser les connexions SSH ⮕ oui
- Interface-1 → Adresse IP réseau autorisée pour les connexions SSH ⮕ 192.0.2.1
- Interface-1 → Masque du sous réseau pour les connexions SSH ⮕ 255.255.255.255
- Utiliser les adresses internes pour certains services :
- Annuaire → Adresse IP ou nom DNS du serveur LDAP ⮕ 192.0.2.50
- Ltsp → Adresse IP ou nom DNS du serveur NFS ⮕ 192.0.2.1
Certains flux ne peuvent pas passer par l’interface eth0 du serveur Eclair, les paramètres ci-dessus permettent de passer par le pont interne aux conteneurs..
Le reste de la configuration ne fait l’objet d’aucune particularité :
- L'Interface-0 étant celle qui sert vos clients légers et qui accédera au NFS de l’AmonEcole ;
- Tous les flux passant par AmonEcole, vous devez donc configurer le DNS et le proxy en conséquence.
Pour les clients légers lourds, n’oubliez pas de configurer le type de client léger :
- En mode normal, Ltsp → Type de l'image à générer sur le serveur ⮕ fat
4.7 Exécuter instance
Vous avez un certain nombre de messages d’erreur notamment pour les modules noyaux mais vous devriez arriver au bout.
Le dernier message list index out of range
est aussi dû à la gestion
des noyaux, en mode debug
le traceback est le suivant :
list index out of range Traceback (most recent call last): File "/usr/lib/python2.7/dist-packages/creole/reconfigure.py", line 984, in main reboot_server() File "/usr/lib/python2.7/dist-packages/creole/reconfigure.py", line 864, in reboot_server if fonctionseole.controle_kernel(): File "/usr/lib/python2.7/dist-packages/creole/fonctionseole.py", line 113, in controle_kernel wanted_kernel = get_wanted_kernel() File "/usr/lib/python2.7/dist-packages/creole/fonctionseole.py", line 67, in get_wanted_kernel last_ver = kernel_images[-1].split('-') IndexError: list index out of range
5 Gérer les erreurs systemd
Dans le conteneur Eclair, la commande systemctl is-system-running
doit renvoyer degraded
.
Vous pouvez afficher la liste des services en erreur, la commande :
systemctl list-units --failed
renvoie :
UNIT LOAD ACTIVE SUB DESCRIPTION ● networking.service loaded failed failed Raise network interfaces ● rc-local.service loaded failed failed /etc/rc.local Compatibility LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 2 loaded units listed. Pass --all to see loaded but inactive units, too. To show all installed unit files use 'systemctl list-unit-files'.
5.1 Désactiver le service rc-local.service
Ce service tente de régler les paramètres des témoins lumineux du clavier, la commande :
systemctl status rc-local.service
renvoie :
● rc-local.service - /etc/rc.local Compatibility Loaded: loaded (/lib/systemd/system/rc-local.service; static; vendor preset: enabled) Drop-In: /lib/systemd/system/rc-local.service.d └─debian.conf Active: failed (Result: exit-code) since mer. 2017-07-19 10:13:22 CEST; 12min ago Process: 256 ExecStart=/etc/rc.local start (code=exited, status=1/FAILURE) juil. 19 10:13:22 eclair systemd[1]: Starting /etc/rc.local Compatibility... juil. 19 10:13:22 eclair rc.local[256]: KDGKBLED: Ioctl() inapproprié pour un périphérique juil. 19 10:13:22 eclair rc.local[256]: Erreur de lecture des paramètres courants de fanions. Peut-être n'êtes vous pas sur la console ? juil. 19 10:13:22 eclair systemd[1]: rc-local.service: Control process exited, code=exited status=1 juil. 19 10:13:22 eclair systemd[1]: Failed to start /etc/rc.local Compatibility. juil. 19 10:13:22 eclair systemd[1]: rc-local.service: Unit entered failed state. juil. 19 10:13:22 eclair systemd[1]: rc-local.service: Failed with result 'exit-code'.
Nous pouvons simplement le désactiver et masquer pour qu’il ne démarre plus :
systemctl stop rc-local.service systemctl disable rc-local.service systemctl mask rc-local.service
5.2 Gestion des interfaces réseaux
Vous pouvez avoir plus d’informations sur le problème du service
networking.service
, la commande :
systemctl status networking.service
renvoie :
● networking.service - Raise network interfaces Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled) Drop-In: /run/systemd/generator/networking.service.d └─50-insserv.conf-$network.conf Active: failed (Result: exit-code) since mer. 2017-07-19 10:13:22 CEST; 1min 4s ago Docs: man:interfaces(5) Process: 56 ExecStart=/sbin/ifup -a --read-environment (code=exited, status=1/FAILURE) Process: 51 ExecStartPre=/bin/sh -c [ "$CONFIGURE_INTERFACES" != "no" ] && [ -n "$(ifquery --read-environment --list --exclude=lo)" ] && udevadm settle (code=exited, status=0/SUCCESS) Main PID: 56 (code=exited, status=1/FAILURE) juil. 19 10:13:21 eclair systemd[1]: Starting Raise network interfaces... juil. 19 10:13:22 eclair ifup[56]: RTNETLINK answers: File exists juil. 19 10:13:22 eclair ifup[56]: Failed to bring up containers. juil. 19 10:13:22 eclair systemd[1]: networking.service: Main process exited, code=exited, status=1/FAILURE juil. 19 10:13:22 eclair systemd[1]: Failed to start Raise network interfaces. juil. 19 10:13:22 eclair systemd[1]: networking.service: Unit entered failed state. juil. 19 10:13:22 eclair systemd[1]: networking.service: Failed with result 'exit-code'.
La ligne ifup[56]: RTNETLINK answers: File exists
signifie que
l’adresse IP existe déjà, car nous l’avons configurée en dur dans
/var/lib/lxc/eclair/config
pour la mise en route.
Il nous suffit de supprimer la ligne de configuration du conteneur et de le redémarrer.
Sur le maître AmonEcole, exécuter la commande suivante :
sed -i -e '/lxc.network.ipv4/d' /var/lib/lxc/eclair/config
et redémarrer le conteneur Eclair avec la commande :
lxc-stop -n eclair && lxc-start -n eclair
5.3 Vérifier l’état des services systemd
Vous devez maintenant avoir le retour running
de la commande systemctl is-system-running
.
6 Points non réglés
- La commande
reconfigure
affiche des messages d’erreur :- pour tout ce qui à trait à la gestion du matériel ;
- pour tout ce qui a trait à la gestion des noyaux ;
- La commande
diagnose
affiche des messages d’erreur :- pour l’accès à la passerelle : bien que les mises à jour fonctionnent
- pour l’accès aux DNS : bien que la commande
dig www.fdn.fr
fonctionne