Docker: Montar recurso NFS
Hoy vamos a unir los dos proyectos que os he ido mostrando en las últimas entradas. Por una parte, Openmediavault sobre un clúster de RaspBerry Pi 4 y discos SSD´s. Y por otro, el clúster de containers con RaspBerry Pi 4 y RaspBerry Pi Zero 2W.
Para containers Docker que necesitan persistencia, será indispensable montar un volumen que nos guarde el dato, y qué mejor que un NAS SSD sobre una RaspBerry Pi 4…
Lo primero que os voy a mostrar es el interface de OpenMediaVault, he configurado un recurso NFS donde he colocado el cliente que va tener acceso (yo por ejemplo he permitido a mi red, porque quiero utilizarlo para varios LABs).
Así que una vez montado os voy a enseñar como se monta normalmente y como lo vamos a hacer un container Docker.
Montar recurso NFS en Linux
Para montar un recurso NFS en Linux, lo primero que necesitaremos comprobar es que tenemos el cliente nfs instalado, para que entienda el protocolo. Revisarlo con este comando:
1 2 3 4 5 6 7 |
root@p0:/# apt install nfs-client Leyendo lista de paquetes... Hecho Creando árbol de dependencias Leyendo la información de estado... Hecho Nota, seleccionando «nfs-common» en lugar de «nfs-client» nfs-common ya está en su versión más reciente (1:1.3.4-2.5+deb10u1). 0 actualizados, 0 nuevos se instalarán, 0 para eliminar y 325 no actualizados. |
Si ya está instalado, generaremos una carpeta destino, donde se montará el recurso en el sistema:
1 2 |
pi@p0:~ $ sudo su - root@p0:~# mkdir /mnt/nfs |
Para montar el share, usaremos el comando:
1 |
root@p0:/# mount -t nfs 192.168.2.196:/DISCOSSD/containers /mnt/nfs |
Y podríamos revisar su montaje:
1 2 3 4 5 6 7 8 9 10 11 12 |
root@p0:/# df -h S.ficheros Tamaño Usados Disp Uso% Montado en /dev/root 29G 6,7G 21G 25% / devtmpfs 1,8G 0 1,8G 0% /dev tmpfs 1,9G 0 1,9G 0% /dev/shm tmpfs 1,9G 201M 1,7G 11% /run tmpfs 5,0M 4,0K 5,0M 1% /run/lock tmpfs 1,9G 0 1,9G 0% /sys/fs/cgroup /dev/mmcblk0p1 253M 55M 198M 22% /boot tmpfs 388M 0 388M 0% /run/user/1000 overlay 29G 6,7G 21G 25% /var/lib/docker/overlay2/26255f4b83dce5580fe8e2ce624dc7788f1ad3fb13cd4821f4b1bd4174c32348/merged 192.168.2.196:/DISCOSSD/containers 879G 235G 644G 27% /mnt/nfs |
Hacéis una pequeña validación de que se puede escribir sobre él:
1 2 3 |
root@p0:~# touch /mnt/nfs/prueba.txt root@p0:~# ls /mnt/nfs/ prueba.txt |
Ahora para que se monte automáticamente cada vez que reinicie, generamos una línea en /etc/fstab:
1 |
192.168.2.196:/DISCOSSD/containers /mnt/nfs nfs rw,hard,intr,rsize=8192,wsize=8192,timeo=14 0 0 |
Para validar podéis usar el siguiente comando o reiniciar:
1 |
root@p0:~# mount -a |
Esta teoría es importante, para entender como se monta en linux, porque necesitaremos saberlo para hacerlo bien en un container Docker, que en la práctica es lo mismo pero con menos recursos.
Montar recurso NFS en Container Docker
Una vez aprendido el concepto, lo vamos a llevar a containers Docker.
Como habéis visto, necesitáis que el sistema entienda el recurso que necesita montar, y para eso debe tener instalado el driver correspondiente nuestro host, que con Raspbian ya lo tiene.
En una infraestructura de 64 bits y no ARM, podéis usar el siguiente driver y seguir las instrucciones del proyecto:
https://github.com/ContainX/docker-volume-netshare
Otra forma, es repetir el apartado anterior y montarlo para linux en cada nodo. De forma, que localmente, el host tiene un recurso que todos los nodos tienen por igual.
Así que cada vez que montemos un volumen, referenciemos al recurso mapeado, en este caso “/mnt/nfs”, y generemos un árbol desde cualquier nodo para el container que necesitemos, sin necesidad de pasar por todos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
root@p0:~# mkdir /mnt/nfs/dockerapache root@p0:~# ls /mnt/nfs/ dockerapache prueba.txt root@p0:~# ssh p4 Linux p4 5.4.79-v7+ #1373 SMP Mon Nov 23 13:22:33 GMT 2020 armv7l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Thu Dec 2 11:59:22 2021 from 172.19.181.254 Wi-Fi is currently blocked by rfkill. Use raspi-config to set the country before use. pi@p4:~ $ ls /mnt/nfs/ dockerubuntu prueba.txt |
Luego lo pasamos al generar el volumen donde montaremos el recurso del host de la siguiente forma:
1 |
docker run -v "$(pwd)":[volume_name] [docker_image] |
Lo haremos de la siguiente forma:
- Generamos el contenedor, de forma que al salir se elimine (parámetro “-rm”)
- Comprobamos que se genera la carpeta /data
- Creamos una carpeta de prueba en el recurso
- Salimos de contenedor
- Y verificamos que el dato persiste cuando salimos del contenedor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
root@p0:~# docker run -it --rm -v /mnt/nfs/dockerubuntu:/data --name dockerubuntu ubuntu root@570f478c4dbf:/# ls bin boot data dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var root@570f478c4dbf:/# cd data root@570f478c4dbf:/data# ls root@570f478c4dbf:/data# mkdir test root@570f478c4dbf:/# df -h Filesystem Size Used Avail Use% Mounted on overlay 29G 7.9G 20G 29% / tmpfs 64M 0 64M 0% /dev tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup shm 64M 0 64M 0% /dev/shm 192.168.2.196:/DISCOSSD/containers/dockerubuntu 879G 235G 644G 27% /data /dev/root 29G 7.9G 20G 29% /etc/hosts tmpfs 1.9G 0 1.9G 0% /proc/asound tmpfs 1.9G 0 1.9G 0% /sys/firmware root@570f478c4dbf:/data# exit exit root@p0:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cd5fb4dc714e alexellis2/visualizer-arm:latest "/usr/bin/entry.sh n…" 45 hours ago Up 45 hours 8080/tcp viz.1.fem68dkl49dsh4xxcobbziggr root@p0:~# ls /mnt/nfs/dockerubuntu/ test |
1 2 |
pi@p4:~ $ ls /mnt/nfs/dockerubuntu/ test |
Ejemplo docker grafana con volumen NFS
Os dejo otro ejemplo, podéis crear un volumen a partir del recurso, para grafana. Y luego dárselo a vuestro docker de aplicación. Os dejo los comandos, he creado una carpeta grafana en el NFS para esto:
1 2 3 4 5 6 7 8 9 10 11 12 |
root@p0:~# docker volume create --name grafana-volumen --opt type=none --opt device=/mnt/nfs/grafana --opt o=bind grafana-volumen root@p0:~# docker volume ls DRIVER VOLUME NAME local 8c919b9fbe0a5771ab6b2ef35c71f24f5967785bcc14e4167d6f8cf87778030a local 8ce72e32b416d9e4f28671ef4aeb5e3a50a574f6d8d4dab88cb8fa7b5c6f45ae local 28c68df767e64ea763e3422b11707e3dbd5ed0a73d99998bb4f4746dc15185aa local 50d6908af5875c6f77aa82fddfc2397b546d78cf50109b4ad42e7720ba37db30 local 07720c32fe10e3ea80de9f40df3b7cabbf3243db1dd57e6ab4cd993b5037f30b local 3908698799f26ba66543d99e3f065acbb8ed432bef1d18201b5730aae231788e local a5d545842b1489a6cd552a2b0a62699191caf862610c59a387b599aa13878413 local grafana-volumen |
Una vez tenemos el volumen, generamos el container para grafana y mapeamos el volumen localmente en el contenedor:
1 2 3 4 5 6 |
root@p0:~# docker run -d -p 3000:3000 --name grafana -v grafana-volumen:/var/lib/grafana grafana/grafana-enterprise f62de2c558b768badaa3bb8b3546d0518c29f4d84deebbcc651f7b186e027e9d root@p0:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f62de2c558b7 grafana/grafana-enterprise "/run.sh" 20 seconds ago Up 18 seconds 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp grafana cd5fb4dc714e alexellis2/visualizer-arm:latest "/usr/bin/entry.sh n…" 2 days ago Up 2 days 8080/tcp viz.1.fem68dkl49dsh4xxcobbziggr |
Te ha gustado la entrada SGUENOS EN TWITTER O INVITANOS A UN CAFE?