↓ Ir al contenido

Recuperación de datos en Docker tras fallo de almacenamiento: diagnóstico con lsof y reconstrucción de inodes

·3 mins
Rogelio Guerra Riverón
Autor
Rogelio Guerra Riverón
Construyendo mi propia infraestructura web desde cero. Aquí documento cada paso: servidores, redes, contenedores y lo que vaya surgiendo.

El problema
#

Hace dos semanas mi servidor doméstico sufrió un corte de energía mientras corría varios contenedores Docker. Cuando reinicié, uno de los volúmenes montados quedó corrupto. El contenedor no iniciaba y los datos parecían perdidos. No estaban completamente borrados, pero el sistema de archivos estaba dañado.

Documenté el proceso de recuperación porque es algo que probablemente vuelva a necesitar.

Paso 1: Identificar qué está abierto
#

Primero necesitaba saber qué procesos tenían archivos abiertos en ese volumen. Aquí es donde lsof resulta esencial.

lsof /ruta/al/volumen/docker

En mi caso, el volumen estaba montado en /var/lib/docker/volumes/datos/_data. El comando me mostró que había referencias fantasma a archivos que ya no existían en el inode.

Si quería ser más específico y filtrar solo por contenedores:

lsof +D /var/lib/docker/volumes/datos/_data

Esto listaba todos los descriptores de archivo abiertos en ese directorio. Vi que había procesos huérfanos intentando acceder a archivos eliminados o corruptos.

Paso 2: Intentar montar en modo lectura
#

Antes de tocar nada, intenté montar el volumen en modo solo lectura para evitar empeorar las cosas:

sudo mount -o remount,ro /ruta/al/volumen

Esto me permitió examinar el sistema de archivos sin riesgo de corromperlo más.

Paso 3: Usar debugfs para inspeccionar inodes
#

El siguiente paso era entender el estado del sistema de archivos. debugfs es tu mejor amigo cuando ext4 se comporta mal.

sudo debugfs -R 'ls -l' /dev/mapper/vg0-datos

Cambié /dev/mapper/vg0-datos por el dispositivo real en mi caso. Esto me mostró la estructura de directorios sin depender del kernel.

Para listar inodes específicos que sabía que existían:

sudo debugfs /dev/mapper/vg0-datos

Dentro del prompt interactivo:

debugfs: ls -l /
debugfs: inode <número>
debugfs: dump /ruta/archivo /tmp/recuperado

Paso 4: Reconstruir inodes dañados
#

Los inodes corruptos eran el principal problema. Usé fsck en modo no interactivo primero para ver el estado:

sudo fsck -n /dev/mapper/vg0-datos

El flag -n hace un chequeo de solo lectura. Mostró varios inodes dañados y bloques huérfanos.

Luego ejecuté la reparación real:

sudo fsck -y /dev/mapper/vg0-datos

El flag -y responde “sí” automáticamente a las preguntas de reparación. Esto tardó unos 15 minutos en mi volumen de 500GB.

Paso 5: Recuperar datos específicos
#

Después de fsck, algunos archivos estaban en /lost+found. Los moví manualmente de vuelta:

sudo mv /ruta/al/volumen/lost+found/* /ruta/al/volumen/recuperados/
sudo chown -R 1000:1000 /ruta/al/volumen/recuperados/

El chown era necesario porque los permisos se había restablecido a root.

Paso 6: Reiniciar el contenedor
#

docker-compose up -d

En mi caso funcionó. Los datos recuperados estaban intactos. Algunos archivos de log perdidos no eran críticos.

Lecciones aprendidas
#

  1. Backups son no-negociables en servidores domésticos. Esto me enseñó que de verdad lo son.
  2. lsof es tu diagnosticador: siempre revela qué está usando tus archivos.
  3. debugfs es más confiable que el kernel cuando ext4 está dañado.
  4. fsck -n primero: nunca voy directo a -y sin ver el daño antes.

La próxima vez que falle el almacenamiento, sabré exactamente qué hacer.