Podemos configurar un cluster de alto rendimiento en Debian utilizando la interfaz de paso de mensajes LAM/MPI.
Los prerrequisitos de este tutorial es disponer de una instalación básica de debian Etch, en nuestro caso hemos usado cinco máquinas (un frontend y cuatro nodos), aisladas en una red propia que se usará tan solo para el cluster de alto rendimiento, las hemos llamado: (10.11.12.1) debian-frontend, (10.11.12.2) debian-node1, (10.11.12.3) debian-node2, (10.11.12.4) debian-node3, (10.11.12.5) debian-node4. En cada una de las máquinas hemos creado un usuario al que hemos llamado "cluster".
Una vez tengamos la instalación básica y comprobamos que tengan connectividad entre ellas y lleguen a un gateway con salida internet (para la instalación de paquetes con apt-get), procederemos a instalar el paquete build-essential en cada una de las máquinas para compilar LAM/MPI que nos descargaremos de la web oficial.
Así que en cada uno de los nodos ejecutaremos:
apt-get install build-essential
En nuestro caso no vamos a usar C++ y no necesitamos Fortran para programar en el cluster, así que no necesitaremos el compilador Fortran, eso sí le especificaremos la opción --without-fc en el configure, compilamos también el paquete en cada una de las máquinas:
tar -xzvf lam-7.1.4.tar.gz cd lam-7.1.4 ./configure --without-fc && make && make install
Una vez tenemos LAM/MPI instalado en todas las máquinas, modificaremos el archivo .bashrc del usuario cluster, que encontraremos en la home de este /home/cluster/.bashrc, al final del archivo añadiremos las siguientes líneas:
PATH=/usr/local/lam/bin:$PATH export PATH PATH=/usr/local/lam/bin:$PATH export PATH
Modificaremos en el frontend el archivo /etc/hosts donde le indicaremos donde están todos los nodos, y luego lo podemos copiar a los otros nodos:
127.0.0.1 localhost 10.11.12.1 debian-frontend 10.11.12.2 debian-node1 10.11.12.3 debian-node2 10.11.12.4 debian-node3 10.11.12.5 debian-node4
Una vez podamos localizar todos los nodos, debemos conseguir que el frontend pueda acceder usando ssh a todos los nodos sin necesidad de password, para ello nos vamos al nodo principal y ejecutaremos ssh-keygen:
ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/cluster/.ssh/id_rsa): [ENTER] Enter passphrase (empty for no passphrase): [ENTER] Enter same passphrase again: [ENTER] Your identification has been saved in /home/cluster/.ssh/id_rsa. Your public key has been saved in /home/cluster/.ssh/id_rsa.pub. The key fingerprint is: 17:4f:9b:88:55:e2:dc:25:c3:74:01:c7:49:52:08:4f cluster@debian-frontend
Copiamos la clave a todos los nodos:
scp /home/cluster/.ssh/id_rsa.pub cluster@10.11.12.2:/home/cluster/ scp /home/cluster/.ssh/id_rsa.pub cluster@10.11.12.3:/home/cluster/ scp /home/cluster/.ssh/id_rsa.pub cluster@10.11.12.4:/home/cluster/ scp /home/cluster/.ssh/id_rsa.pub cluster@10.11.12.5:/home/cluster/
Accedemos a cada uno de los nodos y guardamos la clave:
cd /home/cluster/ mkdir .ssh cat id_rsa.pub >> /home/cluster/.ssh/authorized_keys rm id_rsa.pub
Nos volvemos al frontend, y comprobamos que podemos acceder a los hosts ejecutando un comando que debería mostrar el shell en uso sin necesidad de introducir ningún password:
rsh debian-node1 -n 'echo $SHELL' /bin/bash rsh debian-node2 -n 'echo $SHELL' /bin/bash [...]
Crearemos un archivo, al que yo he llamado boot_schema donde indicaremos todos los nodos del cluster, y el número de CPUs, si tenemos SMP le indicaremos dos CPU añadiendo cpu=2 despues del nodo (por ejemplo debian-node4 cpu=2):
#Mis nodos del cluster debian-frontend debian-node1 debian-node2 debian-node3 debian-node4
Momento de arrancar el cluster, para ello le pasaremos el archivo boot_schema que creamos en el paso anterior, y si todo ha ido bien veremos algo parecido a esto:
lamboot -v -ssi boot rsh boot_schema LAM 7.1.4/MPI 2 C++/ROMIO - Indiana University n-1<6023> ssi:boot:base:linear: booting n0 (debian-frontend) n-1<6023> ssi:boot:base:linear: booting n1 (debian-node1) n-1<6023> ssi:boot:base:linear: booting n2 (debian-node2) n-1<6023> ssi:boot:base:linear: booting n3 (debian-node3) n-1<6023> ssi:boot:base:linear: booting n4 (debian-node4) n-1<6023> ssi:boot:base:linear: finished
Tenemos a nuestra disposición una suite de tests para probar nuestra instalación, pero que hay más bonito que empezar con un "Hola Mundo" en C para abrir nuestro apetito, para ello crearemos un archivo helloworld.c con el siguiente contenido, en un directorio al que he llamado test dentro de nuestra home:
#include <stdio.h> #include <mpi.h> int main(int argc, char *argv[]) { int rank, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); printf("Hello, world! I am %d of %d\n", rank, size); MPI_Finalize(); return 0; }
Lo compilamos y pasamos el ejecutable a los otros nodos:
cd /home/cluster/test mpicc helloworld.c -o helloworld rsh debian-node1 -n 'mkdir /home/cluster/test' scp hello 10.11.12.2:/home/cluster/test/ rsh debian-node2 -n 'mkdir /home/cluster/test' scp hello 10.11.12.3:/home/cluster/test/ [...]
Hora de probar, deberíamos obtener un resultado como este (aunque no necesariamente en el mismo orden):
mpirun C hello Hello, world! I am 0 of 5 Hello, world! I am 2 of 5 Hello, world! I am 1 of 5 Hello, world! I am 4 of 5 Hello, world! I am 3 of 5
Tenemos también como hemos dicho una suite de tests que nos permitiran comprobar el correcto funcionamiento de la instalación MPI:
cd /home/cluster tar -xzvf lamtests-7.1.4.tar.gz cd lamtests-7.1.4/ ./configure make make -k check 2>&1 | tee check.out
Comentarios
Muy interesante
Muy interesante el artículo. Me ha recordado a mis PFC: configurando todos los nodos, el acceso sin password,...
A ver si nos amplías en otro artículo el uso que le vais a dar en el curro, porque la verdad es que tiene muy buena pinta.
Saludos, Iván.
Un pequeño adelanto
Hola Iván,
me alegro que te resulte interesante, por tanto puedo decirte que habrá un próximo post sobre el tema. Ya adelanto que vamos a programar en Python (ese que está tan de moda ahora), ya expondré mi elección en la implementación Python-MPI, porqué y como lo he implementado.
Así que si os interesa el tema, stay tuned!
Saludos