Serveur Clafoutis: Créer une grappe de calcul Super-Clafoutis
Introduction
- En bioinformatique, une analyse ne demande pas de faire une simple opération sur un seul fichier mais la même opération (ou l'usage du même programme mais avec des paramètres modifiés) sur des dizaines, sinon, des milliers de fichiers. Est-ce qu'on fait ça de manière sérielle, une tâche à la fois? Non, ça prendrait trop de temps
. Donc on utilise un ensemble d'ordinateurs, exécutant les opérations de manière parallèle ou pseudo-parallèle, et interconnectés par un réseau de communication à haute vitesse: c'est un cluster ou une grappe de calcul.
- Primo: ce sont de merveilleux outils d'enseignement et d'apprentissage. Une grappe de calcul ne s'emploie pas comme un ordinateur simple et il est nécessaire d'apprendre comment exécuter les tâches. Apprendre sur de grosses infrastructures peut poser problème…
- Secundo: pour certains usagers, faire du calcul parallèle n'est peut-être pas possible sur une infrastructure partagée. Les faibles coûts du RPi rend la construction d'une grappe basée sur eux plus facile et abordable.
Installation du matériel
- Donc, quel est le matériel nécessaire? Dans l'ordre:
- Plusieurs Raspberry Pi 4B ou Raspberry Pi 5 avec 8Gb et leur espace de stockage système (au minimum, des cartes MicroSD ou des clés USB de qualité avec une capacité minimale de 64Gb);
- Idéalement, autant de carte HAT PoE ou PoE+ (pour le Raspberry Pi 5) que de RPi pour l'alimentation électrique via le commutateur Ethernet.
- Une alternative est une alimentation électrique capable d'alimenter plusieurs dispositifs USB, procurant 15W/20W par port (5V/3A ou 5V/4A).
- Un commutateur Gigabit Ethernet, idéalement capable d'alimenter en électricité les RPi via le protocole PoE ou PoE+ (pour des Raspberry Pi 5).
- Une caractéristique souhaitable est la capacité de lier (bonding) plusieurs interfaces pour créer une interface à plus forte capacité pour le NAS.
- Si votre NAS possède un port 10Gb Ethernet, trouver un commutateur avec un port 10Gb Ethernet disponible.
- Un stockage partagé de type NAS, idéalement avec 4 ports réseau 1Gb capables d'être mis en commun via LACP.
- Si votre NAS possède un port 10Gb Ethernet ou bien peut accueillir une carte 10Gb Ethernet, c'est encore mieux
.
- Un système physique d'installation des RPi, ou bien en rack ou en bloc.
Installation logicielle en pré-requis
- Tous les RPi ont accès aux volumes partagés par le NAS (via NFS) sous
/opt/bio
(afin d'avoir les mêmes applications),/home
(pour que les RPi puissent écrire sur le même espace) et tout autre répertoire nécessaire (par exemple,/shares/data
pour le stockage des données partagées). - Si nécessaire. installer les librairies nécessaires sur les noeuds de calcul.
Protocole d'installation
Étape 0: Opérations préliminaires
- Modifiez le fichier
/etc/hosts
de tous les ordis qui feront partie de la grappe en inscrivant les infos associant nom de serveur et adresse IP. Par exemple, pour une grappe de 5 ordis oùgru
est le contrôleur et les ordisminion01
àminion04
seront les noeuds de calcul, on écrit ceci à la fin du fichier (les valeurs *.a.xy0 à *.a.xy4 sont évidemment spécifiques à votre réseau):
# Super Clafoutis 192.168.a.xy0 gru 192.168.a.xy1 minion01 192.168.a.xy2 minion02 192.168.a.xy3 minion03 192.168.a.xy4 minion04
- Pour faciliter l'accès inter-machines, utilisons l'accès SSH sans mot de passe via la création et l'installation d'une clé d'authentification:
# Sur gru | Pas besoin d'utiliser de phrase d'accès donc simplement presser enter lorsque demandé % ssh-keygen -t rsa # On copie la clé sur chaque minion % for i in {1..4}; do ssh-copy-id monUsager@minion0$i;done
- Pour le bon fonctionnement de
slurm
, les identificateurs d'usager (UUID) et de groupe (GUID) doivent être identiques pour tous les RPi de la grappe. Si nécessaire, il faudra les modifier dans les fichiers/etc/passwd
et/etc/group
.
Étape 1: Installation de MUNGE
- Il faut installer MUNGE sur tous les ordinateurs de la grappe:
% sudo apt install munge
- À la suite de cette opération, l'usager
munge
sera créé sur chaque système, le processusmunged
sera démarré par cet usager et les permissions nécessaires seront données au répertoire/etc/munge
et/etc/default/munge
- Dans le fichier
/etc/default/munge
du contrôleurgru
, insérer la ligne suivante dans le fichier/etc/default/munge
(par ex., vianano
):
OPTIONS="--syslog --key-file /etc/munge/munge.key"
- Créer une clé d'encryption sur le contrôleur
gru
qui sera utilisée pour les communications entre les noeuds:
% sudo -u munge mungekey --verbose
- Par défaut,
mungekey
crée une clé de 1024 bits, bien assez pour un usage de labo, sous/etc/munge
De plus, il aura les bonnes permissions.
- Démarrer/re-démarrer le service
munge
et vérifier qu'il fonctionne (les lignes affichées ne devraient pas contenir le motERROR
ouFAILED
…):
% sudo -u munge systemctl start munge && systemctl status munge
- Il faut maintenant, sur chaque noeud de la grappe, installer
munge
et copier la clé d'encryption qui se trouve sur le contrôleur. NOTE : pour réussir cela, il faudra permettre l'accèsssh
à l'usagerroot
sur les noeuds de traitement en activant la paramètrePermitRootLogin yes
du fichier/etc/ssh/sshd_config
et en redémarrant le servicessh
. Donc si on imagine notre grappe de 4 noeuds appelésminion01
àminion04
:
% for i in `seq 1 4`; do sudo scp /etc/munge/munge.key minion0${i}:/etc/munge/munge.key; done
- Ne pas oublier de retirer l'option
PermitRootLogin yes
dans le fichier/etc/ssh/sshd_config
de chaqueminion
et de redémarrer le servicessh
! Simplement ajouter le caractère#
en 1ère position sur la ligne. - Il reste à redémarrer le service
munge
et à vérifier que les RPi se reconnaissent:
# Sur chaque minion % sudo -u minion systemctl restart munge # Sur le controleur gru vers un des minions # A faire pour tous les minions pour s'assurer que ça fonctionne entre tout le monde. % ssh minion01 munge -n | unmunge # Vous devriez voir une sortie au terminal qui ressemble à ça: STATUS: Success (0) ENCODE_HOST: minion01 (192.168.1.xy1) ENCODE_TIME: 2022-07-02 10:36:24 -0400 (1656772584) DECODE_TIME: 2022-07-02 10:36:30 -0400 (1656772590) TTL: 10 CIPHER: aes128 (4) MAC: sha256 (5) ZIP: none (0) UID: bioubuntu (1030) GID: users (100) LENGTH: 0
- Pour s'assurer que le service
munge
soit démarré à chaque redémarrage des serveurs:
% sudo systemctl enable munge
Étape 2: Installation de SLURM sur le noeud contrôleur
- On commence par l'installation de
SLURM
viaapt
sur tous les RPi:
% sudo apt install slurm-wlm
- À la suite de cette opération, tous les RPi auront les bons répertoires avec les bonnes permissions
- Il faut maintenant créer un fichier de configuration
slurm.conf
sous/etc/slurm
.
# % sudo cp /usr/share/doc/slurm-client/examples/slurm.conf.simple.gz /etc/slurm # % cd /etc/slurm && gzip -d slurm.conf.simple.gz % sudo mv slurm.simple slurm.conf
- Il vous suffit de l'éditer pour qu'il ressemble à ceci:
ClusterName=clafoutis SlurmctldHost=gru(192.168.1.xy0) #SlurmctldHost= # #DisableRootJobs=NO #EnforcePartLimits=NO #Epilog= #EpilogSlurmctld= #FirstJobId=1 #MaxJobId=67043328 #GresTypes= #GroupUpdateForce=0 #GroupUpdateTime=600 #JobFileAppend=0 #JobRequeue=1 #JobSubmitPlugins=lua #KillOnBadExit=0 #LaunchType=launch/slurm #Licenses=foo*4,bar #MailProg=/usr/bin/mail #MaxJobCount=10000 #MaxStepCount=40000 #MaxTasksPerNode=512 MpiDefault=none #MpiParams=ports=#-# #PluginDir= #PlugStackConfig= #PrivateData=jobs ProctrackType=proctrack/linuxproc #Prolog= #PrologFlags= #PrologSlurmctld= #PropagatePrioProcess=0 #PropagateResourceLimits= #PropagateResourceLimitsExcept= #RebootProgram= ReturnToService=1 SlurmctldPidFile=/run/slurmctld.pid SlurmctldPort=6817 SlurmdPidFile=/run/slurmd.pid SlurmdPort=6818 SlurmdSpoolDir=/var/lib/slurm/slurmd SlurmUser=slurm #SlurmdUser=root #SrunEpilog= #SrunProlog= StateSaveLocation=/var/lib/slurm/slurmctld SwitchType=switch/none #TaskEpilog= TaskPlugin=task/affinity #TaskProlog= #TopologyPlugin=topology/tree #TmpFS=/tmp #TrackWCKey=no #TreeWidth= #UnkillableStepProgram= #UsePAM=0 # # # TIMERS #BatchStartTimeout=10 #CompleteWait=0 #EpilogMsgTime=2000 #GetEnvTimeout=2 #HealthCheckInterval=0 #HealthCheckProgram= InactiveLimit=0 KillWait=30 #MessageTimeout=10 #ResvOverRun=0 MinJobAge=300 #OverTimeLimit=0 SlurmctldTimeout=120 SlurmdTimeout=300 #UnkillableStepTimeout=60 #VSizeFactor=0 Waittime=0 # # # SCHEDULING #DefMemPerCPU=0 #MaxMemPerCPU=0 #SchedulerTimeSlice=30 SchedulerType=sched/backfill SelectType=select/cons_res SelectTypeParameters=CR_Core # # # JOB PRIORITY #PriorityFlags= #PriorityType=priority/basic #PriorityDecayHalfLife= #PriorityCalcPeriod= #PriorityFavorSmall= #PriorityMaxAge= #PriorityUsageResetPeriod= #PriorityWeightAge= #PriorityWeightFairshare= #PriorityWeightJobSize= #PriorityWeightPartition= #PriorityWeightQOS= # # # LOGGING AND ACCOUNTING #AccountingStorageEnforce=0 #AccountingStorageHost= #AccountingStoragePass= #AccountingStoragePort= AccountingStorageType=accounting_storage/none #AccountingStorageUser= #AccountingStoreFlags= #JobCompHost= #JobCompLoc= #JobCompPass= #JobCompPort= JobCompType=jobcomp/none #JobCompUser= #JobContainerType=job_container/none JobAcctGatherFrequency=30 JobAcctGatherType=jobacct_gather/none SlurmctldDebug=info SlurmctldLogFile=/var/log/slurm/slurmctld.log SlurmdDebug=info SlurmdLogFile=/var/log/slurm/slurmd.log #SlurmSchedLogFile= #SlurmSchedLogLevel= #DebugFlags= # # # POWER SAVE SUPPORT FOR IDLE NODES (optional) #SuspendProgram= #ResumeProgram= #SuspendTimeout= #ResumeTimeout= #ResumeRate= #SuspendExcNodes= #SuspendExcParts= #SuspendRate= #SuspendTime= # # # COMPUTE NODES NodeName=minion01 NodeAddr=192.168.1.xy1 CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 State=UNKNOWN NodeName=minion02 NodeAddr=192.168.1.xy2 CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 State=UNKNOWN NodeName=minion03 NodeAddr=192.168.1.xy3 CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 State=UNKNOWN NodeName=minion04 NodeAddr=192.168.1.xy4 CPUs=4 Sockets=1 CoresPerSocket=4 ThreadsPerCore=1 State=UNKNOWN PartitionName=all Nodes=ALL Default=YES MaxTime=INFINITE State=UP
- Remarquez que
gru
ne fait pas partie de la liste de noeuds de travail de la grappe. Si il y était, il recevrait des tâches ce qui le ralentirait pour le travail interactif. Assurez vous maintenant de copier ce fichier sur tous les RPi faisant partie de la liste des noeuds de travail. - Sur
gru
, faites les commandes suivantes:
% sudo systemctl enable slurmctld % sudo systemctl restart slurmctld
- Vous ne devriez pas voir de messages d'erreur avec la commande
systemctl status slurmctl
. Sur les noeuds de travail, on fait une tâche similaire:
% sudo systemctl enable slurmd % sudo systemctl restart slurmd
- Vérifier que le contrôleur voit les machines:
% sinfo PARTITION AVAIL TIMELIMIT NODES STATE NODELIST all* up infinite 1 idle minion01
- Si l'état (
STATE
) d'une machine est àdrain
ou àdown
, exécuter la commande suivante et refaite la commandesinfo
pour vérifier le retour à la normale:
% Sur minion01 par ex.: % sudo scontrol update nodename=minion01 state=idle
- Note: si à tout moment, un noeud “tombe” et doit être redémarré, il faut refaire cette commande en spécifiant le noeud en défaut.
- Si tout fonctionne, le commande suivante devrait vous retourner les noms de tous les noeuds de travail:
% srun -l hostname 0: minion01 1: minion02 2: minion03 3: minion04
Annexe: Installation/Utilisation de l'utilitaire sacct
- Une grappe de calcul est la plupart du temps une ressource partagée par un ensemble. Pour assurer le suivi des opérations et de l'usage fait d'une grappe, il est nécessaire d'avoir des fonctions de journalisation spécifiques aux programmes de la suite SLURM: c'est le programme
sacct
. Dans une grappe Super-Clafoutis, surtout destinée à une recherche individuelle,sacct
est aussi très utile car c'est avec lui qu'il est possible de comprendre pourquoi des tâches ne pourraient avoir été exécutées ou complétées.
- SLURM utilise MySQL comme application externe pour stocker et gérer les données sur les tâches exécutées. Une installation Impilo installe le serveur et le client MySQL mais n'en fait pas l'initialisation… Un tutoriel pour ce faire se trouve ici; essentiellement, il faut suivre les instructions présentées dans l'étape 2 du processus d'installation.
- En exécutant le script
mysql_secure_installation
, choisissez les paramètres les plus robustes tel que:- Donner un mot de passe robuste pour l'usager
root
(attention:root
de MySQL n'est pas le même queroot
du système); - Effacer l'usager
anonymous
; - Ne pas permettre de connexion externe pour
root
; - Effacer la base de données de démonstration appelée
test
.
- Les premières étapes se font dans MySQL
Commençons par créer l'usager
slurm
, qui effectuera toutes les opérations sur les bases de données de SLURM:
# On opère MySQL en tant qu'usager root de MySQL % mysql -u root -p # On entre dans MySQL et le prompt mysql> vous le démontre! # Evidemment, le mot de passe est à votre discrétion... Ici, ce n'est que pour # des fins de démonstration; vous êtes averti... mysql> CREATE USER 'slurm'@'localhost' IDENTIFIED BY 'bioubuntu'; Query OK, 0 rows affected (0.16 sec)
- Ensuite on crée les bases de données nécessaires:
mysql> create database slurm_acct_db; Query OK, 1 row affected (0.04 sec) mysql> create database slurm_job_db; Query OK, 1 row affected (0.04 sec)
- On termine la mise en place sur MySQL en donnant les permissions nécessaires à l'usager
slurm
:
mysql> grant all privileges on slurm_acct_db.* to 'slurm'@'localhost'; Query OK, 0 rows affected (0.02 sec) mysql> grant all privileges on slurm_job_db.* to 'slurm'@'localhost'; Query OK, 0 rows affected (0.03 sec)
- On installe le package
slurmdbd
:
% sudo apt install slurmdbd
- Il faut créer un fichier de configuration pour
slurmdbd
, appelé/etc/slurm/slurmdbd.conf
avec les infos suivantes:
AuthType=auth/munge AuthInfo=/var/run/munge/munge.socket.2 DbdHost=localhost StoragePort=3306 StorageUser=slurm # Evidemment, mettre celui que vous aurez choisi ci-dessus StoragePass=bioubuntu StorageType=accounting_storage/mysql StorageLoc=slurm_acct_db LogFile=/var/log/slurm/slurmdbd.log PidFile=/var/run/slurm/slurmdbd.pid SlurmUser=slurm
- Assurez-vous d'avoir les bonnes permissions:
% sudo clown root: /etc/slurm/slurmdbd.conf
- Vérifiez que ça baigne en initialisant la base de données avec
slurmdbd
% sudo slurmdbd -D -vvv # Vous allez voir plein de texte défilé pour la création des tables et l'initialisation # de MariaDB pour slurmdbd...
- Plus à venir….