Déployer ses systèmes avec Kadeploy

Magazine
Marque
GNU/Linux Magazine
Numéro
179
|
Mois de parution
février 2015
|
Domaines


Résumé
Kadeploy est un logiciel libre développé à l'INRIA (Institut National de Recherche en Informatique et en Automatisme). Ce logiciel a été implémenté pour déployer des images de systèmes d'exploitation sur la plateforme d’expérimentation Grid'5000 [1]. L'approche proposée par Kadeploy repose sur les briques standards du système (PXE, SSH, IPMI etc.) ainsi que sur l'infrastructure de communication TakTuk.

Body

Lorsque l'on évoque le déploiement automatisé, de grands noms viennent immédiatement à l'esprit : Ghost (logiciel propriétaire), CloneZilla ou encore Fog (logiciels libres). Ces logiciels proposent de déployer une image référence sur X postes de travail. La création de cette image référence peut se faire de façon brute, bits à bits ou de manière plus intelligente si le logiciel comprend le système de fichiers utilisé par l'image. Ces images sont ensuite déployées sur tous les postes en unicast ou multicast via un agent en exécution sur les postes à déployer. Cet agent peut être un service réseau du système d'exploitation installé sur le poste ou un service exécuté depuis un périphérique de démarrage (LiveCD, Clé USB, PXE, etc.).

Une autre approche est de créer une image très basique du système à déployer et d'appliquer en post-installation tous les logiciels et paramètres de configuration. L'avantage par rapport à la première approche est le côté moins figé de l'image. Il est possible de mettre à jour de manière modulaire les éléments de configuration en modifiant la configuration du système post-installation. L'inconvénient est que côté administration système, cela fait un service de plus à gérer. C'est à mettre en balance avec la fréquence de modification des images. De tels systèmes de configuration post-installation peuvent soit s'appuyer sur le système de gestion de paquets de la distribution (Kickstart pour rpm et FAI pour dpkg), soit être agnostiques par rapport au système utilisé, moyennant évidemment une couche d'abstraction entre lui et le système d'exploitation (Puppet et Chef).

1. Kadeploy

Kadeploy est utilisé au sein du pôle recherche de la DSI de l'université Paris 13 pour déployer les nœuds du cluster HPC (High Performance Computing) partagés par les différents laboratoires du campus. Il est installé sur un nœud d’administration sous Debian et il est chargé de déployer des images en Debian Wheezy avec la couche logicielle HPC. Le déploiement passe par le réseau hors-bande du cluster soit un réseau Ethernet classique (par opposition aux réseaux à faible latence type Infiniband dédiés au calcul). D'un point de vue scientifique, l’intérêt de Kadeploy est ses excellentes performances sur les déploiements à large échelle [2]. D'un point de vue administration système, c'est sa qualité d'intégration et son fonctionnement très modulaire.

1.1 Architecture

Kadeploy s'appuie sur les briques standards du système. C'est un système assez modulaire et l'installation présentée dans cet article repose sur TakTuk, PXE, DHCP, Puppet, OpenSSH et IPMI. Kadeploy est divisé en deux grosses parties :

- Une partie serveur kadeploy3d qui écoute sur le réseau en attente des demandes de déploiement. Une fois la demande reçue, il lance le déploiement sur la ou les machines concernées ;

- Une partie cliente composée d'un ensemble de commandes préfixées par « ka » : kaenv3, kadeploy3 et karights3 pour les principales utilisées dans cet article.

Le serveur Kadeploy3d écrit ses informations dans une base de données MySQL. Ces informations sont essentiellement relatives aux droits des utilisateurs (qui peut déployer quoi et où) et à l'état des déploiements. Le déploiement d'une machine se décompose en plusieurs étapes (voir figure 1) :

1. La machine à déployer démarre en boot PXE et accroche un serveur PXE ;

2. Le serveur PXE lui fait amorcer un noyau Linux accompagné d'un initrd (petit système de base) minimal. Ce noyau est appelé « noyau de déploiement » dans la terminologie Kadeploy ;

3. Lors de l'initialisation des paramètres réseaux, le noyau de déploiement récupère la configuration via le serveur DHCP (ce n'est pas nécessaire au bon fonctionnement de Kadeploy, c'est un choix arbitraire pour configurer le réseau du noyau de déploiement) ;

4. Le serveur Kadeploy se connecte alors par SSH à la machine pour partitionner le disque et instancier le système de fichiers ;

5. Le serveur Kadeploy envoie l'image sur le système de fichiers fraîchement instancié ;

6. Le serveur Kadeploy redémarre la machine et attend qu'elle ait fini de démarrer pour notifier la réussite du déploiement.

steps

Fig. 1: Étapes de déploiement d'un système sur un nœud via Kadeploy.

1.2 Installation

Dans cet article, Kadeploy est installé sur une Debian Wheezy via les paquets deb fournis sur la forge INRIA [3]. Kadeploy est développé en Ruby, stocke ses informations dans une base MySQL et utilise l'infrastructure de communication TakTuk [4]. Nous reviendrons sur TakTuk un peu plus tard. Installons les dépendances à partir du gestionnaire de paquets :

# apt-get install ruby ruby-mysql taktuk

Ensuite, il faut télécharger les .deb depuis la forge INRIA et les installer :

# dpkg -i kadeploy-client_3.3.0~rc5-1_all.deb kadeploy-common_3.3.0~rc5-1_all.deb kadeploy_3.3.0~rc5-1_all.deb

La dernière étape de l'installation est de mettre en place la partie MySQL. Cette phase est très classique et consiste à installer le serveur et y injecter la base kadeploy en y associant un utilisateur dédié :

# apt-get install mysql-server

Après avoir répondu aux questions de debconf, il faut se connecter à l'instance MySQL fraîchement installée :

# mysql -u root -p

Créer la base de données :

mysql> CREATE DATABASE deploy3;

Ajouter l'utilisateur dédié à cette base de données :

mysql> GRANT select, insert, update, delete, create, drop, alter, create temporary tables, lock tables ON deploy3.* TO 'deploy'@'localhost';

Et on lui fixe un mot de passe :

mysql> SET PASSWORD FOR 'deploy'@'localhost' = PASSWORD('kadeploy');

Enfin, on ajoute les tables nécessaires au fonctionnement de Kadeploy :

mysql> use deploy3;

mysql> source /usr/share/doc/kadeploy/db_creation.sql

La partie physique de l'installation de Kadeploy est terminée, passons aux briques sur lesquels il s'appuie. Cet article est une proposition d'assemblage de briques sur lesquelles appuyer l'installation de Kadeploy. Comme mentionné dans la section précédente, Kadeploy est modulaire et s'appuie sur des protocoles plutôt que des implémentations. L'administrateur a toute latitude pour composer son infrastructure Kadeploy (par exemple si les clients supportent l'iPXE, ils peuvent récupérer environnement de déploiement sur un serveur HTTP plutôt que par TFTP). De mon point de vue d'administrateur système, c'est l'aspect le plus intéressant et ingénieux de Kadeploy. Le code développé au sein du projet s'appuie sur des services standards et les directives de configuration de Kadeploy sont suffisamment génériques pour utiliser les implémentations de services que l'on veut.

2. Installation des briques

Cette étape consiste à démarrer le noyau de déploiement et instancier le système de fichiers sur la machine visée. Les protocoles utilisés sont DHCP et PXE pour le démarrage de la machine. Un noyau Linux minimal de déploiement sera ensuite configuré. Nous allons commencer par quelques rappels sur les protocoles utilisés par Kadeploy.

2.1. DHCP et PXE

DHCP est un protocole de paramétrage automatique de la couche réseau des machines. Lors de l’initialisation de la couche réseau, la machine envoie une requête DHCPDISCOVER en broadcast sur le réseau. Un serveur DHCP répond avec un DHCPOFFER. Le client sélectionne la première offre reçue. Il forme ensuite une requête DHCPREQUEST à destination du serveur retenu et celui-ci répond avec un DHCPACK contenant les paramètres réseau du demandeur (adresse, DNS et passerelle par défaut).

BOOTP est une option du protocole DHCP qui permet de définir un serveur à attaquer en TFTP (ou en HTTP si la carte réseau gère l'iPXE) pour récupérer une image de démarrage. Les interfaces réseau implémentant la norme PXE peuvent réaliser ce type de démarrage.

La configuration minimale pour Kadeploy est un démarrage PXE proposant un noyau de déploiement avec son initrd. À cette configuration, une netinstall standard Debian a été ajoutée. Cet ajout vient du fait que cela facilite la vie pour créer un master de système à déployer sur des machines ne disposant pas de port USB et encore moins de lecteurs CD/DVD. Cette installation est faite à partir des paquets. Dans un premier temps, nous allons installer la partie strictement minimale pour Kadeploy, soit un serveur DHCP, un serveur TFTP (nos cartes ne font pas de l'iPXE) et les bootstrap PXE à démarrer par le réseau :

# apt-get install isc-dhcp-server tftpd-hpa syslinux

2.1.1. DHCP

Le service DHCP sert à gérer les requêtes DHCPDISCOVER contenant l'option de démarrage PXE générées par les interfaces réseau des clients configurés pour démarrer par le réseau. Le serveur DHCP doit disposer d'un fichier d'amorce (ici pxelinux.0) accessible depuis une adresse de serveur TFTP. Tout cela se passe dans le fichier /etc/dhcp/dhcpd.conf :

ignore client-updates;


subnet 192.168.40.0 netmask 255.255.255.0 {

        option domain-name "bullx";

        option domain-name-servers @IP_SDNS;

        option routers @IP_GW;

        pool {

                range 192.168.40.20 192.168.40.200;

                use-host-decl-names on;

                filename "pxelinux.0";

                next-server @IP_STFTP;

        }

}

On définit d'abord le réseau à servir en DHCP (subnet 192.168.40.0 netmask 255.255.255.0). Ensuite, on fixe tous les paramètres de configuration par défaut : le nom de domaine DNS à concaténer par défaut (option domain-name "bullx"), le(s) serveur(s) DNS (option domain-name-servers @IP_SDNS), et la passerelle par défaut (option routers @IP_GW). La section suivante définit un pool. Un pool est une étendue de machine. Ici, on va de la 20 à la 200 (range 192.168.40.20 192.168.40.200). Pour cette étendue, le nom de la déclaration servira de hostname (use-host-decl-names on). On lui demande d'aller chercher le fichier pxelinux.0 (filename "pxelinux.0") situé sur la machine @IP_STFTP (next-server @IP_STFTP).

2.1.2. TFTP

Au boot, la machine cliente cherche dans le répertoire pxelinux.cfg/ si elle trouve un fichier de configuration pour le boot PXE lui correspondant. La correspondance peut se faire par rapport à l'adresse MAC de l'interface réalisant le boot ou sur l'adresse IP de l'hôte. Si elle ne trouve rien, l'interface tente de trouver le fichier default :

PXE entry point found (we hope) at 9AE5:00D6

My IP address seems to be C0A80146 192.168.1.70

FTFTP prefix:

Trying to load: pxelinux.cfg/01-00-14-22-a1-53-85

Trying to load: pxelinux.cfg/C0A80146

Trying to load: pxelinux.cfg/C0A8014

Trying to load: pxelinux.cfg/C0A801

Trying to load: pxelinux.cfg/C0A80

Trying to load: pxelinux.cfg/C0A8

Trying to load: pxelinux.cfg/C0A

Trying to load: pxelinux.cfg/C0

Trying to load: pxelinux.cfg/C

Trying to load: pxelinux.cfg/default

On voit bien que la machine tente d'abord par l'adresse MAC, puis par l'IP (encodée en hexadécimal), puis par les sous réseaux pour enfin se résoudre à utiliser default. Voici le fichier default utilisé dans l'installation de Kadeploy sur le site :

default menu.c32

prompt 0


menu title Debian GNU/Linux installer boot menu


label local

menu label ^Boot local

menu default

kernel chain.c32

append hd0 0

timeout 50


label install

menu label ^Installation Debian Wheezy

kernel debian-wheezy/amd64/vmlinuz

append vga=788 initrd=debian-wheezy/amd64/initrd.gz -- quiet


label deploy

menu label ^Noyau deploiement Kadeploy

kernel kernels/vmlinuz-2.6.32-5-amd64

append vga=788 initrd=kernels/initrd -- quiet

Nous voyons ici trois entrées pour le menu de démarrage. Pour disposer d'un menu en mode texte, il faut placer le fichier menu.c32 à la racine du service TFTP (default menu.c32).

La première section est un démarrage local (label local). Ce boot est l'entrée par défaut (menu default). Ce démarrage utilise le module chain.c32 pour trouver un média sur lequel démarrer. Le média sélectionné ici est le MBR du premier disque dur (hd0 0). Si on avait voulu démarrer sur la première partition du second disque dur on aurait mis hd1 1. Cette entrée sera automatiquement sélectionnée au bout de 5 secondes (timeout 50).

La seconde section démarre l'installeur Debian pour la version Wheezy (label install). Ici on charge un noyau (kernel debian-wheezy/amd64/vmlinuz) et l'initrd qui va avec (ligne suivante, append).

La dernière section démarre un noyau avec un initrd contenant tous les outils pour dépanner une machine plantée. Ici il s'agit du noyau utilisé par Kadeploy. Nous verrons dans la section suivante comment créer (et personnaliser) le noyau Kadeploy.

L'utilisateur deploy doit pouvoir écrire dans le répertoire /var/lib/tftp/pxelinux.cfg/. Kadeploy va utiliser ce répertoire tout au long de l’exécution du processus de déploiement pour piloter par PXE le contexte de boot de la machine (boot local ou environnement de déploiement).

# chown -R deploy /srv/tftp/pxelinux.cfg

2.2. Noyau de déploiement

Ce noyau intervient au moment du déploiement d'une machine. En fait, la machine doit démarrer dessus par PXE. Kadeploy utilise un outil nommé debirf pour générer le noyau et l'initrd à déposer dans le répertoire TFTP. debirf propose un ensemble de scripts facilitant grandement la création d'un environnement de boot minimal . En très gros, il récupère un kernel pour l'image vmlinuz et il fait un debootstrap pour peupler l'initrd (debirf s'occupe de la partie archivage/compression). On obtient deux fichiers en sortie :

- Un noyau ;

- Un initrd.

Il faut installer deux paquets supplémentaires pour créer son noyau de démarrage : debootstrap et debirf (et éventuellement build-essential s'il n'est pas présent) :

# apt-get install debootstrap build-essential debirf

Les prérequis pour un initrd Kadeploy sont :

- Un serveur SSH pour recevoir des commandes depuis le service Kadeploy. Les connexions du service Kadeploy se font traditionnellement via une clé. Il faut donc que cette clé soit installée dans l'initrd ;

- Les drivers minimaux type contrôleurs disques ;

- Les outils d'instanciation de systèmes de fichiers (mkfs, fsck) ;

- Un client DHCP (nous utilisons une imputation par l'adresse MAC, nous savons quelle machine est derrière quelle IP).

Pour créer un tel environnement avec Kadeploy, il faut commencer par copier la partie publique de la clé SSH dans l'environnement de debirf :

# cp /etc/kadeploy3/keys/id_deploy.pub /opt/kadeploy-3.3.0.rc8/addons/deploy_env_generation/debirf/kadeploy-deploy-kernel/kadeploy_specific/ssh/

Ensuite, il faut aller dans le répertoire /opt/kadeploy-3.3.0.rc8/addons/deploy_env_generation/debirf et exécuter cette commande :

# make all

Cette commande va aller lire le fichier debirf.conf pour récupérer la distribution sur laquelle baser l'initrd (DEBIRF_DISTRO), les miroirs (DEBIRF_MIRROR) et la liste des paquets à inclure/exclure dans l'initrd (INCLUDE / EXCLUDE). Ce delta de paquets se fait par rapport au debootstrap.

Cet environnement est tout à fait personnalisable. Par exemple, on peut ajouter le support du firmware pour les cartes réseaux broadcom (firmware-bnx2). Debirf utilise un système de modules pour personnaliser l'initrd. Ils sont localisés dans le répertoire modules de la configuration de votre environnement à créer. Un module existant a0_add_extra_repos active déjà les dépôts « non-free ». On peut créer un autre module firmware-bnx2 pour installer les firmwares broadcom :

#!/bin/bash -e


debirf_exec sh -c "apt-get -y install firmware-bnx2"

On notera que la commande apt-get n'est pas invoquée en direct, mais via la fonction debirf_exec qui réalise un chroot dans l’environnement avant de lancer la commande en paramètre (sinon le paquet sera installé sur le système de base et non dans l'initrd). En sortie, on obtient bien deux fichiers vmlinuz-3.2.0-4-amd64 et debirf-kadeploy-deploy-kernel_wheezy_3.2.0-4-amd64.cgz qui sont respectivement le noyau et l'initrd.

On peut aller observer le contenu pour voir ce qui est réellement installé dans l'initrd associé au noyau de déploiement. On commence par faire une copie de l'initrd original :

# cp /opt/kadeploy-3.3.0.rc8/addons/deploy_env_generation/debirf/kadeploy-deploy-kernel/debirf-kadeploy-deploy-kernel_wheezy_3.2.0-4-amd64.cgz ~/test_initrd

# cd ~/test_initrd

On le décompresse :

# gunzip -dc debirf-kadeploy-deploy-kernel_wheezy_3.2.0-4-amd64.cgz > initrd.cpio

On le désarchive dans le répertoire initrd-rep :

# mkdir initrd-rep

# cd initrd-rep/

# cpio -i < ../initrd.cpio

Puis on décompresse/désarchive la racine de l'initrd :

# gzip -dc rootfs.cgz | cpio -idumv

Pour ajouter des éléments, il vaut mieux passer par la configuration de debirf plutôt que copie et archivage/compression du tout.

2.3. TakTuk

TakTuk est une infrastructure de communication également développée à l'INRIA. Cette infrastructure gère la diffusion de l'information de manière arborescente. Chaque cible de la diffusion peut devenir une source. Si on prend comme exemple la diffusion de la commande hostname sur N machines, cela peut se gérer de trois manières :

- Boucle sur la liste de machines, hostname est exécuté sur la machine 1 puis sur la 2 jusqu'à N ;

- En effectuant un fork du programme lanceur, plusieurs connexions peuvent être gérées en parallèle. Attention aux limites du système en termes de processus par utilisateurs ;

- Diffusion hiérarchique, hostname est exécuté sur la machine 1. La machine 1 se connecte ensuite à la 2 et la 6 pour lancer hostname. La machine 2 se connecte à la 3 et à la 7 et exécute la commande. La machine 6 se connecte à la 8 et à la 9, etc.

Une boite à outils nommée Kanif a été développée au-dessus de TakTuk. Dans cette boîte à outils, on trouve les outils kash (lancement d'une commande sur N nœuds), kaput (copie de fichiers vers N machines) et kaget (récupérer des fichiers de N sources). Ces outils sont des wrappers développés autour de la commande taktuk pour en faciliter l'utilisation. Taktuk est présent dans les dépôts Debian de base :

# apt-get install taktuk

Taktuk est également utilisé par Kadeploy pour propager les commandes sur le cluster.

3. Configuration de kadeploy3d

kadeploy3d est un démon qui accepte les connexions des outils client Kadeploy. L'utilisateur peut interroger kadeploy3d pour lister les images disponibles, en ajouter/supprimer une ou lancer un déploiement.

3.1. Environnement

Pour fonctionner, le serveur kadeploy3d a besoin de se connecter à la base MySQL, de modifier les fichiers du démarrage PXE et définir qui peut interagir avec lui (via les commande ka*). Dans les nouvelles versions de Kadeploy, la communication entre les clients et le serveur se fait en SSL. Un répertoire ssl a été crée pour accueillir les certificats générés avec la commande :

# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out ./server.crt -keyout ./server.key

Les permissions doivent être fixées :

# chown -R deploy ../ssl

# chmod 400 server.key

# chmod 444 server.crt

Enfin, il faut créer une clé SSH sans mot de passe pour que le serveur Kadeploy puisse interagir avec les machines dont il gère le déploiement. Cette clé sera utilisée dans le système déployé pour, par exemple, le redémarrer en vue d'un redéploiement. Elle sera également présente dans le noyau de déploiement pour que kadeploy3d puisse effectuer les actions d'installation. Les clés sont stockées dans le répertoire keys.

# ssh-keygen -b 2048 -t rsa -f /etc/kadeploy3/keys/id_deploy

3.2 Configuration du démon

La configuration du service se fait dans le fichier server.conf. Les paquets sont fournis avec des fichiers d'exemples comprenant un certain nombre de paramètres préconfigurés. L'idée est de ne modifier que les attributs propres à notre installation. Commençons par la section base de données (cf. 2.2) :

database:

name: deploy3

kind: mysql

host: localhost

login: deploy

passwd: kadeploy

Ce sont les paramètres classiques : nom de la base de données (name), le type (kind), la machine sur laquelle le serveur de base de données est en exécution (host), le nom d'utilisateur dédié à l'accès à la base (login) et le mot de passe associé (passwd).

La seconde grosse partie à configurer est le PXE. Cette section décrit au serveur Kadeploy l'organisation du service de démarrage PXE (pxe) :

pxe:

dhcp:

method: PXElinux

repository: /srv/tftp

export:

kind: tftp

server: 192.168.40.4

profiles:

directory: pxelinux.cfg

filename: ip_hex

Il faut d'abord indiquer que l'amorçage du noyau de déploiement se fait depuis un service DHCP (dhcp) via PXElinux (method). On indique ensuite l'emplacement des fichiers de démarrage (repository). Comme ici la méthode de récupération de ces fichiers est TFTP (kind) depuis un serveur distant (server), cela revient à indiquer la racine du service TFTP. Enfin, le répertoire contenant les fichiers de configuration des machines démarrant sur PXE (directory) ainsi que la convention de nommage de ces fichiers (filename) sont renseignés. Pour mémoire, le répertoire indiqué dans profiles comme valeur de l'attribut directory doit être accessible en écriture à l'utilisateur deploy.

Attention à la section external / mkfs, il faut ajouter un -q aux variables args. En effet, si la sortie d'une commande est trop verbeuse, cela fait planter l'infrastructure de communication TakTuk (cf 3.3) :

mkfs:

- args: -b 4096 -O sparse_super,filetype,resize_inode,dir_index -q

fstype: ext4

La communication peut se faire de façon chiffrée (via SSL) ou en clair. Pour activer le SSL, il faut ajouter un certificat auto signé :

# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -out ./server.crt -keyout ./server.key

On peut mettre ce que l'on veut dans le CN, car SSL est juste utilisé pour le chiffrement de la communication et non pour l'authentification du serveur Kadeploy auprès du client. Il faut ensuite l'activer côté serveur (security) :

security:

secure_server: true

local_only: true

certificate: /etc/kadeploy3/ssl/server.crt

private_key:

algorithm: RSA

file: /etc/kadeploy3/ssl/server.key

Ici on accepte seulement des requêtes locales à la machine (local_only) en SSL (secure_server). On lui donne l'emplacement du certificat (certificate) et de la clé privée (private_key / file). Il existe également des possibilités d'authentification du client auprès du serveur. On distingue deux niveaux : machine et identité de l'utilisateur. Au niveau machine, on peut autoriser n'importe quel utilisateur d'une machine à lancer des commandes Kadeploy :

authentication:

acl:

whitelist:

- localhost

Dans cet exemple, tout ce qui vient de l'hôte local est autorisé (cohérent avec le local_only à true). On parle d'une authentification au niveau machine. Pour authentifier un utilisateur, Kadeploy propose 3 méthodes : htpasswd, ident et les certificats. Chacune de ces méthodes propose de définir une whitelist de machines autorisées, quel que soit l'utilisateur qui lance la commande Kadeploy. On notera que cette authentification n'est pas du tout destinée à autoriser ou pas un utilisateur à déployer une image, mais plutôt à définir qui est autorisé à interagir avec le serveur Kadeploy. L'autorisation de qui peut déployer quoi et où sera discutée dans la section 4.4.

3.3. Configuration d'un template de machines

Un template de machines est un type de machines à configurer. Sur le site où kadeploy est utilisé, nous avons deux templates : un pour les nœuds de calculs et un autre pour les nœuds GPU. La différence entre les deux étant la présence des librairies CUDA sur le nœud GPU. Cette association entre machines physiques et templates se fait dans le fichier clusters.conf :

---

clusters:

- name: common

  conf_file: /etc/kadeploy3/cluster-common.conf

  nodes:

- address: 192.168.40.10

  name: magi10

- address: 192.168.40.11

  name: magi11

Ce fichier définit une suite de clusters. Chaque cluster possède un nom (name), un fichier de configuration (conf_file) et une suite de machines (nodes). Chaque machine est identifiée par une adresse IP (address) et un nom (name). Passons au fichier cluster-common.conf qui définit le template pour tous les nœuds de calcul.

La première chose à faire est de décider du plan de partitionnement des machines. Celui des nœuds de calcul est très simple. Il est composé de quatre partitions primaires : / de 30 Gi, swap de 12 Gi, /tmp de 2 Gi et /scratch de la taille restante. Cela se répercute de la façon suivante dans le fichier de configuration :

partitioning:

partitions:

tmp: 3

deploy: 1

swap: 2

prod: 6

disable_swap: false

block_device: /dev/sda

script: parted-common

La section partitioning contient une liste de partitions. Chaque partition est identifiée par un numéro. Ce numéro correspond au numéro de périphérique attaché à la partition. Par exemple, pour un disque dur sur /dev/sda, le chiffre 1 correspond à /dev/sda1. D'après la configuration, nous avons /dev/sda3 monté sur /tmp, le swap sur /dev/sda2, le / du système déployé sur /dev/sda1 et une partition prod sur /dev/sda6. Or il n'a jamais été question d'une telle partition dans le plan de partitionnement composé de 4 partitions primaires (une partition numérotée 6 est donc un non-sens). Pour comprendre, il faut rappeler que Kadeploy a été développé pour déployer des systèmes expérimentaux sur du vrai matériel à large échelle. La configuration standard est d'avoir sur un nœud un système de production et un système expérimental déployé par l'utilisateur. Lorsqu'un nœud est réservé pour une expérimentation, Kadeploy redémarre le système de production pour lancer le déploiement du système à tester sur la partition deploy et modifie la séquence de démarrage pour amorcer sur ce nouveau système.

La section précédente ne fait que décrire le partitionnement. Pour le réaliser de manière effective, il faut créer (ou adapter) un script de partitionnement (script). Dans notre exemple, il s'agit du fichier parted-common :

#!/bin/bash -e


PARTED_OPTS="--script -a optimal"

UNIT="GB"


function do_parted()

{

/sbin/parted $PARTED_OPTS $KADEPLOY_BLOCK_DEVICE unit $UNIT $@

}

do_parted "mklabel msdos"

do_parted "mkpart primary ext4 0% 30"

do_parted "mkpart primary linux-swap 30 42"

do_parted "mkpart primary ext4 42 44"

do_parted "mkpart primary ext4 44 100%"

do_parted "toggle $KADEPLOY_DEPLOY_PART_NUM boot"

do_parted "align-check optimal 1"

do_parted "align-check optimal 2"

do_parted "align-check optimal 3"

do_parted "align-check optimal 4"

/sbin/partprobe $KADEPLOY_BLOCK_DEVICE

Ce script définit les options à passer à parted (PARTED_OPTS) et l'unité de stockage par défaut (UNIT). Une fonction do_parted est ensuite créée pour invoquer la commande parted avec les bons arguments. Cette fonction est ensuite utilisée pour créer un partitionnement de type msdos (mklabel msdos) et 4 partitions primaires (trois en ext4 et une swap). Chaque ligne est construite sur le même modèle : invocation de la fonction do_parted suivie du type de partition (mkpart primary ext4), du début et de la fin de celle-ci. On a donc une partition démarrant à 0% (c'est-à-dire au début du disque) et s’arrêtant à 30GB (/) suivie d'une partition démarrant à 30GB et s’arrêtant à 42GB soit 12GB pour le swap, puis une allant de 42GB à 44GB soit une taille de 2GB (/tmp) et enfin une partition de la taille restante, c'est-à-dire de 44GB à 100% (/scratch). La partition deploy est ensuite définie comme partition bootable (toggle). Les partions sont ensuite alignées de manière optimale (align-check optimal) et le système est notifié du nouveau partitionnement via la commande partprobe.

La section suivante configure le démarrage de la machine (boot) :

boot:

install_bootloader: install_grub2

kernels:

deploy:

initrd: kernels/initrd

params: console=tty0 console=ttyS0,38400n8 rw

vmlinuz: kernels/vmlinuz-3.2.0-4-amd64

user:

params: console=tty0 console=ttyS0,38400n8

On commence par configurer le gestionnaire de démarrage de la machine à déployer (install_bootloader). Ici il s'agit de GRUB2, le script install_grub2 est récupérable dans l'archive .tar.gz de Kadeploy. La deuxième partie concerne la configuration du noyau de déploiement (deploy) et du système déployé (user). Pour le noyau de déploiement, on définit l'emplacement de l'initrd (initrd) et du noyau (vmlinuz) relativement par rapport à la racine du serveur TFTP (la racine ayant été définie dans le fichier server.conf). Pour les deux noyaux, on donne la liste des paramètres à utiliser pour le démarrage (params).

Une autre information que Kadeploy doit posséder c'est comment procéder à l'allumage, à l'arrêt et au redémarrage des machines. Ces informations sont présentes dans la section remoteops du fichier de configuration :

remoteops:

reboot:

- name: soft

  cmd: ssh -A -q -o BatchMode=yes -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o ConnectTimeout=2 -o UserKnownHostsFile=/dev/null -i /etc/kadeploy3/keys/id_deploy root@HOSTNAME_SHORT /sbin/reboot

- name: hard

  cmd: ipmitool -vI lan -H HOSTNAME_SHORT-ipmi -U root -f /etc/kadeploy3/ipmi/pass chassis power reset

Nous allons juste détailler la partie relative au redémarrage (reboot), les sections allumage (power_on) et arrêt (power_off) sont construites sur le même modèle. Pour le redémarrage, nous avons deux possibilités ayant chacune un nom (name) et une commande associés (cmd). Le nom est une sorte de niveau de la commande à invoquer. On distingue trois niveaux : soft, hard et very hard. Ici, soft correspond à une commande SSH : Kadeploy essaye de redémarrer la machine en envoyant une commande reboot via SSH. La commande hard est une commande IPMI exécutant un arrêt/redémarrage du châssis. IPMI est un contrôleur indépendant sur la machine permettant d'envoyer des ordres à la partie matérielle du serveur (arrêt du châssis, remontées de températures, ouvrir une console virtuelle, etc.). Le niveau very hard n'est pas configuré, mais pourrait interagir avec le PDU.

Enfin, il est également possible de définir des actions pré ou post installation. Sur notre installation, nous avons juste un script qui s’exécute post-installation (postinstall) :

postinstall:

files:

- file: /store/postinst.tgz

  format: tgz

  script: launch.sh

Plusieurs fichiers peuvent être définis (files). Chaque entrée file correspond à une archive compressée (file) dans un certain format (format). Le script à exécuter à l'intérieur de l'archive doit être précisé (script). Dans notre exemple, le script launch.sh de l'archive compressée postinst.tgz est exécuté. Le fichier launch.sh doit être à la racine de l'archive :

# tar -czf postinst.tgz launch.sh

3.4 Lancement du premier déploiement

La configuration touche à sa fin. Il faut maintenant créer une image à déployer, créer le fichier de configuration de cette image et donner le droit à l'utilisateur de déployer cette image. Commençons par créer une image. Nous partons d'une image Debian Wheezy tout à fait standard.

L'INRIA met à disposition un outil, tgz-g5k [5] qui remonte un système de fichiers en lecture seule afin de créer une archive compressée en excluant certains fichiers. Cet outil est à installer et à exécuter sur le système dont on souhaite faire une image. La documentation d'installation est assez complète. Une fois l'outil installé, la commande est simple :

# tgz-g5k upload@kadeploy:/store/wheezy-hpc.tgz

Cette commande crée une image du système dans l'archive compressée wheezy-hpc.tgz directement sur le serveur kadeploy via SSH en utilisant l'utilisateur upload. Une fois cette image créée, il faut lui ajouter un petit fichier de description (par exemple wheezy-hpc.desc) :

name: wheezy-hpc

version: 1

description: wheezy-hpc

author: nicolas greneche

visibility: shared

image:

file: /store/wheezy-hpc.tgz

kind: tar

compression: gzip

boot:

kernel: /boot/vmlinuz-3.2.0-4-amd64

initrd: /boot/initrd.img-3.2.0-4-amd64

partition_type: 0x83

filesystem: ext4

os: linux

Les paramètres sont assez explicites pour le nom (name), la version (version), la description (description) et l'auteur (author). La visibilité (visibility) propose 3 valeurs :

- privé (private) : seul l'auteur (author) peut l'utiliser ;

- partagée (shared) : tout le monde peut l'utiliser, seulement le nom de l'auteur doit être spécifié dans les commandes ;

- publique (public) : tout le monde peut l'utiliser sans restriction.

La section image renseigne l'emplacement physique de l'archive compressée du système à déployer sur le système de fichiers (file), le type d'archive (kind) et le type de compression (compression). La section boot sert à localiser le noyau (kernel) et l'initrd (initrd) à l’intérieur de l'archive. On termine par le type de partition sur laquelle le système sera déployé (partition_type), le type de système de fichiers à instancier sur cette dernière (filesystem) et la famille de système d'exploitation (os). L'image doit ensuite être enregistrée via la commande kaenv3 :

# kaenv3 -a wheezy-hpc-v4.desc

Et on vérifie :

# kaenv3 -l

Name Version User Description

#### ####### #### ###########

wheezy-hpc 1 root wheezy-hpc

Il ne reste plus qu'à spécifier que notre utilisateur peut demander un déploiement :

# karights3 -a -u root -p /dev/sda1 -m magi[10-50]

Cela veut dire que potentiellement root peut déployer une image sur la partition /dev/sda1 des machines magi10 à magi50.

Lançons maintenant le déploiement :

# kadeploy3 -e wheezy-hpc-v4 -m magi10

Deployment #D-aff57e2e-bdc8-4d5f-a132-47b3f6352d32 started

Grab the tarball file /store/wheezy-hpc.tgz

Launching a deployment on magi10

Performing a Deploy[SetDeploymentEnvUntrusted] step

switch_pxe

reboot

* Performing a soft reboot on magi10

* Performing a hard reboot on magi10

wait_reboot

create_partition_table

format_deploy_part

mount_deploy_part

format_swap_part

End of step Deploy[SetDeploymentEnvUntrusted] after 85s

Performing a Deploy[BroadcastEnvChain] step

send_environment

* Broadcast time: 163s

manage_admin_post_install

manage_user_post_install

check_kernel_files

install_bootloader

sync

End of step Deploy[BroadcastEnvChain] after 213s

Performing a Deploy[BootNewEnvClassical] step

switch_pxe

umount_deploy_part

reboot_from_deploy_env

wait_reboot

End of step Deploy[BootNewEnvClassical] after 82s

End of deployment for magi10 after 380s

End of deployment on cluster common after 380s

Deployment #D-aff57e2e-bdc8-4d5f-a132-47b3f6352d32 done


The deployment is successful on nodes

magi10

Le déploiement s'est déroulé de la manière suivante :

1. Redémarrage soft de la machine à déployer. C'est un échec, car la clé SSH de Kadeploy n'est pas installée sur le système cible. Kadeploy tente donc un redémarrage hard par IPMI ;

2. Une fois la machine redémarrée, les partitions sont créées. Le système de fichiers ext4 et instancié sur /dev/sda1 et le swap sur /dev/sda2 ;

3. L'archive du système à déployer est envoyée sur la machine ;

4. Les tâches post-installation sont réalisées (nous y reviendrons dans la section suivante) ;

5. Installation du système de démarrage ;

6. Démontage de la partition du système et redémarrage ;

7. Vérification de la disponibilité de la machine redéployée ;

À ce stade, nous disposons d'une machine fonctionnelle déployée avec Kadeploy. Ce déploiement est essentiellement binaire, mais propose d'utiliser des scripts de pré/post-installation. Nous allons utiliser cette possibilité pour coupler Kadeploy et Puppet.

4. Post-installation avec Puppet

Dans notre procédure d'installation, l'appel à Puppet se fait juste après le déploiement du système et le redémarrage sur ce dernier. Au moment où Puppet s’exécute, nous avons donc l'archive du système à déployer décompressée dans /mnt/dest. L'objectif est de combiner Puppet et Kadeploy. Cela pose plusieurs problèmes. Nous souhaitons garder les clés SSH d'un hôte à travers ses redéploiements pour éviter de mettre à jour sans cesse le known_hosts ainsi qu'une configuration réseau Ethernet et Infiniband statique.

4.1 Gestion des certificats avec Kadeploy et Puppet

Un problème se pose lorsque Puppet et Kadeploy sont combinés. Pour bien comprendre, lorsque Puppet est lancé pour la première fois sur le client, il génère un certificat qu'il envoie au serveur qui le signe. Cette authentification bilatérale empêche un client non autorisé de récupérer une configuration par la suite. La conséquence niveau déploiement est que la partie cliente doit être « impersonnifiée » (c'est-à-dire que dans l'image de référence il faut retirer le certificat de la machine, la clé privée et le certificat du serveur Puppet). Cette partie est simple, le script tgz-g5k est très bien fait pour ça. Il suffit de noter les fichiers à exclure de l'image dans le fichier dismissed :

# cat /usr/local/share/tgz-g5k/dismissed | grep puppet

etc/puppet/ssl/certificate_requests/*

etc/puppet/ssl/public_keys/*

etc/puppet/ssl/*

etc/puppet/ssl/private_keys/*

etc/puppet/ssl/certs/*

Pour la suppression du certificat de la machine côté serveur Puppet, il faut invoquer la commande suivante :

# puppet cert clean magi11.bullx

Le meilleur moment pour faire cette action est lors du déploiement. Du moment que l'on décide de redéployer un hôte, son certificat sur le serveur doit être effacé et révoqué. Seulement Kadeploy ne propose pas de hook permettant de faire lancer une commande au service kadeploy3d.

Nous avons choisi de gérer ce problème en faisant faire une connexion SSH à l’environnement de déploiement déclenchant une ForcedCommand qui invalide le certificat sur le serveur Puppet. On génère une clé SSH sur le serveur Puppet :

# ssh-keygen -t rsa -b 2048 -f /etc/puppet/keys/puppet

On ajoute cette clé dans le authorized_keys de l'utilisateur puppet :

# cat /etc/puppet/keys/puppet.pub >> /var/lib/puppet/.ssh/authorized_keys

On rédige un script à utiliser en ForcedCommand qui va invalider le certificat du client sur le serveur Puppet/var/lib/puppet/scripts/clean.sh :

#!/bin/bash

case $SSH_ORIGINAL_COMMAND in

"/usr/bin/puppet cert clean "*)

$SSH_ORIGINAL_COMMAND

echo "$SSH_ORIGINAL_COMMAND" > /tmp/test.txt

;;

*)

echo "Permission denied."

exit 1

;;

esac

La variable d’environnement SSH_ORIGINAL_COMMAND contient la commande passée en argument de la connexion SSH. L'idée du script est de n'autoriser que le passage d'une commande /usr/bin/puppet cert clean quelque_chose. On pourrait l’améliorer en faisant une requête DNS de quelque_chose pour voir s'il s'agit bien d'un FQDN.

On doit ensuite forcer cette commande côté serveur SSH :

# tail -n 2 /etc/ssh/sshd_config

Match User puppet

ForceCommand /var/lib/puppet/scripts/clean.sh

Enfin, on ajoute la connexion SSH au script de déploiement (fichier launch.sh de la section 4.3) :

ssh -A -q -o BatchMode=yes -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o ConnectTimeout=2 -o UserKnownHostsFile=/dev/null -i /etc/puppet/keys/puppet puppet@puppet "/usr/bin/puppet cert clean $dns_name"

4.2 Puppet en post-installation d'un environnement Kadeploy

Grâce à la section précédente, les certificats sont nettoyés et Puppet va pouvoir s’exécuter sur le système à déployer. Le système à déployer est décompressé dans /mnt/dest. Puppet est installé dans le système à déployer. Nous allons donc exécuter la commande puppet agent en la chrootant dans /mnt/dest.

Premier piège : il faut penser à ajouter le montage de proc et dev dans le chroot avant de lancer la commande puppet agent sinon tous les attributs renseignés par facter ne seront pas disponibles (par exemple les IP attachées aux interfaces). De plus, comme on génère des certificats, il faut que tous les périphériques de génération d'entropie soient accessibles dans le chroot.

Second piège : ajouter un wait après la phase de chroot. Le principe du wait est de dire au père d'attendre la mort du fils pour sortir du wait. Si on ne le fait pas, le déploiement échoue, car le script de post-installation se termine avant que le processus fils exécutant la commande chrootée n'ait terminé. Voici les lignes de commandes à ajouter dans le script launch.sh :

#!/bin/bash


...


mount -t proc none /mnt/dest/proc

mount --rbind /dev /mnt/dest/dev


chroot /mnt/dest /usr/bin/puppet agent --onetime --no-daemonize

wait


mount /mnt/dest/proc

mount /mnt/dest/dev

Conclusion

Kadeploy est un outil qui nécessite quelques bases au niveau administration système pour donner sa pleine mesure. Une fois ces bases maîtrisées, sa conception modulaire permet toutes les fantaisies. Chaque étape du déploiement est configurable. De nombreux hooks sont disponibles pour ajouter une commande ou un script. C'est un outil issu du monde de la recherche ayant parfaitement intégré les besoins de la production. De plus, ce logiciel libre est développé en France. De quoi en être fier, non ?

Références

[1] Grid'5000 : https://www.grid5000.fr/mediawiki/index.php/Grid5000:Home

[2] Performances de Kadeploy sur les déploiements à large échelle : http://hal.inria.fr/docs/00/70/09/62/PDF/kadeploy-scale2012.pdf

[3] Paquets Debian Kadeploy : http://kadeploy3.gforge.inria.fr/

[4] Infrastructure de communication TakTuk : http://taktuk.gforge.inria.fr/

[5] tgz-g5k : https://www.grid5000.fr/mediawiki/index.php/TGZ-G5K


Sur le même sujet

Basez votre supervision sur des logs de qualité avec Rsyslog

Magazine
Marque
Linux Pratique
HS n°
Numéro
47
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Les événements systèmes (aussi nommés logs dans la suite de l’article) sont des éléments déterminants pour la supervision du bon fonctionnement du système d’exploitation. Leur intérêt est souvent sous-coté aussi bien du point de vue maintenance du système que de sa sécurité. Cet article a pour ambition de poser les bases d’une bonne gestion des logs.

Neovim : dépoussiérez votre Vim

Magazine
Marque
Linux Pratique
HS n°
Numéro
47
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Une application historique, puissante, populaire avec une base utilisateurs énorme, une compatibilité multiplateforme ultra-large, un code et une API quasi inmaintenables, dirigée par un Dictateur Bienveillant À Vie comme chef de projet et unique développeur : Vim présente toutes les caractéristiques d’un projet libre à succès. Et donc aussi tous les problèmes qui irritent ses utilisateurs et les contributeurs qui auraient le courage de participer à son développement. Dans cet article, nous allons découvrir Neovim, un fork de Vim né de la frustration d’utilisateurs de l’éditeur.

Collectez et exploitez les métriques de votre système avec Collectd

Magazine
Marque
Linux Pratique
HS n°
Numéro
47
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Par défaut, votre système journalise dans différents fichiers les événements qui se passent vous permettant de déceler une activité anormale et autre plantage. Mais vous avez aussi besoin de collecter des métriques de votre système et de ses applications, et de générer les graphiques associés. Car c’est seulement grâce à ces données et graphiques que vous pourrez faire de l’analyse de performance pour détecter les goulots d’étranglement, ou faire de la gestion de capacité en prédisant la future charge système. Un des moyens les plus simples de collecter des données d’un serveur est d’utiliser le démon Collectd.

Hébergement privé de dépôts Git

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
109
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Nous allons voir comment mettre en place un hébergement de dépôts Git privé indépendant et évolutif, avec seulement trois containers. Cela comprendra une interface web, la possibilité de gérer plusieurs utilisateurs, organisations et leurs dépôts, qu’ils soient privés ou publics.

Cluster et orchestration de conteneurs avec Docker Swarm

Magazine
Marque
Linux Pratique
HS n°
Numéro
47
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Cet article prolonge mon précédent article [1] et parle de la capacité à introduire de la haute disponibilité dans les environnements de conteneurs Docker, critère indispensable pour pouvoir utiliser ces technologies jusqu’à la production, ceci au travers de la notion de cluster et d’orchestration de conteneurs.

Par le même auteur

Basez votre supervision sur des logs de qualité avec Rsyslog

Magazine
Marque
Linux Pratique
HS n°
Numéro
47
|
Mois de parution
juillet 2020
|
Domaines
Résumé

Les événements systèmes (aussi nommés logs dans la suite de l’article) sont des éléments déterminants pour la supervision du bon fonctionnement du système d’exploitation. Leur intérêt est souvent sous-coté aussi bien du point de vue maintenance du système que de sa sécurité. Cet article a pour ambition de poser les bases d’une bonne gestion des logs.

Surveillez votre système pour prévenir et détecter toute action malveillante

Magazine
Marque
Linux Pratique
HS n°
Numéro
46
|
Mois de parution
octobre 2019
|
Domaines
Résumé

Wazuh est un fork libre du projet OSSEC qui appartient à la famille des HIDS (Host Intrusion Detection System). Ces systèmes de détection d’intrusions vont surveiller les logs applicatifs, les appels système ainsi que le noyau pour tenter de détecter des compromissions de l’OS.

Installation et configuration d’un annuaire OpenLDAP

Magazine
Marque
Linux Pratique
Numéro
115
|
Mois de parution
septembre 2019
|
Domaines
Résumé

OpenLDAP est une implémentation libre du standard d’interrogation et de modification d’annuaire LDAP. Cet article ambitionne de vous donner les clés pour centraliser vos utilisateurs Linux dans un annuaire LDAP. Cependant, les connaissances acquises pourront également vous servir dans le monde Microsoft, car Active Directory s’appuie également sur le protocole LDAP.

Authentification de l’accès à votre réseau : mise en place d’un portail captif et d’un service 802.1X

Magazine
Marque
Linux Pratique
Numéro
114
|
Mois de parution
juillet 2019
|
Domaines
Résumé

Un portail captif est un élément de contrôle mandataire régulant l’accès au réseau pour les clients équipés d’un navigateur web. Dans cet article, nous allons voir comment intégrer cet élément dans une infrastructure pour authentifier les clients connectés en Wi-Fi avant leur accès effectif au réseau extérieur. Nous allons également présenter le 802.1X qui vise à authentifier les utilisateurs avant tout accès au réseau.