Ir al contenido

Recuperación de volúmenes Docker corruptos con fsck y validación de integridad del filesystem en producción

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 poco pasé por la experiencia de que un contenedor Docker dejara de funcionar después de un apagado no limpio del servidor. El volumen quedó en un estado inconsistente y Docker se negaba a iniciarlo. No es agradable que pase en producción, así que aquí está lo que aprendí.

Diagnóstico inicial
#

Lo primero es identificar qué está pasando. Corrí:

docker ps -a

El contenedor estaba en estado Exited (1). Los logs no mostraban nada útil. Luego intenté reiniciarlo:

docker start nombre-contenedor

Docker devolvía errores vagos sobre inodos o estructura de directorios. Claro. El filesystem estaba corrupto.

Ubicar el volumen físico
#

Los volúmenes de Docker se almacenan en /var/lib/docker/volumes/ por defecto. Necesitaba saber dónde estaba físicamente:

docker inspect nombre-contenedor | grep -A 5 Mounts

Esto me mostró la ruta del volumen. En mi caso era algo como /var/lib/docker/volumes/nombre-volumen/_data.

Pero eso no es lo importante. Lo importante es en qué dispositivo físico está. Ejecuté:

df /var/lib/docker/volumes/

En mi caso todo estaba en /dev/sda1. Necesitaba saber el filesystem:

mount | grep sda1

Era ext4. Bien, porque fsck soporta ext4 nativamente.

Parar Docker completamente
#

Aquí es crítico. No puedo ejecutar fsck mientras Docker esté usando el dispositivo. Paré Docker:

sudo systemctl stop docker

Y verifiqué que realmente se detuvo:

ps aux | grep docker

Validación sin reparación
#

Primero hice una validación de solo lectura. Esto no arregla nada, solo reporta:

sudo fsck -n /dev/sda1

La flag -n es de “no-op”. Genera un reporte sin modificar nada. Esto me permitió ver la magnitud del problema sin riesgo.

El reporte mostró inodos huérfanos y bloques asignados incorrectamente. Nada catastrófico, pero definitivamente corrupto.

Reparación automática
#

Una vez que entendí el alcance, pasé a la reparación. Usé la flag -y para que fsck respondiera “sí” automáticamente a todas las preguntas:

sudo fsck -y /dev/sda1

Esto tardó unos minutos. Fsck recreó inodos, limpió bloques huérfanos y reorganizó la tabla de asignación. El proceso es lento pero necesario.

Validación post-reparación
#

Después de que fsck terminó, corrí nuevamente en modo validación:

sudo fsck -n /dev/sda1

Esta vez sin errores. Buen signo.

Iniciando Docker nuevamente
#

sudo systemctl start docker

Esperé un momento a que Docker reiniciara completamente:

sleep 5
docker ps

Verificar el contenedor
#

docker start nombre-contenedor
docker logs nombre-contenedor

Funcionaba. El volumen estaba recuperado.

Validación de integridad en volúmenes activos
#

Para futuras prevenciones, creé un script que valida la integridad sin parar Docker. Uso fsck -n en un cron diario:

#!/bin/bash
sudo fsck -n /dev/sda1 > /tmp/fsck-report.txt 2>&1
if grep -q "error" /tmp/fsck-report.txt; then
    echo "Alerta: Errores detectados en filesystem" | mail -s "fsck alert" admin@domain.local
fi

Lecciones aprendidas
#

No dejes que los contenedores de producción terminen abruptamente. Usa docker stop con timeout adecuado. Valida regularmente la integridad del filesystem. Mantén backups de los volúmenes críticos.

Y la más importante: fsck funciona. Aunque no sea glamoroso, recupera filesystems corruptos cuando necesitas que funcione.