Installer un serveur Eclair dans un conteneur LXC

Table des matières

Nous allons faire cohabiter AmonEcole et Eclair en installant tout éclair dans un conteneur LXC dédié.

Cela va se faire en plusieurs étapes :

  1. Créer et paramétrer un conteneur Ubuntu (presque) standard
  2. Transformer ce conteneur en serveur EOLE
  3. Préparer le serveur Scribe
  4. Configurer votre serveur Eclair
  5. 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 et rpc_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 NFS192.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 interne 192.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 à activer2
  • Configurer la seconde interface avec les paramètres suivants (le message d’avertissement est tout à fait normal) :
    • Interface-1 → Adresse IP de la carte192.0.2.54
    • Interface-1 → Masque de sous réseau de la carte255.255.255.0
  • Autoriser les connexions SSH depuis le maître sur l’/Interface-1/ :
    • Interface-1 → Autoriser les connexions SSHoui
    • Interface-1 → Adresse IP réseau autorisée pour les connexions SSH192.0.2.1
    • Interface-1 → Masque du sous réseau pour les connexions SSH255.255.255.255
  • Utiliser les adresses internes pour certains services :
    • Annuaire → Adresse IP ou nom DNS du serveur LDAP192.0.2.50
    • Ltsp → Adresse IP ou nom DNS du serveur NFS192.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 serveurfat

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

Auteur: Daniel Dehennin

Created: 2017-08-23 mer. 09:00

Emacs 25.2.2 (Org mode 8.2.10)

Validate