in docker backup shell ~ read.

Docker: copia de seguridad de un contenedor y sus volumenes

Imaginemos que tenemos un contenedor en marcha, el cual tiene un volumen donde almacena la información sensible que deseamos sea persistente y no se pierda. Por ahora todo funciona a las mil maravillas, pero como Murphy siempre aparece sin avisar, estaría bien hacer una copia de seguridad por si acaso.

Bien, pues manos a la obra.

Supongamos que el escenario es el siguiente. El contenedor que está en ejecución se llama my-app y que el volumen en el que almacena los datos es vol-my-app.

Crear copia de seguridad

La mejor manera de realizar una copia del contenedor es crear una imagen del mismo y así poder exportarla. Para ello hacemos uso de la opción commit y creamos una imagen basada en nuestro contenedor.

docker commit my-app my-app_backup

Si ejecutamos docker images, aparte de las imágenes que ya tenemos, aparecerá otra con el nombre my-app_backup. Esta es la imagen de nuestro contenedor que podremos exportar a un archivo **.tar ** con docker save:

docker save -o my-app_backup.tar  my-app

Ahora ya tenemos un archivo my-app_backup.tar que contiene una imagen completa del contenedor.

Para evitar el síndrome de Diógenes digital, borramos la imagen del backup que ya tenemos en el archivo .tar.

docker image rm my-app_backup

La copia de seguridad del volumen de datos es un poco más complicado. Desconozco si los desarrolladores de Docker tienen pensado programar algo parecido a docker save pero orientado a volumenes. De mientras, la manera más limpia de hacer una copia es mediante la ejecución de un contenedor.

Me explico. La idea es ejecutar un contenedor temporalmente en el que montaremos el volumen vol-my-app y por otro lado montaremos una carpeta local, en la que almacenaremos un .tar con el contenido del volumen. Dicho así suena raro, pero tiene su sentido.

Lo mejor es parar el contenedor y así evitar que los datos no se corrompan en el proceso de copiado:

docker container stop my-app

Ahora ejecutamos un nuevo contenedor junto al comando para realizar el tar con el contenido del volumen:

docker run --rm -it -v vol-my-app:/volume -v /tmp:/backup debian:stable-slim \
tar -cf /backup/vol-my-app.tar -C /volume ./

El contenedor internamente creará una .tar con el contenido del volumen, y lo dejara en /backup, que realmente es /tmp fuera del contenedor. Por lo que la copia de seguridad estará en /tmp/vol-my-app.tar.

Volvemos a arrancar el contenedor original para que todo siga ejecutándose con normalidad:

docker container start my-app

Ahora ya tenemos las copias de seguridad realizadas. Por un lado el contenedor como una imagen en my-app.tar, y por el otro el volumen en /tmp/vol-my-app.tar. Una buena idea sería sacar esos dos archivos fuera del equipo y almacenarlo en un lugar seguro.

Restaurar las copia de seguridad

Imaginemos que Murphy aparece de la nada y nuestro equipo pasa a mejor vida, llevándose con él el contenedor que tanto nos costó configurar. Después de echarse las manos al a cabeza recordamos que tenemos esos 2 archivos .tar con una copia del contenedor y el volumen de datos, menos mal. Pues vamos a recuperar esa copia.

Lo primero seria restaurar el contenedor:

docker load < my-app_backup.tar

Ejecutando docker images veremos que se ha restaurado una imagen con el nombre my-app_backup. Como nuestro contenedor depende de un volumen de datos, deberemos recuperar esos datos antes de poner en marcha un contenedor de dicha imagen.

Para recuperar el volumen el proceso es muy parecido al que se utilizó para crear la copia de seguridad. En este caso en vez de crear un .tar lo que haremos en extraer el contenido de la copia, vol-my-app.tar, y meterlo en el volumen:

Creamos un volumen con el mismo nombre que el original:

docker volume create vol-my-app

Insuflamos el contenido de .tar al nuevo volumen:

docker run --rm -it -v vol-my-app:/volume -v /tmp:/backup debian:stable-slim \
sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xf 
/backup/vol-my-app.tar”

Ahora que ya tenemos todo restaurado, solo hace falta arrancar un contenedor que se base en la imagen recuperada junto al volumen:

docker run -d --restart unless-stopped --name **my-app** -v vol-my-app:/var/lib/my-app -p 8888:8888/tcp my-app_backup

Ejecutando docker stats podremos ver que nuestro contenedor ha vuelto a la vida después de morir súbitamente.

Chupate esa Murphy !!!

Fuentes:

  1. https://sysadminnightmare.org/docker-save-load-import-export-commit/
  2. https://loomchild.net/2017/03/26/backup-restore-docker-named-volumes/
comments powered by Disqus