name: inverse class: center, inverse, middle # Conteneurs pour le calcul #  #  ###### Martin Souchal 2021 (APC - FACe - ComputeOps) --- # ComputeOps - Le projet [ComputeOps](https://gitlab.in2p3.fr/CodeursIntensifs/DecaLog/-/wikis/ComputeOps) a pour objectif d'étudier les avantages des conteneurs pour les applications de type HPC. Lancé en 2018, le projet est financé par le master project DecaLog de l'IN2P3 dans le cadre du programme de R&D transverse. - Participants IN2P3 : APC, LAL, LPNHE, LLR, IPHC - Partenaires extérieurs : - Groupe de travail Aristote sur la virtualisation légère. - Ecole Centrale de Nantes - IAS - INRA - Intel - Sylabs .right[] --- # Plan - Les conteneurs : principes généraux - Les conteneurs et le HPC - Focus sur Singularity - Orchestration et Job Scheduling - Conclusion --- # Les conteneurs ### Un peu d'histoire... - Technologie apparue dans Solaris via les jails - Basé sur les kernel namespaces (kernel 2.4.19) et les cgroups (kernel 2.6.24) - LXC/LXD en 2008, Docker en 2013 - Kubernetes en 2014 chez Google - 2015 : Docker top 15 GitHub, création de l'[Open Container Initiative](https://opencontainers.org/) (OCI)
--- # Les conteneurs ### Principe de base - A l'arrêt, un conteneur est un fichier (ou un ensemble de fichiers) qui est enregistré sur un disque. - Au démarage du conteneur, le moteur décompresse les fichiers et les méta-données nécessaires, puis les transmet au noyau Linux, comme un processus normal. - Au démarage du conteneur un appel API au noyau déclenche une isolation supplémentaire (si nécessaire) et monte une copie des fichiers de l'image du conteneur. - Une fois lancés, les conteneurs ne sont un processus Linux comme un autre. --- # Open Container initiative (OCI) *Le processus de démarrage des conteneurs, ainsi que le format de l'image sur le disque, sont définis et régis par des normes.* - Gouvernance ouverte chapeautée par la Linux Foundation - Standard pour les runtimes et les images de conteneurs (pas les manifestes !) - Ligne de commande unifiée ```bash docker run example.com/org/app:v1.0.0 alias docker=podman alias docker=singularity ... ``` --- # Vocabulaire - Runtime : moteur chargé d'executer le conteneur - Image : fichier (ou un ensemble de fichiers) enregistré sur un disque - Manifeste : Fichier texte, "recette" du conteneur - Registre : un serveur abritant des images de conteneurs - Repository : ensemble de registres
.footnote[Source : Manage Docker containers, by Bachir Chihani and Rafael Benevides] --- # Manifeste - Plusieurs formats de manifestes : Dockerfile, Singularity... - Un manifeste est transformé en image via un mécanisme de build (intégré ou non) - Un conteneur peut être construit "from scratch" ou a partir d'une autre image ```yaml FROM python:3 RUN mkdir /code RUN apt-get update -q && apt-get install graphviz libgraphviz-dev libldap2-dev libsasl2-dev -yqq WORKDIR /code COPY requirements.txt /code/ RUN pip install -r requirements.txt COPY . /code/ ``` ```bash docker build Dockerfile ``` --- # Runtimes - Runtimes bas niveau : runc (docker), LXC/LXD, crun, conmon (RedHat), nvidia-docker (Nvidia) - Runtimes haut niveau : Docker, Singularity, Podman (RedHat), containerd (Docker), CR-IO (Kubernetes), enroot (Nvidia), SmartOs (Samsung) - MicroVms : KataContainer (INTEL), Firecracker (AWS), gVisor (google) - Image builder : buildah, img, orca-build...
.footnote[Source : [Alterway](https://blog.alterway.fr/le-point-sur-les-container-runtimes.html), [XataZ](https://catlife.drycat.fr/~/XataZ/la-jungle-des-conteneurs)] --- # Isolation et performances - runtimes de bas niveau en user mode (namespaces) : - Temps d'instanciation minimal - Isolation faible (proche du matériel) - Performances optimales - runtimes sécurisées (Kata, gVisor) : - Isolation forte (équivalent VM) - Temps d'instanciation modéré (plus rapide que VMs) - Performances dégradées, dépendantes hardware - Performances lièes aux formats d'images - Format en couches optimisés pour téléchargement - Format fchier optimisé pour le stockage --- # Sécurité - Docker : daemon root, possibilité d'être root dans un conteneur - Conteneurs user mode : - même utilisateur hors du conteneur et dans le conteneur - les problématiques de sécurité sont reportées sur le noyau linux - Isolation plus ou moins forte - Vecteur de failles de sécurité logicelle important - Vecteur d'attaque pour rootkit (très facile de cacher du code malicieux dans un conteneur) --- # Registres publics ### Ou trouver des images de conteneurs prêtes à l'emploi ? * Images vérifées - [NVIDIA NGC](https://ngc.nvidia.com) - images orientées GPU - [Docker Hub](https://hub.docker.com/) - images officielles * Libres - [Docker Hub](https://hub.docker.com/) - [Singularity Hub](https://singularity-hub.org/) - [Sylabs cloud](https://cloud.sylabs.io/) - images signées - [Quay.io](https://quay.io/) (scan de sécurité) --- # Registres privés ### Comment partager ses applications conteneurisées ? - Gitlab (Registre Docker) - Harbor (Registre Docker) - Singularity Hub (Registre Singularity) - Azure, AWS, etc... (OCI) - Pour stocker des images OCI dans des registres docker : [ORAS](https://github.com/deislabs/oras/)
--- # Bonnes pratiques - Partager le manifeste du conteneur avec le conteneur - Utiliser l'intégration continue pour la génération de conteneurs - Spécifier toutes les versions exactes des OS et des logiciels dans les manifestes (conda env export, pip freeze, etc....) - Taguer les images des conteneurs - Signer les conteneurs diffusés à l'aide de clés - Préferer les catalogues d'images vérifiées, ou au moins ceux qui scannent les failles de sécurité --- name: inverse class: center, inverse, middle # Les conteneurs et le HPC --- # Architecture HPC ### High Performance Computing
- Cluster/grappe de calcul - Matériel spécifique : - Utilisation d'accélérateurs (GPUs, TPUs...) - Réseau Infiniband/Omnipath - Calcul parallèle avec mémoire partagée (MPI) - Spark, hadoop... - Orchestration avec un Job Scheduler (Univa, SGE, Slurm, etc...) --- # Problématiques software HPC - Besoin de performances et d’optimisations au plus proche du matériel. - Des jobs qui tournent des semaines, voir des mois ; la maintenance doit être planifiée longtemps en avance, - Applications scientifiques parfois complexes à compiler, avec de nombreuses dépendances, - Des noyaux souvent plus vieux que d’ordinaire (nombreux soucis avec la glibc)..., - Environnement cluster = multi-utilisateurs. - Support : "J’ai besoin du logiciel X..." --- # En quoi les conteneurs peuvent nous aider dans le contexte scientifique ? * Collaboration - Diffusion et partage simple de logiciels - Portabilité des logiciels - Technologie simple à mettre en œuvre - Rapidité de mise œuvre * Répétabilité .red[*] - Assurance de répétabilité - Assurance de retrouver le même environnement - Assurance de retrouver les même résultats * Simplicité - Solution identique du laptop au meso-centre - Interface graphique .footnote[.red[*] pas de reproductibilité avec les conteneurs mais de la répétabilité !] --- # Cas d'usage pratique dans la science * Environnement de travail python prêt à l'emploi transportable sur n'importe quel cluster de calcul * Les données restent dans les espaces de travail et n'ont pas besoin d'être intégrées au conteneur * Tout ça de manière sécurisée sans avoir besoin d'être root --- # Workflow HPC - Build de l'image du conteneur sur le poste de travail, ou en CI - Test en local - Mise a disposition dans un catalogue - Execution dans un environnement HPC --- # Répétabilité * Le journal [Rescience](http://rescience.github.io/) offre la possibilité de soumettre des articles scientifiques qui se doivent d'être reproductible. * Figer l'environnement d'execution dans un conteneur et le joindre à une publication garantit la répétabilité, parfois la reproductibilité * La reproductibilité en informatique nécessite de partager un environnement logiciel *exactement identique*, mais aussi un hardware *exactement identique*.... * Executer un environnement logiciel exactement identique n'est pas garanti par l'utilisation de conteneurs. - bonnes pratiques à respecter - transparence totale - rigueur .right[] --- background-image: url(images/docker.png) # Docker et le calcul ### Un ecosystème pas très adapté... - Docker est un micro service (un conteneur, une application), pas très facile de gérer des chaines de calcul - Network namespace et compatibilité matériel réseau pour cluster (Intel OmniPath, Infiniband...) - Aucun support MPI. - Image docker : superpositions de couches, pas très portable dans un cluster - GPU Nvidia supportés par [nvidia-docker](https://github.com/NVIDIA/nvidia-docker) - Sécurité : - daemon root à installer sur tous les noeuds de calculs... - des utilisateurs root dans votre cluster... .right[] --- # Nivida docker - Permet d'utiliser des GPUs Nvidia avec Docker - Utilisable comme runtime et comme toolkit - Prérequis : kernel version > 3.10, Docker >= 19.03, NVIDIA GPU > Fermi, NVIDIA drivers ~= 361.93
.footnote[Source [NVIDIA](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/overview.html)] --- # Conteneurs orientés calcul ## 4 Conteneurs usermode compatibles HPC
Nom | Dernière Release | Support | OCI ------------- | ------------- | ------------- | ------------- [Charlie-cloud](https://github.com/hpc/charliecloud) | 18/12/2020 | MPI - GPU - IB | Non [Singularity](https://github.com/hpcng/singularity) | 12/01/2021 | MPI - GPU - IB | Oui [Shifter](https://github.com/NERSC/shifter) | 01/04/2018 | MPI - GPU - IB | Non [Nvidia enroot](https://github.com/NVIDIA/enroot) | 02/12/2020 | GPU - IB | Oui --- background-image: url(images/charlie.png) # Charlie-cloud - Développé à Los Alamos National Laboratory (LANL) - Univers docker - nécessite de modifier la configuration kernel (user.max_user_namespaces, namespace.unpriv_enable=1) - Pas de package, make install uniquement - Runtime uniquement (pas de construction d'image) - conteneurs utilisables sans droits root - un conteneur = un répertoire - Support GPU avec drivers dans le conteneur - Pas de gestion integrée du réseau - Ecrit en C, peu de ligne de code (autour de 1000) - Libre et gratuit --- background-image: url(images/shifterlogo_2.png) # Shifter - Développé au NERSC - Pas de package - Images docker converties mais ne nécessite pas docker installé - Nombreuses dépendances pour l'installation - Nécessite un Image gateway pour faire lien entre docker et shifter - utilisable sans droits root mais avec un daemon - Support GPU avec drivers dans le conteneur - Pas de gestion integrée du réseau - Documentation quasi inexistante - Ecrit en C - Libre et gratuit --- name: inverse class: center, inverse, middle # Singularity --- background-image: url(images/singu.png) # Historique * Inventé par Greg Kurtzer (CentOS, Warewulf) au Berkeley Lab pour répondre aux problèmes spécifiques au HPC * Développement démarré en Octobre 2015 * Première release en Avril 2016 * Les retours de la communauté ont menés à la version 2.0 en Juin 2016 * Sylabs.io en Janvier 2018 * Sortie de la version 3.0 en Octobre 2018 avec une réécriture complète, de nouvelles fonctionalités et une ambition hors HPC * Support officiel NVIDIA via GPU Cloud --- background-image: url(images/singu.png) # Fonctionnalités * Necessite Golang > 1.13 pour la compilation * Package RPM uniquement * Droits root nécessaires pour créer un conteneur localement * SIF est le format d'image par défaut, apportant chiffrement, signature et vérification * Fichier image unique, executable * Infrastructure Cloud (Container Library, Remote Builder, et Keystore) * Possibilité d’exécuter des images Docker et OCI * Support/isolation réseau (plugins CNI / root uniquement) * Support GPU natif avec les drivers de la machine hôte * Libre et gratuit / Version pro payante --- background-image: url(images/singu.png) # Sécurité * Support des Cgroups * L’utilisateur root peut définir un set de capabilities à l’exécution * L’administrateur peut gérer les capabilities des utilisateurs (avec précaution) * Les utilisateurs peuvent passer un contexte d’exécution SELinux, ou un profil AppArmor * Les utilisateurs peuvent passer leurs propres filtres d’appel système via seccomp * Support d’exécution avec des UID/GID différents pour l’utilisateur root * Conteneurs chiffrés (SIF) --- background-image: url(images/singu.png) # Avantages de Singularity pour le HPC - Facile à installer et à déployer sur un cluster de calcul - Compatibilité avec Docker - Utilisation de registres Public/Privé dédiés (http://www.singularity-hub.org/) - Un conteneur est facile à transporter pour l'utilisateur (un fichier à copier) - Singularity apps - Compatible tous scheduler (Dans Singularity, pas de démon, vu comme une application standard par le Job Scheduler. Compatible avec les vieux noyaux, pas de problèmes de sécurité (ou rarement). Pas de ‘cgroups‘ ; les limites sont fixées par le Job Scheduler.) - Intégration de tests et d'aide intégrée dans le conteneur - Accès direct aux GPU de la machine - Intégration dans Kubernetes --- name: inverse class: center, inverse, middle # Orchestration et scheduling --- # Orchestrateur de conteneur *Un Orchestrateur est un système permettant d'automatiser le déploiement, la mise à l'échelle et la gestion des applications conteneurisées* - Approche microservice : les conteneurs qui composent une application sont regroupés dans des unités logiques (pods) pour en faciliter la gestion et la découverte - Deux acteurs : [Kubernetes](https://kubernetes.io/) (The Linux Foundation) et [Nomad](https://www.nomadproject.io/) (Hashicorp) --- # Kubernetes * Kubernetes est orienté microservice et web * Pas de support natif d'accélérateurs (framework device plugins) * Basé sur Docker, ouvert aux runtime CRI (containerd, CRI-O, Singularity) * Pas de gestion de batch dans Kubernetes, ce qui s'en rapproche le plus est la notion de Job * Un job crée un ou plusieurs pods et s'assure qu'ils se terminent bien. Lorsqu'un pod se termine avec succès le Job l'enregistre. Quand tous les pods sont terminés, le Job est complet. Supprimer un job supprime le Pod qu'il a crée. * Le job lance un nouveau pod si un pod échoue ou est supprimé. * Possibilité de lancer plusieurs pods en parallèle (mais pas avec MPI). * Singularity-CRI est fourni avec le support natif des GPU NVIDIA en [device plugin](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)
--- # Nomad * Scheduler Hybride et multi cloud * Déployer facilement des applications conteneurisées ou pas * Infrastructure as cloud déclaratif * Binaire multi plateforme * Version 0.10, déja en production * Compatible GPU, FPGA, TPUs... * Uniquement de la gestion de cluster et scheduling * Supporte Spark
--- # Intérêt de Nomad vs Kubernetes pour le calcul * Auto rescheduling * Fédération native d'orchestrateur multi-region et multi-datacenter * Intégration parfaite avec la stack HashiCorp (Vault, Consul et Terraform...) * Intégration automatique des GPU/TPU/FPGA * Pas orienté conteneur uniquement (possibilité d'orchestrer des VMs ou des applications batchs) * Scalabilité : Kubernetes est limité a 5000 nœuds et a 100 pods par nœuds. Instances de Nomad de plus de 10 000 nœuds en production. * Entièrement et uniquement développé par des employés d'HashiCorp, en open source. * Compatible Linux, MacOs et Windows (Kubernetes n'est supporté que sur Linux) * Binaire de 75Mb (pour client et serveur).
--- # Désavantages de Nomad : * Kubernetes fournit tous les services necessaires pour faire tourner des conteneurs Docker or Rkt-based (cluster management, scheduling, service discovery, monitoring, secrets management, ...). * Nomad est développé par une seule entité, HashiCorp et n'a pas de support communautaire. * Définition des ressources manuelle * Auto scaling pas encore disponible * Développement très rapide, avec une certaine tendance à la dépréciation sauvage et sans préavis * Un certains nombre de fonctionnalités payantes
--- # Job scheduler - Approche Job avec heure de début - fin, ressources à utiliser - mécanismes de files d’attente/de mises en attente ou pause (checkpointing), de priorités / Fair sharing, droits/accès et partages des ressources physiques. - Intégration dans l’environnement cluster existant --- # Conclusion --- # Questions ---