Construire son cluster HPC

Magazine
Marque
GNU/Linux Magazine
Numéro
185
Mois de parution
septembre 2015
Spécialité(s)


Résumé
Un cluster HPC (Haute Performance de Calcul) peut être vu comme un ensemble de machines coopérants pour résoudre un problème non soluble dans un temps raisonnable par une machine seule. Nous allons voir comment créer un cluster sous Linux en utilisant des logiciels libres.

Body


L'objectif

L'objectif est de construire un cluster HPC basé sur des logiciels libres. Nous considérons que les services usuels sont installés et opérationnels (notamment DNS, répertoires utilisateurs distribués et service d'annuaires pour les comptes systèmes). Voici la topologie cible :

topo-clust

L'utilisateur se connecte à un nœud frontal (login) où il trouve son environnement ainsi que sa home montée via un système de fichiers distribué sur l'ensemble du cluster. Tous les programmes sont compilés sur le frontal. L'utilisateur interagit ensuite avec un job scheduler localisé sur le nœud d'administration (admin) via un jeu de commandes installé sur le nœud frontal pour demander la réalisation de ses calculs. Le job scheduler distribue ensuite le travail sur les nœuds de calcul (compute1 et compute2). L'utilisateur ne peut donc pas se connecter en direct sur les nœuds de calcul. Il doit décrire les ressources qu'il demande (nombre de CPU, de nœuds, quantité de mémoire etc.) ainsi que la façon de lancer ses calculs (exécutable, script, variables d’environnements etc.). C'est ce qu'on appelle un « job ».

Les outils

L'installation de notre cluster va se faire au-dessus d'une Debian Jessie. Nous allons détailler quatre composants :

- Kanif : propagation de commandes sur la machine;

- SLURM : job scheduler libre;

- OpenMP et OpenMPI : librairies incontournables dans le domaine du calcul.

Phase 1 : Kanif

Kanif propose deux commandes très utiles pour administrer un cluster HPC :

- kash qui exécute une commande sur un ensemble de machine ;

- kaput qui copie des fichiers / répertoires depuis une source sur un ensemble de machines.

L'installation se fait très simplement via le gestionnaire de paquet Debian :

root@login:~# apt-get install kanif

Il faut ensuite avoir une authentification par clé SSH fonctionnelle. Cette authentification se fait depuis le compte root du nœud frontal vers les comptes root des nœuds de calcul. Côté nœuds de calcul, il faut juste installer TakTuk :

root@compute1:~# apt-get install taktuk

Testons :

root@login:~# kash -n compute[1-2] hostname

--------------------------------------------------------------------------------

STDOUT

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

compute[1-2] (2 HOST)

--------------------------------------------------------------------------------

compute1

compute2

La commande hostname s'est bien exécutée sur compute1 et compute2 depuis le nœud de login.

Phase 2 : SLURM

SLURM est un job scheduler. Son rôle est de maintenir une image aussi précise que possible de l'état d'utilisation des ressources sur le cluster. Il se base sur cette image pour placer les jobs des utilisateurs en fonction des ressources libres.

process

L'utilisateur se connecte au nœud frontal et utilise la commande srun ou sbatch pour envoyer un job sur le cluster. Ces deux commandes sont respectivement utilisées pour le mode interactif et batch, nous y reviendrons. Une connexion à un service slurmctld en exécution sur le nœud d'administration est réalisée. Ce service connaît la topologie du cluster ainsi que l'état d'utilisation des ressources. Si les ressources demandées par l'utilisateur sont libres, slurmctld demande au(x) service(s) slurmd de(s) noeud(s) de calcul(s) réservé(s) d’exécuter le job.

Le service slurmd accepte la requête du service slurmctld et fork immédiatement un processus slurmstepd qui va manager la consommation de ressources du job ainsi que ses entrées / sorties. Le job est un processus fils de slurmstepd exécuté sous l'identité de l'utilisateur (setuid). Pour installer SLURM, la première chose à faire est de créer un utilisateur système dédié consistant sur le réseau (c'est à dire avec le même UID partout).

root@login:~# useradd -d /var/slurm -r -u 600 -U slurm

Il faut ensuite créer tous les répertoires nécessaires à SLURM sur tous les nœuds du cluster :

root@login:~# mkdir -p /var/slurm/slurmd && mkdir /var/slurm/slurmctld && chown -R slurm:slurm /var/slurm

root@login:~# mkdir /var/log/slurm && chown -R slurm:slurm /var/log/slurm

Ces deux opérations doivent être répétées pour le nœud d'administration et les nœuds de calculs. Les communications entre slurmctld et slurmd sont authentifiées avec Munge (clé privée partagée par les nœuds). Il faut donc installer Munge sur tous les nœuds du cluster :

root@login:~# apt-get install munge

Et distribuer la clé privée :

root@login:~# kaput -n compute[1-2] /etc/munge/munge.key /etc/munge

root@login:~# scp /etc/munge/munge.key root@admin:/etc/munge

Le système est prêt à accueillir SLURM. Il reste juste à installer les librairies de développement de Munge sur le nœud frontal pour pouvoir compiler le support de Munge dans SLURM :

root@login:~# apt-get install libmunge-dev

Passons à la compilation de SLURM :

root@login:~# bunzip2 slurm-14.11.7.tar.bz2 && tar -xvf slurm-14.11.7.tar && cd slurm-14.11.7

root@login:~/slurm-14.11.7# ./configure –prefix=/usr/local/compiled/slurm-14.11.7

root@login:~/slurm-14.11.7# ln -s /usr/local/compiled/slurm-14.11.7 /usr/local/compiled/slurm

root@login:~/slurm-14.11.7# make && make install

J'aime installer mes programmes compilés bien à part. Vous pouvez tout à fait choisir un autre préfixe. SLURM sera donc installé dans /usr/local/compiled/slurm. On réplique l'installation sur les nœuds de calcul et le nœud d'admin en y copiant le répertoire /usr/local/compiled/slurm-14.11.7 et en réalisant le lien.

On rédige ensuite un fichier minimal de configuration qui est partagé à la fois par les outils clients srun et sbatch, slurmctld et slurmd. Ce fichier doit être identique sur tous les nœuds du cluster :

ClusterName=magi

ControlMachine=admin

SlurmUser=slurm

AuthType=auth/munge

MailProg=/usr/bin/mail

MpiParams=ports=12000-12999

SlurmdDebug=debug

StateSaveLocation=/var/slurm/slurmctld

SlurmdSpoolDir=/var/slurm/slurmd

SlurmctldPidFile=/var/run/slurmctld.pid

SlurmdPidFile=/var/run/slurmd.pid

SlurmdLogFile=/var/log/slurm/slurmd.log

SlurmctldLogFile=/var/log/slurm/slurmctld.log

SlurmdTimeout=600

TmpFS=/scratch

NodeName=compute[1-2] Procs=8 State=UNKNOWN

PartitionName=COMPUTE Nodes=magi6 Default=YES MaxTime=INFINITE State=UP Shared=YES

Ce fichier définit le nom du cluster (ClusterName), la machine où tourne slurmctld (ControlMachine), l'utilisateur système associé à slurmctld (SlurmchrUser) et le type d’authentification (AuthType). Ensuite viennent les paramètres propres à chaque service. Pour slurmd : MpiParams fixe les ports réseau utilisés pour les communications MPI (nous y reviendrons), SlurmdSpoolDir donne l'emplacement des fichiers d'état des jobs sur la machine, Slurm[Pid|Log]File sont équivoques et SlurmdTimeout fixe le temps de non-réponse au-delà duquel un nœud de calcul est jugé down par slurmctld. Pour slurmctld : StateSaveLocation fixe l'emplacement des fichiers contenant l'affectation des ressources sur le cluster. Slurmctld[Pid|Log]File sont également équivoques. Le mode debug est activé pour voir si l’exécution des services slurmctld et slurmd est exempte de toute erreur.

Les deux dernières lignes renseignent la topologie du cluster. La première décrit les nœuds de calcul au niveau physique (CPU, mémoire, technologie d'interconnexion etc.). Ici il s'agit de deux machines compute1 et compute2 équipées chacune de 8 cœurs. La seconde ligne instancie ce que l'on appelle une partition. Une partition peut être vue comme un groupe de machine partageant des caractéristiques communes. Nous pourrions avoir une partition pour les machines sur base Intel, une autre pour les IBM Blue Gene, une autre encore pour les GPU etc. L'utilisateur choisit alors de lancer ses jobs sur l'une ou l'autre des partitions. Ici nous avons une partition COMPUTE contenant les machines compute1 et compute2. Les machines doivent obligatoirement être décrite via la directive NodeName avant d'intégrer une partition. Une machine ne peut pas être dans plusieurs partitions.

Ce fichier de configuration est installé dans /usr/local/compiled/slurm/etc/slurm.conf sur tous les nœuds. Il nous faut maintenant rédiger les scripts de démarrage pour le très controversé systemd. Il va falloir en faire un pour slurmctld sur le nœud d'administration et un autre pour slurmd sur les nœuds de calcul. Commençons par slurmctld en créant /lib/systemd/system/slurmctld.service :

[Unit]

Description=Slurmctld

After=syslog.target

[Service]

Type=forking

ExecStart=/usr/local/compiled/slurm/sbin/slurmctld -f /usr/local/compiled/slurm/etc/slurm.conf

[Install]

WantedBy=multi-user.target

On notera qu'avec l'ajout du paramètre -D la commande affectée à ExecStart peut être utilisée sur le terminal pour débugger le lancement de slurmctld. Activons et démarrons le service :

root@admin:~# systemctl enable slurmctld.service

root@admin:~# service slurmctld start

Testons qu'il soit en exécution :

root@admin:~# netstat -laputn -A inet | grep slurmctld

tcp        0      0 0.0.0.0:6817            0.0.0.0:*               LISTEN      1421/slurmctld

On trouve bien un processus slurmctld en écoute sur le port TCP 6817. Je vous recommande en complément d'aller voir dans les logs /var/log/slurm/slurmctld.log pour traquer d'éventuels warnings.

La même manipulation doit être réalisée sur les nœuds de calcul pour slurmd. Vous pourrez vérifier la disponibilité réseau du service slurmd en combinant kash et netstat. À ce stade, SLURM est opérationnel et prêt à recevoir du travail. Reconnectons-nous en simple utilisateur et fixons quelques variables d’environnements pour localiser le fichier de configuration et les exécutables de SLURM :

nico@login:~$ export SLURM_CONF=/usr/local/compiled/slurm/etc/slurm.conf

nico@login:~$ export PATH=/usr/local/compiled/slurm/bin:$PATH

Commençons par vérifier l'état du cluster avec un sinfo :

nico@login:~$ sinfo

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST

COMPUTE*     up   infinite      2   down compute[1-2]

Nous voyons que les deux machines de la partition COMPUTE sont down. C'est normal car elles viennent d'être ajoutées dans le cluster. Passons les en idle (qui est l'état dans lequel les nœuds attendent du travail) avec la commande scontrol :

nico@login:~$ sudo scontrol update nodename=compute[1-2] state=idle

Vérifions l'état de la partition :

nico@login:~$ sinfo

PARTITION AVAIL  TIMELIMIT  NODES  STATE NODELIST

COMPUTE*     up   infinite      2   idle compute[1-2]

Les deux nœuds sont en idle nous pouvons lancer notre premier job. Nous allons utiliser la commande srun qui soumet un job à SLURM et en affiche les sorties sur la sortie standard du terminal :

nico@login:~$ srun -N 2 hostname

compute1

compute2

Dans cet exemple, l'utilisateur demande de lancer la commande hostname sur deux nœuds la partition par défaut (COMPUTE). Le service slurmctld demande donc aux services slurmd de compute1 et compute2 de s’exécuter et les résultats sont envoyés sur la sortie standard de l'utilisateur. Le terminal de l'utilisateur est donc bloqué le temps de l’exécution du job. C'est ce qu'on appelle le mode interactif. Nous verrons un peu plus loin comment utiliser le mode batch pour soumettre un job et relâcher la session de l'utilisateur en redirigeant les sorties.

Phase 3 : OpenMP

Nous avons maintenant un cluster opérationnel. Nous allons voir les deux librairies de parallélisation stars du  domaine du HPC : OpenMP et OpenMPI. OpenMP est une surcouche du multithreading dans le sens où elle permet de paralléliser des boucles très simplement via des pragmas ajoutés au code source. OpenMP est clairement orienté programmation à mémoire partagée (c'est à dire que la mémoire doit être accessible aux différents fils d’exécution du programme compilé avec OpenMP), ce qui cantonne le programme à une machine isolée (même s'il existe des systèmes à image unique, mais c'est une autre histoire !). Voici un code OpenMP très simple :

#include <utmpx.h>

int main (int argc, char *argv[]) {

   int nthreads, thread_id;

   #pragma omp parallel private(nthreads, thread_id) {

      thread_id = omp_get_thread_num();

      printf("Thread %d says: Hello World on core %i\n", thread_id,sched_getcpu());

      if (thread_id == 0) {

         nthreads = omp_get_num_threads();

         printf("Thread %d reports: the number of threads are %d\n",

                        thread_id, nthreads); } }

  return 0; }

Ce code crée N fils d’exécution au niveau du pragma omp parallel et affiche le numéro du processeur sur lequel le code du fil s'est exécuté. Commençons par le compiler en ajoutant la directive -fopenmp à une compilation classique :

nico@login:~$ gcc -fopenmp testomp.c -o testomp

Pour exécuter ce code, il est nécessaire de spécifier combien de fils d’exécution sont requis. Cela se fait au moyen de la variable d’environnement OMP_NUM_THREADS. Nous la fixons et exécutons le programme dans la foulée :

nico@login:~$ export OMP_NUM_THREADS=4

nico@login:~$ ./testomp

Thread 1 says: Hello World on core 2

Thread 0 says: Hello World on core 3

Thread 0 reports: the number of threads are 4

Thread 2 says: Hello World on core 5

Thread 3 says: Hello World on core 4

Nous voyons bien les quatre fils d’exécution et que chaque fil est localisé sur un cœur différent. L'affectation des fils sur les cœurs est laissée à la discrétion de l’ordonnanceur du noyau Linux. Lançons maintenant ce programme sur notre cluster :

nico@login:~$ srun -N 1 ./testomp

Thread 0 says: Hello World on core 2

Thread 0 reports: the number of threads are 4

Thread 3 says: Hello World on core 1

Thread 2 says: Hello World on core 0

Thread 1 says: Hello World on core 3

Sans surprise nous retrouvons le même genre de sortie. On notera que la variable d’environnement OMP_NUM_THREADS a été propagée sur le nœud de calcul choisi à l’exécution.

Phase 4 : OpenMPI

Par opposition à OpenMP, OpenMPI est utilisé dans les infrastructures à mémoire distribuée. OpenMPI crée une infrastructure de communication au-dessus du réseau physique (Ethernet, Infiniband etc.) qui abstrait le réseau au niveau du programmeur. Celui-ci peut alors déployer des processus MPI un peu partout sur l'infrastructure sans se soucier du placement ou de la gestion des connexions entre les différentes machines de son infrastructure. Nous allons récupérer les sources du dernier OpenMPI stable, les compiler et les installer dans /usr/local/compiled/openmpi. On notera qu'il existe une option de compilation --with-slurm qui optimise les performances de OpenMPI lorsque celui-ci est utilisé avec SLURM.

root@login:~# wget http://www.open-mpi.org/software/ompi/v1.8/downloads/openmpi-1.8.5.tar.gz

root@login:~# tar -xvzf openmpi-1.8.5.tar.gz && cd  openmpi-1.8.5

root@login:~/openmpi-1.8.5# ./configure --prefix=/usr/local/compiled/openmpi-1.8.5 --with-slurm

root@login:~/openmpi-1.8.5# make && make install

root@login:~/openmpi-1.8.5# ln -s /usr/local/compiled/openmpi-1.8.5 /usr/local/compiled/openmpi

Il faut également ajouter les librairies OpenMPI dans le cache des librairies sur le nœud frontal :

root@login:~# echo '/usr/local/compiled/openmpi' > /etc/ld.co.conf.d/hpc.conf

root@login:~# ldconfig

root@login:~# ldconfig -p | grep -i mpi

Il faut répéter cette manipulation sur les nœuds de calcul. C'est bien utile kash non ?

Voici un petit programme qui crée simplement des processus MPI qui affichent un « Hello world » et la machine depuis laquelle ils nous font leur petit coucou :

#include <stdio.h>

#include <mpi.h>

int main (argc, argv) {

  int rank, size;

  char hostname[40];

  MPI_Init (&argc, &argv);

  MPI_Comm_rank (MPI_COMM_WORLD, &rank);

  MPI_Comm_size (MPI_COMM_WORLD, &size);

  gethostname(hostname,40);

  printf( "Hello world from process %d of %d at %s\n", rank, size, hostname );

  MPI_Finalize();

  return 0 ; }

Repassons en simple utilisateur pour tester ce programme. Commençons par fixer le PATH afin d'avoir les exécutables OpenMPI. La compilation des programmes OpenMPI se fait avec mpicc qui est un wrapper autour de gcc avec les bonnes librairies et les includes positionnés.

nico@login:~$ export PATH=/usr/local/compiled/openmpi/bin:$PATH

nico@login:~$ mpicc testmpi.c -o testmpi

Pour exécuter un programme OpenMPI, il faut s'appuyer sur le lanceur mpiexec :

nico@login:~$ mpiexec -n 4 ./test mpi

Hello world from process 0 of 4 at login

Hello world from process 1 of 4 at login

Hello world from process 2 of 4 at login

Hello world from process 3 of 4 at login

Nous voulons créer quatre processus MPI (-n 4) qui exécutent le programme. Ce programme affiche le rang (identifiant) du processus et sort. C'est par le rang que les processus communiquent entre eux. Par exemple on pourrait avoir un programme qui est organisé de la manière suivante :

  • si je suis le processus de rang  , je découpe mon jeu de données en N-1 parties et j'envoie la partie 1 au processus de rang 1, la partie 2 au processus de rang 2 etc.
  • si je suis le processus de rang N j'attends mon jeu de données provenant du processus de rang  , je le traite et le renvoie au processus de rang  .

Nous voyons que ce type de programmation ne fait pas apparaître de notion d'IP, port, socket etc. La couche réseau est abstraite. Lançons le même programme par le job scheduler. Cette fois-ci le programme OpenMPI va s’exécuter sur les nœuds de calcul :

nico@login:~$ srun --resv-ports --mpi=pmi2 -n 4 ./testmpi

Hello world from process 1 of 4 at compute1

Hello world from process 2 of 4 at compute1

Hello world from process 0 of 4 at compute1

Hello world from process 3 of 4 at compute1

Tous est exécuté sur le nœud compute1 car celui-ci a suffisamment de cœurs libres pour encaisser les quatre processus MPI. Cependant en jouant avec les paramètres de réservation de ressource de SLURM il est possible de changer ce comportement :

nico@login:~$ srun --resv-ports --mpi=pmi2 -N 2 --ntasks-per-node=2 ./testmpi

Hello world from process 1 of 4 at compute1

Hello world from process 0 of 4 at compute2

Hello world from process 2 of 4 at compute2

Hello world from process 3 of 4 at compute1

Cette fois ci, l’exécution du programme est distribuée sur plusieurs nœuds de calcul car nous lui demandons deux nœuds (-N 2) et surtout deux tâches par nœud (--ntasks-per-node=2). Si nous n'avions pas précisé le nombre de tâches par nœud et juste réservé deux nœuds, SLURM aurait tout mis sur le même car c'est plus intéressant de tout avoir sur la même machine s'il y a suffisamment de cœurs libres.

Résultat : Job en mode batch

Le fonctionnement en mode batch demande à l'utilisateur de rédiger un script de soumission. C'est de cette manière qu'il faut utiliser un cluster HPC. Ce script contient deux sections : les ressources demandées et la façon de lancer le programme. Les variables destinées à SLURM sont précédées d'un #SBATCH.

#!/bin/bash

#SBATCH --job-name=hello

#SBATCH --output=slurm.out

#SBATCH --error=slurm.err

#SBATCH --mail-type=end

#SBATCH --mail-user=nicolas.greneche@univ-paris13.fr

#SBATCH --nodes=2

#SBATCH --ntasks-per-node=2

srun --resv-ports --mpi=pmi2 ./testmpi

Dans cet exemple, un nom est donné au job (--job-name) un fichier de sortie standard et erreur est spécifié (--output et --error), une notification mail de fin de job est placée (--mail-type et --mail-user) et enfin les ressources demandées sont décrites (--nodes et --ntasks-per-node). Il ne nous reste plus qu'à soumettre ce job via la commande sbatch :

nico@login:~$ sbatch run.slurm

Submitted batch job 164515

Le job scheduler nous renvoi un JOBID. La commande squeue permet de vérifier l'état de la file d'attente des jobs :

nico@login:~$ squeue

  JOBID PARTITION     NAME     USER  ST       TIME  NODES NODELIST(REASON)

 164515   COMPUTE    hello     nico   R 0-00:01:25      2 compute[1-2]

Nous voyons notre job en exécution (ST=R) sur la partition COMPUTE. Voyons la sortie du fichier slurm.out :

nico@login:~$ cat slurm.out

Hello world from process 0 of 4 at compute1

Hello world from process 2 of 4 at compute2

Hello world from process 1 of 4 at compute1

Hello world from process 3 of 4 at compute2

Sans surprise nous retrouvons le même genre de sortie qu'avec srun.




Article rédigé par

Par le(s) même(s) auteur(s)

Intégration d’ownCloud pour servir un partage de fichiers existant

Magazine
Marque
Linux Pratique
Numéro
136
Mois de parution
mars 2023
Spécialité(s)
Résumé

Le logiciel libre ownCloud est une solution de partage et de stockage des fichiers en mode web. Avec la profusion des plateformes commerciales de ce type (Google Drive, iCloud, Dropbox, etc.), l’accès web aux fichiers est devenu le nouveau standard. Dans cet article, nous allons explorer une méthode pour interfacer cette méthode d’accès aux fichiers avec un serveur NFS (Network File System) existant.

Équilibrage de charge avec IPVS

Magazine
Marque
Linux Pratique
HS n°
Numéro
55
Mois de parution
octobre 2022
Spécialité(s)
Résumé

IP Virtual Server (IPVS) est un équilibreur de charge agissant au niveau 4 du modèle OSI. Il est implémenté sous forme d’un module noyau s’appuyant sur le framework Netfilter, ce qui le rend efficace sur l’équilibrage des services par rapport à leurs ports TCP/UDP, mais totalement agnostique aux protocoles applicatifs transportés (LDAP, HTTP, etc.).

Libre-service de machines virtuelles avec OpenNebula

Magazine
Marque
Linux Pratique
Numéro
130
Mois de parution
mars 2022
Spécialité(s)
Résumé

Dans un article précédent, nous avons mis en place une infrastructure OpenNebula basique [1]. Nous allons maintenant configurer cette plateforme pour proposer aux utilisateurs un guichet de libre-service de machines virtuelles. L’idée est que les utilisateurs puissent créer eux-mêmes leurs machines virtuelles.

Les derniers articles Premiums

Les derniers articles Premium

Sécurisez vos applications web : comment Symfony vous protège des menaces courantes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les frameworks tels que Symfony ont bouleversé le développement web en apportant une structure solide et des outils performants. Malgré ces qualités, nous pouvons découvrir d’innombrables vulnérabilités. Cet article met le doigt sur les failles de sécurité les plus fréquentes qui affectent même les environnements les plus robustes. De l’injection de requêtes à distance à l’exécution de scripts malveillants, découvrez comment ces failles peuvent mettre en péril vos applications et, surtout, comment vous en prémunir.

Bash des temps modernes

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Les scripts Shell, et Bash spécifiquement, demeurent un standard, de facto, de notre industrie. Ils forment un composant primordial de toute distribution Linux, mais c’est aussi un outil de prédilection pour implémenter de nombreuses tâches d’automatisation, en particulier dans le « Cloud », par eux-mêmes ou conjointement à des solutions telles que Ansible. Pour toutes ces raisons et bien d’autres encore, savoir les concevoir de manière robuste et idempotente est crucial.

Présentation de Kafka Connect

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Un cluster Apache Kafka est déjà, à lui seul, une puissante infrastructure pour faire de l’event streaming… Et si nous pouvions, d’un coup de baguette magique, lui permettre de consommer des informations issues de systèmes de données plus traditionnels, tels que les bases de données ? C’est là qu’intervient Kafka Connect, un autre composant de l’écosystème du projet.

Le combo gagnant de la virtualisation : QEMU et KVM

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

C’est un fait : la virtualisation est partout ! Que ce soit pour la flexibilité des systèmes ou bien leur sécurité, l’adoption de la virtualisation augmente dans toutes les organisations depuis des années. Dans cet article, nous allons nous focaliser sur deux technologies : QEMU et KVM. En combinant les deux, il est possible de créer des environnements de virtualisation très robustes.

Les listes de lecture

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.
11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.
10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Voir les 125 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous