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 -aEl contenedor estaba en estado Exited (1). Los logs no mostraban nada útil. Luego intenté reiniciarlo:
docker start nombre-contenedorDocker 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 MountsEsto 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 sda1Era 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 dockerY verifiqué que realmente se detuvo:
ps aux | grep dockerValidación sin reparación#
Primero hice una validación de solo lectura. Esto no arregla nada, solo reporta:
sudo fsck -n /dev/sda1La 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/sda1Esto 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/sda1Esta vez sin errores. Buen signo.
Iniciando Docker nuevamente#
sudo systemctl start dockerEsperé un momento a que Docker reiniciara completamente:
sleep 5
docker psVerificar el contenedor#
docker start nombre-contenedor
docker logs nombre-contenedorFuncionaba. 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
fiLecciones 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.