Al desplegar un contanedor de MySQL 8.0 en un servidor CentOS, es común encontrarse con el error 10038 al intentar conectar desde herramientas externas como Navicat. Este problema suele derivar de tres factores: la política de autenticación de MySQL 8, el firewall del sistema operativo o las reglas de red del proveedor de servicios en la nube.
1. Configuración del contenedor y privilegios de acceso
Primero, procedemos a descargar la imagen y ejecutar el contenedor mapeendo el puerto estándar 3306.
# Descargar la imagen oficial
docker pull mysql:8.0
# Iniciar el contenedor con una contraseña definida
docker run --name srv-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=ClaveSegura2024 -d mysql:8.0
Una vez que el contenedor esté en ejecución, debemos ingresar a la terminal de MySQL para ajustar los permisos de acceso remoto y el método de cifrado de contraseñas, ya que MySQL 8 utiliza caching_sha2_password por defecto, lo cual genera incompatibilidades con versiones antiguas de clientes SQL.
# Entrar al contenedor
docker exec -it srv-mysql mysql -u root -p
# Dentro de MySQL:
# Otorgar permisos globales al usuario root
CREATE USER 'root'@'%' IDENTIFIED BY 'ClaveSegura2024';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
# Cambiar el plugin de autenticación a mysql_native_password para compatibilidad
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'ClaveSegura2024';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'ClaveSegura2024';
# Aplicar cambios
FLUSH PRIVILEGES;
2. Verificación del Firewall en CentOS
Si la conexión sigue fallando, es necesario verificar si el firewall nativo de CentOS (firewalld) está bloqueando las peticiones entrantes en el puerto 3306.
# Comprobar el estado del firewall
systemctl status firewalld
# Si está activo, podemos detenerlo temporalmente para pruebas o abrir el puerto específico
systemctl stop firewalld
# O añadir la excepción permanentemente:
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
3. Inspección de red y binding de puertos
Es fundamental confirmar que el sistema está escuchando correctamente en el puerto asignado. Mediante netstat, podemos validar si el servicio de Docker tiene el puerto abierto para IPv4 o IPv6.
# Instalar herramientas de red si no están presentes
yum install net-tools -y
# Verificar puertos en escucha
netstat -tunlp | grep 3306
Adicionalmente, debemos asegurar que el reenvío de IP (IP Forwarding) esté habilitado en el kernel, lo cual es vital para la comunicación de red de Docker:
# Verificar si el reenvío está activo (debe retornar 1)
sysctl net.ipv4.ip_forward
4. Configuración de Grupos de Seguridad (Cloud Provider)
Si después de realizar los pasos anteriores el comando telnet direccion_ip 3306 desde tu máquina local sigue sin responder, el bloqueo reside probablemente en la capa de infraestructura del proveedor de la nube (como AWS, Azure o Alibaba Cloud).
Los proveedores de VPS suelen incluir un "Grupo de Seguridad" o firewall externo que actúa antes de llegar a tu servidor CentOS. Por defecto, estos grupos solo permiten tráfico en el puerto 22 (SSH).
Para resolverlo:
- Accede al panel de control de tu instancia en la nube.
- Localiza la sección de Security Groups o Firewall Rules.
- Añade una regla de entrada (Inbound Rule) con los siguientes parámetros:
- Protocolo: TCP
- Rango de puertos: 3306
- Origen: 0.0.0.0/0 (o tu IP específica para mayor seguridad)
- Guarda los cambios e intenta la conexión desde Navicat nuevamente.