# Cómo el desajuste de MTU en Docker y OpenStack rompe CI/CD: Diagnóstico y solución
Un fallo de compilación un viernes por la noche suele ser más que un error aleatorio: es un desajuste de MTU entre contenedores Docker y la red overlay de OpenStack. El problema solo aparece con transferencias de datos grandes, como clonar un repositorio, mientras que las peticiones pequeñas funcionan perfectamente. Esto genera una falsa sensación de que la red va bien hasta que llegan cargas reales.
Por qué las peticiones pequeñas funcionan y las grandes fallan
La señal de alerta de este problema es su selectividad. Comandos como curl -I o ping que envían paquetes diminutos siempre tienen éxito. El lío empieza con operaciones que necesitan bloques grandes de datos: git clone, docker pull, descargas de artefactos. ¿El culpable? La Unidad Máxima de Transmisión (MTU): el tamaño máximo de paquete IP que se puede enviar sin fragmentación.
Las redes Ethernet estándar usan una MTU de 1500 bytes. Pero en entornos cloud como OpenStack, tecnologías overlay como VXLAN o GRE crean redes aisladas envolviendo cada paquete en unos 50 bytes de cabecera extra. Así, aunque la red física soporte 1500, los paquetes de tu VM solo tienen 1450 bytes disponibles.
Docker por defecto usa una red bridge con MTU 1500, ignorando las particularidades de la infraestructura. Los contenedores generan paquetes a esa medida. Cuando llegan a la interfaz del host con MTU 1450, no pueden transmitirse por la bandera DF (Don't Fragment). Idealmente, el Path MTU Discovery debería activarse, pero firewalls, grupos de seguridad o routers mal configurados suelen bloquear los mensajes ICMP "Fragmentation Needed".
Diagnostica el problema en 30 segundos
Detecta un desajuste de MTU con estos tres comandos:
- Verifica la MTU de la interfaz de red del host:
```
ip link show ens3 | grep mtu
```
En OpenStack, espera ver mtu 1450.
- Comprueba la MTU dentro de un contenedor:
```
docker run --rm alpine ip link show eth0 | grep mtu
```
Docker usa por defecto mtu 1500. Si es mayor que la del host, ahí está el problema.
- Ejecuta un test de ping bloqueando fragmentación:
```
docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com
docker run --rm alpine ping -s 1423 -M do -c 3 gitlab.example.com
```
El primero (1422 = 1450 − 28) debería funcionar; el segundo fallar con Message too long.
Solución paso a paso
Configura la MTU en Docker
La solución principal: configura Docker para usar la MTU correcta. Edita /etc/docker/daemon.json:
{
"mtu": 1450
}
Reinicia el daemon de Docker:
sudo systemctl restart docker
Maneja redes existentes
Nota: Los cambios en daemon.json solo afectan a redes nuevas. Las existentes —especialmente de Docker Compose— mantienen la MTU antigua. Dos opciones:
- Recrear todo:
```
docker compose down && docker compose up -d
```
- Establecer MTU explícitamente en Docker Compose:
```yaml
networks:
app-net:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: 1450
```
Pasos finales
Reinicia GitLab Runner y prueba:
sudo gitlab-runner restart
docker run --rm alpine ping -s 1422 -M do -c 3 gitlab.example.com
Si la prueba pasa, listo.
Errores comunes y mejores prácticas
- No bajes la MTU "por si acaso". Reducirla a 1300 corta el rendimiento un 10-15% por paquetes extra. Usa el valor exacto diagnosticado.
- Automatízalo. Integra la MTU en tu config de infra (Terraform, Ansible, cloud-init), nada de ajustes manuales.
- Cuidado con redes personalizadas.
daemon.jsonno toca las existentes. Verifica condocker network inspect. - Olvídate de confiar en Path MTU Discovery. Los entornos cloud lo rompen con bloqueos ICMP.
Lecciones clave
- El desajuste de MTU solo muerde en transferencias grandes, lo que lo hace difícil de detectar.
- Los overlays de OpenStack consumen 50 bytes de MTU en cabeceras.
- El 1500 por defecto de Docker choca en clouds.
- Solución: Alinea la MTU de Docker con la del host.
- Automatiza la config en tu pipeline de despliegue.
— Editorial Team
Aún no hay comentarios.