Intro

Los linux containers (lxc) son un sistema de virtualización intermedio entre una KVM y un container de docker. Resulta enxtremadamente útiles cuando uno necesita un sistema operativo linux completo pero no quiere perder las ventajas que ofrece la virtualización (poco espacio necesario, facilidad de copias de seguridad y restauración en caso de fallo…).

Sin embargo, una de las cosas en las que en principio se diferencian de los sistemas linux completos es la posibilidad de montar sistemas de archivos remotos.

En nuestro caso, queríamos montar un sistema de archivos sshfs de otro lxc

¿Como lo hacemos?

Primero tendríamos que instalar sshfs en nuestro sistema, porque por defecto no viene instalado en las distribuciones de linux habituales.

CentOS 7

En el caso de Centos 7 hay que instalar antes el repositorio epel

yum install -y epel-release

Luego instalamos el sshfs:

yum install -y sshfs

Debian/Ubuntu

Solamente hay que instalar el sshfs con el siguiente comando:

apt-get install sshfs

Conectando el directorio remoto desde nuestro lxc

El comando sería del estilo:

sshfs -o allow_other,default_permissions 192.168.1.204:shared/data /mnt/external_storage

Sin embargo el sistema se queja con el siguiente mensaje:

fuse: device not found, try 'modprobe fuse' first

No podemos hacer un modprobe en el lxc porque no tiene un kernel (comparte el del host).

Proxmox al rescate

En nuestro caso empleamos proxmox para la creación y gestión de lxc, lo que hace más fácil darle el fuse que el container nos pide para poder montar el directorio remoto.

Para ello tenemos que ir a la sección «Options» del container y clicamos en Features, con lo que se nos abre un diálogo (fig. 1)

Figura 1. Editando las Features de nuestro lxc

Marcamos FUSE y le damos a OK. Podríamos marcar varios para permitir al container usar distintos tipos de montaje remoto.

Tenemos que parar el container y al arrancarlo de nuevo.

Al ejecutar el comando para montar el directorio remoto el sistema no se queja. Si no tenemos nuestra clave ssh pública en el equipo remoto, nos pedirá la contraseña.

Lo ideal sería generar nuestra clave ssh (yo últimamente estoy usando claves ed25519). Para generar la clave habría que hacer:

ssh-keygen -t ed25519

Nos pregunta donde queremos guardar (el directorio que da por defecto está bien) y nos pide la passphrase. Le damos a ENTER para no depender de passphrase.

Nos pide que repitamos la passphrase, y le damos ENTER de nuevo.

Genera la clave y la guarda en nuestro directorio .ssh

Para que podamos acceder sin clave en el container 192.168.1.204 tendremos que adjuntar nuestra clave pública al archivo .ssh/authorized_keys del usuario root del equipo.

Para ello, una vez hemos entrado como root en 192.68.1.204 ejecutamos:

cat >> .ssh/authorized_keys

Y pegamos la clave .ssh/id_ed25519.pub que hemos copiado del otro equipo haciendo:

cat .ssh/id_ed25519.pub

Si no os aclarais con estas instrucciones, podéis googlear Acceso por ssh sin contraseña y seguir cualquiera de los tutoriales que os devuelve Google.

Una vez ejecutado el comando sshfs, si hacemos un df -h podemos ver que el directorio remoto está montado en nuestro sistema:

192.168.1.204:shared/data 98G 648M 93G 1% /mnt/external_storage

Montando al inicio

Ya hemos visto que somos capaces de montar el directorio remoto en nuestro container, pero lo que realmente queremos es que cada vez que se reinicie la máquina el directorio esté disponible.

En un equipo «normal» añadiríamos una línea en el fichero /etc/fstab que se encargue del montaje. Sin embargo, si tenemos algo de experiencia con los lxc sabremos que éstos no tienen fichero /etc/fstab, porque de los montajes de sistemas de archivos se encarga el gestor de containers, el sistema pct. 🤔

Para poder montar el directorio al inicio emplearemos el sistema cron, que si que está presente y funcional en los lxc.

Editaremos el cron de root con el comando crontab -e desde la cuenta de root o con sudo crontab -e y añadiremos la siguiente linea en una máquina Debian / Ubuntu:

@reboot sshfs -o allow_other,default_permissions 192.168.1.204:shared/data /mnt/external_storage

Al reinciar el lxc y volver a entrar en el, veremos que el directorio aparece montado.

Sin embargo, en CentOS 7 esto no ocurre. El sistema no monta automáticamente el directorio con esta línea de cron.

Después de darle muchas vueltas al tema, llegué a la conclusión de que el sistema no está preparado para el montaje nada más iniciarse, así que le damos un tiempo para que se organice y luego montamos el directorio. En los containers CentOS 7 sustituimos la línea de cron anterior por la siguiente:

@reboot sleep 20 && sshfs -o allow_other,default_permissions 192.168.1.204:shared/data /mnt/external_storage

Esto hace que el sistema se espere veinte segundos antes de tratar de montar el directorio remoto.

Nos constará unos segundos ver que el directorio remoto está montado.

Cuidado con los backups en proxmox

Hasta ahora todo bien con proxmox. El problema aparece cuando el sistema quiere hacer la preceptiva copia de seguridad de los contenedores.

Para evitar paradas en los servicios, suelo tener programadas las copias de seguridad como snapshots, que reduce al minimo el tiempo en el que los equipos no están disponibles.

Sin embargo, hacer un snapshot de un equipo que tiene un directorio de otro equipo montado parece que no es una situación que guste mucho a proxmox y no consigue finalizar el snapshot, lo que bloquea tanto el acceso al contenedor como el resto de copia de seguridad.

Por otro lado, tampoco tiene mucho sentido que copiemos en una copia de seguridad del equipo algo que no es suyo, el directorio que ha montado por ssh es de otro equipo y la copia debe realizarse en ese equipo y no en éste.

La solución para evitar este problema es cambiar el tipo de sistema de copia y pasarlo de Snapshot a Stop. De este modo, el proxmox para el contenedor, con lo que el directorio remoto se desconecta, y hace la correspondiente copia de seguridad sin problemas.