De nodos virtuales WCG (KVM) a Dockers + Docker Swarm

por | noviembre 15, 2018

Hace ya un tiempo que monté unos nodos (virtualizados en KVM) con el cliente Boinc para contribuir a proyectos en World Community Grid. Buscando información sobre dockers y Boinc acabé dando con un repo de GitHub del propio proyecto donde explican cómo echar a correr el cliente en un contenedor Docker. Por tanto el paso siguiente que vamos a ver ahora es cómo montar estos 3 clientes Boinc (que actualmente son 3 máquinas virtuales) en una sóla máquina virtual ejecutando cada cliente en un contenedor.

Nodos KVM ejecutando el cliente Boinc

Nodos KVM ejecutando el cliente Boinc

En mi caso he creado una máquina virtual nueva con tres particiones que servirán para guardar los datos que genere cada contenedor:

/opt/appdata/boinc_node1
/opt/appdata/boinc_node2
/opt/appdata/boinc_node3

Ahora ejecutamos el contenedor. Se descargará la imagen si no la teníamos todavía. En KEY ponemos el código asignado a nuestra cuenta de proyectos en WCG:

docker run -d \
  --name boinc_node1 \
  --net=host \
  -v /opt/appdata/boinc_node1:/var/lib/boinc-client \
  -e BOINC_CMD_LINE_OPTIONS="--attach_project http://www.worldcommunitygrid.org <KEY>" \
  boinc/client

Comprobamos que se esté ejecutando el contenedor con docker ps:

root@mid-dockers:/opt/appdata/boinc# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
fcc729bf4fee        boinc/client        "start-boinc.sh"    4 minutes ago       Up 4 minutes                            boinc_node1

Vemos los logs del contenedor de la siguiente manera con docker logs -f boinc_node1

14-Nov-2018 19:59:07 [---] cc_config.xml not found - using defaults
14-Nov-2018 19:59:07 [---] Starting BOINC client version 7.12.0 for x86_64-pc-linux-gnu
14-Nov-2018 19:59:07 [---] log flags: file_xfer, sched_ops, task
14-Nov-2018 19:59:07 [---] Libraries: libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
14-Nov-2018 19:59:07 [---] Data directory: /var/lib/boinc-client
14-Nov-2018 19:59:07 [---] No usable GPUs found
14-Nov-2018 19:59:07 [---] [libc detection] gathered: 2.27, Ubuntu GLIBC 2.27-3ubuntu1
14-Nov-2018 19:59:07 [---] Host name: mid-dockers
14-Nov-2018 19:59:07 [---] Processor: 2 GenuineIntel Westmere E56xx/L56xx/X56xx (Nehalem-C) [Family 6 Model 44 Stepping 1]
14-Nov-2018 19:59:07 [---] Processor features: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt aes hypervisor lahf_lm kaiser arat
14-Nov-2018 19:59:07 [---] OS: Linux Ubuntu: Ubuntu 18.04.1 LTS [4.4.0-130-generic|libc 2.27 (Ubuntu GLIBC 2.27-3ubuntu1)]
14-Nov-2018 19:59:07 [---] Memory: 3.86 GB physical, 980.00 MB virtual
14-Nov-2018 19:59:07 [---] Disk: 18.15 GB total, 9.25 GB free
14-Nov-2018 19:59:07 [---] Local time is UTC +0 hours
14-Nov-2018 19:59:07 [---] Config: GUI RPC allowed from any host
14-Nov-2018 19:59:07 [---] Config: GUI RPCs allowed from:
14-Nov-2018 19:59:07 [---]     127.0.0.1

Con el tiempo deberíamos ver en los logs que comienzan a descargarse y procesarse ficheros de los proyectos a los que estamos suscritos:

...
14-Nov-2018 20:02:13 [World Community Grid] Finished download of fahb_image02_7.28.tga
14-Nov-2018 20:02:13 [World Community Grid] Finished download of fahb_image04_7.28.tga
14-Nov-2018 20:02:13 [World Community Grid] Started download of fahb_image05_7.28.tga
14-Nov-2018 20:02:13 [World Community Grid] Started download of fahb_image06_7.28.tga
14-Nov-2018 20:02:15 [World Community Grid] Finished download of fahb_image05_7.28.tga
14-Nov-2018 20:02:15 [World Community Grid] Finished download of fahb_image06_7.28.tga
14-Nov-2018 20:02:15 [World Community Grid] Started download of fahb_image07_7.28.tga
14-Nov-2018 20:02:15 [World Community Grid] Started download of fahb_image08_7.28.tga
14-Nov-2018 20:02:18 [World Community Grid] Finished download of fahb_image07_7.28.tga
14-Nov-2018 20:02:18 [World Community Grid] Started download of fahb_image09_7.28.tga
14-Nov-2018 20:02:19 [World Community Grid] Finished download of fahb_image08_7.28.tga
14-Nov-2018 20:02:19 [World Community Grid] Finished download of fahb_image09_7.28.tga
...

Añadiendo más contenedores

Iniciamos el segundo contenedor especificando la ruta de datos. Tambiénd debemos tener en cuenta que debemos cambiar el puerto RPC utilizado por el cliente o bien deshabilitar directamente el acceso al cliente por RCP con la opción --no_gui_rpc

docker run -d \
  --name boinc_node2 \
  --net=host \
  -v /opt/appdata/boinc_node2:/var/lib/boinc-client \
  -e BOINC_CMD_LINE_OPTIONS="--attach_project http://www.worldcommunitygrid.org <KEY> \
  --gui_rpc_port 31417" \
  boinc/client

Comprobamos los contenedores que están corriendo:

root@mid-dockers:/opt/appdata/boinc# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
333253a4b260        boinc/client        "start-boinc.sh"    4 seconds ago       Up 2 seconds                            boinc_node2
4a0e945d4256        boinc/client        "start-boinc.sh"    34 seconds ago      Up 33 seconds                           boinc_node1

Para el tercer contenedor que nos queda procederíamos de la misma manera.

Un paso más con Docker Swarm

Podemos iniciar tantos contenedores como necesitemos (y podamos) pero podemos ir más allá y crear contenedores con Docker Swarm. De esta manera creamos tantas réplicas de un contenedor de una forma mucho más rápida, clara y escalable.

En primer lugar inicializamos swarm:

root@mid-dockers:/opt/appdata/boinc# docker swarm init
Swarm initialized: current node (5oi5gd2y8za6wiwogzjxvoifj) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-6a5cvn2cfwevgazeew02f0vkb1pzppx8rs9yerggs29qzzvvq4-aik4oryh7pkmjw9uo5356vim6 192.168.1.154:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Creamos la red:

root@mid-dockers:/opt/appdata/boinc# docker network create -d overlay --attachable boinc
5et9iuo7hhd03esdgg4dq55sm

En mi caso tenía 3 nodos WCG, cada uno con un cliente realizando cálculos computacionales para los distintos proyectos a los que estoy suscrito, así que inicio 3 réplicas en el swarm:

root@mid-dockers:/opt/appdata/boinc# docker service create \
>   --replicas 3 \
>   --name boinc \
>   --network=boinc \
>   -p 31416 \
>   -e BOINC_CMD_LINE_OPTIONS="--attach_project http://www.worldcommunitygrid.org <KEY>" \
>   boinc/client
mlbvtr2vbi8etafh4ec8yf6ai
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

Estado de los contenedores activos con docker ps, como hacíamos antes:

root@mid-dockers:/opt/appdata/boinc# docker ps
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS               NAMES
6ea923b517de        boinc/client:latest   "start-boinc.sh"    39 seconds ago      Up 38 seconds       31416/tcp           boinc.3.aub53kx6oqoze7aujhy94j084
e868c7fc5e6b        boinc/client:latest   "start-boinc.sh"    39 seconds ago      Up 37 seconds       31416/tcp           boinc.1.b9pv1siuykgt7h0a185n86qb8
638ba0723774        boinc/client:latest   "start-boinc.sh"    39 seconds ago      Up 38 seconds       31416/tcp           boinc.2.cvwx2wtoymh1k9a4ry6kh8axr

Los logs los vemos en cada contenedor. Podemos acceder por el nombre del contenedor o el ID. Por ejemlo en boinc.1.b9pv1siuykgt7h0a185n86qb8

root@mid-dockers:/opt/appdata/boinc# docker logs -f boinc.1.b9pv1siuykgt7h0a185n86qb8
14-Nov-2018 21:16:03 [---] Starting BOINC client version 7.12.0 for x86_64-pc-linux-gnu
14-Nov-2018 21:16:03 [---] log flags: file_xfer, sched_ops, task
14-Nov-2018 21:16:03 [---] Libraries: libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
14-Nov-2018 21:16:03 [---] Data directory: /var/lib/boinc-client
14-Nov-2018 21:16:03 [---] No usable GPUs found
14-Nov-2018 21:16:03 [---] Creating new client state file
14-Nov-2018 21:16:03 [---] [libc detection] gathered: 2.27, Ubuntu GLIBC 2.27-3ubuntu1
14-Nov-2018 21:16:03 [---] Host name: e868c7fc5e6b
14-Nov-2018 21:16:03 [---] Processor: 2 GenuineIntel Westmere E56xx/L56xx/X56xx (Nehalem-C) [Family 6 Model 44 Stepping 1]
14-Nov-2018 21:16:03 [---] Processor features: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic popcnt aes hypervisor lahf_lm kaiser arat
14-Nov-2018 21:16:03 [---] OS: Linux Ubuntu: Ubuntu 18.04.1 LTS [4.4.0-130-generic|libc 2.27 (Ubuntu GLIBC 2.27-3ubuntu1)]
14-Nov-2018 21:16:03 [---] Memory: 3.86 GB physical, 980.00 MB virtual
14-Nov-2018 21:16:03 [---] Disk: 18.15 GB total, 8.59 GB free
14-Nov-2018 21:16:03 [---] Local time is UTC +0 hours
14-Nov-2018 21:16:03 [---] Config: GUI RPCs allowed from:
14-Nov-2018 21:16:03 [---]     127.0.0.1
14-Nov-2018 21:16:03 [---] Last benchmark was 17849 days 21:16:03 ago
14-Nov-2018 21:16:03 [http://www.worldcommunitygrid.org/] URL http://www.worldcommunitygrid.org/; Computer ID not assigned yet; resource share 100
14-Nov-2018 21:16:03 [---] No general preferences found - using defaults
14-Nov-2018 21:16:03 [---] Reading preferences override file
14-Nov-2018 21:16:03 [---] Preferences:
14-Nov-2018 21:16:03 [---]    max memory usage when active: 1975.72 MB
14-Nov-2018 21:16:03 [---]    max memory usage when idle: 3556.29 MB

Con esto, ya tendríamos de una manera rápida y sencilla 3 réplicas de una misma imagen corriendo en el swarm y ejecutando los cálculos computacionales de nuestros proyectos de WCG.

También podemos ejecutar el servicio con persistencia de datos. Para ello primero creamos un volumen:

docker volume create boinc-vol

Por defecto este volumen está en /var/lib/docker/volumes:

root@mid-dockers:~# ls -l /var/lib/docker/volumes/
total 68
drwxr-xr-x 3 root root  4096 Jul  6 01:35 1722d85f17492f04e660ce1b66826992f363fd9e9d4246e2234a9af08e3a1376
drwxr-xr-x 3 root root  4096 Jun 13  2018 33b50e991395b820420c9807dc7d678355cf2c78155211fd8b76afc1ec29aea4
drwxr-xr-x 3 root root  4096 Jun 13  2018 554fd8b4912582a7928049185babd4e34a9043ba9db6cdd479233ea11cc466df
drwxr-xr-x 3 root root  4096 Jun 13  2018 663810715f7f23a8b99629a7f98fe2d271e8bfb58fb4be3cfa720ffc5c11e2df
drwxr-xr-x 3 root root  4096 Jul  5 22:01 b6332e9becd825aed06854bd8d865c744bcc82ddee0b1ea778190ee6e26df737
drwxr-xr-x 3 root root  4096 Jul  6 01:30 b6c58683d5df8faccbb7b43c47107c96bda9be9f6345558467d62c08fec234f1
drwxr-xr-x 3 root root  4096 Dec 26 19:42 boinc-vol
drwxr-xr-x 3 root root  4096 Jun 13  2018 f9ad24255e0312eb30fa86dfae793b9b577c9bfcaf9434ab869ce06d690056c9
-rw------- 1 root root 65536 Dec 26 19:42 metadata.db
drwxr-xr-x 3 root root  4096 Jun 13  2018 wordpress_db_data

A la hora de ejecutar docker service no podemos pasarle la opción -v como en caso de un simple docker, tenemos que hacerlo con la opción --mount. Quedaría de la siguiente manera:

root@mid-dockers:/opt/appdata/boinc# docker service create \
>   --replicas 3 \
>   --name boinc \
>   --network=boinc \
>   -p 31416 \
>   --mount source=boinc-vol,destination=/var/lib/boinc-client \
>   -e BOINC_CMD_LINE_OPTIONS="--attach_project http://www.worldcommunitygrid.org <KEY>" \
>   boinc/client

De manera que se mapea el directorio /var/lib/boinc-client del contenedor en el volumen boinc-vol. Como veíamos anteriormente, el contenido en nuestro host estará en /var/lib/docker/volumes/boinc-vol