Cómo probar la conectividad entre contenedores de Docker

DockerDockerBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Los contenedores de Docker se han convertido en una parte fundamental del desarrollo y despliegue de aplicaciones modernas. Cuando se trabaja con múltiples contenedores, es crucial garantizar una conectividad adecuada entre ellos para que sus aplicaciones funcionen correctamente.

En este laboratorio, aprenderá a verificar y solucionar problemas de conectividad entre contenedores de Docker. Empezaremos con conceptos básicos de contenedores de Docker, configuraremos contenedores para realizar pruebas y luego exploraremos varios métodos para comprobar y diagnosticar las conexiones de red entre contenedores.

Al final de este tutorial, podrá probar, verificar y resolver con confianza problemas de conectividad en sus aplicaciones empaquetadas en contenedores.

Este laboratorio requiere una conexión a Internet para el aprendizaje, por lo que solo los usuarios Pro pueden iniciar la máquina virtual. Actualice su cuenta a Pro.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/NetworkOperationsGroup(["Network Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/NetworkOperationsGroup -.-> docker/network("Manage Networks") subgraph Lab Skills docker/run -.-> lab-411613{{"Cómo probar la conectividad entre contenedores de Docker"}} docker/ls -.-> lab-411613{{"Cómo probar la conectividad entre contenedores de Docker"}} docker/ps -.-> lab-411613{{"Cómo probar la conectividad entre contenedores de Docker"}} docker/exec -.-> lab-411613{{"Cómo probar la conectividad entre contenedores de Docker"}} docker/inspect -.-> lab-411613{{"Cómo probar la conectividad entre contenedores de Docker"}} docker/network -.-> lab-411613{{"Cómo probar la conectividad entre contenedores de Docker"}} end

Configuración de contenedores de Docker para pruebas

Antes de poder probar la conectividad entre contenedores, necesitamos crear algunos contenedores con los que trabajar. En este paso, configuraremos dos contenedores de Docker simples y aprenderemos sobre los comandos básicos de Docker.

Comprendiendo los contenedores de Docker

Los contenedores de Docker son paquetes livianos y autónomos que incluyen todo lo necesario para ejecutar una aplicación: código, entorno de ejecución, herramientas del sistema, bibliotecas y configuraciones. Los contenedores comparten el kernel del sistema operativo de la máquina host pero se ejecutan en entornos aislados.

Creación de contenedores de prueba

Comencemos creando dos contenedores simples basados en la imagen de Ubuntu. Utilizaremos estos contenedores durante todo el laboratorio para probar la conectividad entre ellos.

Primero, creemos nuestro primer contenedor:

docker run -d --name container1 ubuntu:22.04 sleep infinity

Ahora, creemos el segundo contenedor:

docker run -d --name container2 ubuntu:22.04 sleep infinity
ejecutar contenedores

Explicación de los parámetros del comando:

  • -d: Ejecuta el contenedor en modo detachado (en segundo plano)
  • --name: Asigna un nombre al contenedor
  • ubuntu:22.04: La imagen de Docker a utilizar (versión 22.04 de Ubuntu)
  • sleep infinity: Un comando que mantiene el contenedor en ejecución indefinidamente

Verificación de que nuestros contenedores estén en ejecución

Para comprobar si nuestros contenedores se están ejecutando correctamente, utilice el siguiente comando:

docker ps

Debería ver una salida similar a esta:

CONTAINER ID   IMAGE          COMMAND            CREATED         STATUS         PORTS     NAMES
f8d97c645cce   ubuntu:22.04   "sleep infinity"   5 segundos atrás   En ejecución hace 4 segundos             container2
a2c516a57cb8   ubuntu:22.04   "sleep infinity"   18 segundos atrás  En ejecución hace 17 segundos            container1

Si no ve ambos contenedores listados, es posible que no se hayan iniciado correctamente. Puede intentar crearlos nuevamente.

Instalación de herramientas de red

Por defecto, la imagen de contenedor de Ubuntu es muy mínima y no incluye las herramientas de red que necesitaremos. Instalemos estas herramientas en ambos contenedores:

Para container1:

docker exec container1 apt-get update
docker exec container1 apt-get install -y iputils-ping net-tools iproute2 curl

Para container2:

docker exec container2 apt-get update
docker exec container2 apt-get install -y iputils-ping net-tools iproute2 curl

Estos comandos:

  1. Utilizan docker exec para ejecutar comandos dentro de un contenedor en ejecución
  2. Actualizan la lista de paquetes con apt-get update
  3. Instalan herramientas de red (iputils-ping para ping, net-tools para netstat, iproute2 para comandos de ip y curl)

Ahora nuestros contenedores están listos para la prueba de conectividad en los siguientes pasos.

Comprendiendo las redes de Docker

Los contenedores de Docker se comunican entre sí a través de redes. Comprender cómo funciona la red de Docker es esencial para probar y solucionar problemas de conectividad entre contenedores.

Conceptos básicos de redes de Docker

Cuando se instala Docker, se crean automáticamente varias redes predeterminadas. Las más comúnmente utilizadas son:

  • bridge: La red predeterminada a la que se conectan los contenedores si no se especifica ninguna otra red
  • host: Los contenedores utilizan directamente la red de la máquina host (sin aislamiento)
  • none: Los contenedores no tienen acceso a la red

Veamos las redes de su sistema:

docker network ls

Debería ver una salida similar a:

NETWORK ID     NAME      DRIVER    SCOPE
1b95853bf83b   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

Comprendiendo la red bridge predeterminada

Por defecto, ambos nuestros contenedores están conectados a la red bridge predeterminada. Veamos esta red:

docker network inspect bridge

Este comando muestra información detallada sobre la red bridge, incluyendo los contenedores conectados a ella y sus direcciones IP. En la salida, busque la sección "Containers" para ver tanto container1 como container2 listados con sus direcciones IP.

Encontrando las direcciones IP de los contenedores

Para trabajar con la conectividad de los contenedores, necesitamos conocer las direcciones IP asignadas a nuestros contenedores. Hay varias maneras de obtener esta información:

Utilizando docker inspect:

docker inspect --format='{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1

O desde dentro del contenedor:

docker exec container1 hostname -i

Anote las direcciones IP de ambos contenedores:

docker exec container1 hostname -i
docker exec container2 hostname -i

La salida mostrará la dirección IP de cada contenedor, que por lo general comienza con 172.17.0.x en la red bridge predeterminada.

Creando una red personalizada de Docker

Si bien la red bridge predeterminada permite la comunicación entre contenedores, crear una red personalizada ofrece mejor aislamiento y resolución DNS integrada (los contenedores pueden alcanzarse entre sí por nombre en lugar de por IP).

Vamos a crear una red bridge personalizada:

docker network create --driver bridge my-network

Ahora, vamos a conectar nuestros contenedores existentes a esta nueva red:

docker network connect my-network container1
docker network connect my-network container2

Podemos verificar que nuestros contenedores están conectados a la nueva red:

docker network inspect my-network

Ahora nuestros contenedores están conectados tanto a la red bridge predeterminada como a nuestra red personalizada my-network. En el siguiente paso, probaremos la conectividad entre ellos.

Prueba de conectividad básica entre contenedores

Ahora que tenemos nuestros contenedores configurados y conectados a redes, podemos probar la conectividad entre ellos. Utilizaremos varios métodos para verificar que los contenedores pueden comunicarse entre sí.

Utilizando ping para probar la conectividad

La forma más simple de probar la conectividad básica de red es utilizando el comando ping, que envía solicitudes de eco ICMP al host destino.

Vamos a hacer ping de container1 a container2 utilizando la dirección IP:

## Primero, obtenga la dirección IP de container2
CONTAINER2_IP=$(docker exec container2 hostname -i)
echo "Dirección IP de Container2: $CONTAINER2_IP"

## Obtenga la primera dirección IP de la CONTAINER2_IP
CONTAINER2_IP=$(echo $CONTAINER2_IP | cut -d' ' -f1)
echo "Dirección IP de Container2: $CONTAINER2_IP"

## Ahora haga ping de container1 a container2
docker exec container1 ping -c 4 $CONTAINER2_IP

Debería ver una salida similar a:

PING 172.17.0.3 (172.17.0.3): 56 bytes de datos
64 bytes de 172.17.0.3: icmp_seq=0 ttl=64 time=0.095 ms
64 bytes de 172.17.0.3: icmp_seq=1 ttl=64 time=0.067 ms
64 bytes de 172.17.0.3: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes de 172.17.0.3: icmp_seq=3 ttl=64 time=0.087 ms
--- 172.17.0.3 ping statistics ---
4 paquetes transmitidos, 4 paquetes recibidos, 0% de pérdida de paquetes
round-trip min/avg/max/stddev = 0.067/0.085/0.095/0.000 ms

Prueba de resolución DNS

Una ventaja de las redes personalizadas de Docker es que proporcionan resolución DNS automática, lo que permite que los contenedores se comuniquen entre sí por nombre.

Vamos a probar la resolución DNS haciendo ping al contenedor por nombre:

docker exec container1 ping -c 4 container2

Esto debería funcionar porque ambos contenedores están en nuestra red personalizada my-network, que proporciona resolución DNS. Debería ver respuestas de ping similares a la prueba anterior, pero utilizando el nombre del contenedor en lugar de la IP.

Utilizando curl para probar la conectividad HTTP

Para aplicaciones que ejecutan servicios web, a menudo necesitamos probar la conectividad HTTP. Vamos a configurar un servidor HTTP simple en container2 y probar la conectividad a él desde container1.

Primero, vamos a iniciar un servidor HTTP básico en container2:

docker exec container2 apt-get install -y python3
docker exec -d container2 bash -c "echo 'Hello from container2' > /index.html && cd / && python3 -m http.server 8080"

Espere unos segundos hasta que el servidor se inicie, luego pruebe la conexión desde container1:

docker exec container1 curl -s http://container2:8080

Debería ver la salida:

Hello from container2

Esto confirma que container1 puede conectarse al servicio HTTP de container2 utilizando el nombre del contenedor para la resolución DNS.

Prueba de conexión con diferentes métodos

También es útil saber cómo probar la conectividad utilizando otras herramientas. Intentemos utilizar nc (netcat) para comprobar si un puerto específico está abierto:

## Asegúrese de que netcat esté instalado en container1
docker exec container1 apt-get install -y netcat

## Pruebe la conectividad al servidor HTTP en container2
docker exec container1 nc -zv container2 8080

Debería ver una salida que indique que la conexión fue exitosa:

Connection to container2 (172.18.0.3) 8080 port [tcp/*] succeeded!

Estas pruebas confirman que nuestros contenedores pueden comunicarse entre sí tanto a nivel de red (ping) como a nivel de aplicación (HTTP).

Solución de problemas de conectividad de contenedores

Puede omitir este paso si no tiene problemas de conectividad.

Ahora que entendemos cómo probar la conectividad entre contenedores, exploremos cómo solucionar los problemas de conectividad comunes.

Problemas de conectividad comunes

Al trabajar con redes de contenedores de Docker, es posible que encuentre varios problemas comunes:

  1. Contenedores en diferentes redes sin enrutamiento adecuado
  2. Configuraciones de firewall o grupos de seguridad que bloquean el tráfico
  3. Aplicación no escuchando en la IP/puerto esperado
  4. Errores de configuración de red
  5. Problemas de resolución DNS

Veamos los pasos de solución de problemas para cada uno de estos posibles problemas.

Verificación de la configuración de red

Primero, examinemos la configuración de red de nuestros contenedores:

## Muestre las interfaces de red de container1
docker exec container1 ip addr show

## Muestre las interfaces de red de container2
docker exec container2 ip addr show

La salida muestra todas las interfaces de red en cada contenedor. Cada red de Docker conectada aparece como una interfaz eth con su dirección IP asignada.

Verificación de las rutas de red

Veamos la configuración de enrutamiento en nuestros contenedores:

docker exec container1 route -n

Esto muestra la tabla de enrutamiento para container1, indicando a dónde se dirige el tráfico de red.

Verificación de los puertos de escucha

Para determinar si una aplicación está escuchando adecuadamente las conexiones, use:

docker exec container2 netstat -tuln

Esto muestra todos los puertos de escucha TCP y UDP. Nuestro servidor HTTP debería estar escuchando en el puerto 8080.

Diagnóstico con tcpdump

Para un análisis más detallado del tráfico de red, podemos usar tcpdump para capturar y analizar los paquetes:

## Instale tcpdump en container1
docker exec container1 apt-get install -y tcpdump dnsutils

## Capture paquetes durante 10 segundos
docker exec container1 timeout 10 tcpdump -i eth0 -n

Mientras esto está en ejecución, abra otra terminal y genere un poco de tráfico:

docker exec container1 ping -c 3 container2

Debería ver que los paquetes ICMP se capturan en la salida de tcpdump.

Verificación de la resolución DNS de Docker

Si tiene problemas con la resolución DNS entre contenedores:

## Verifique la configuración DNS
docker exec container1 cat /etc/resolv.conf

## Pruebe la resolución DNS
docker exec container1 nslookup container2

Simulación de un problema de red

Vamos a simular un problema de conectividad desconectando temporalmente container1 de nuestra red personalizada:

## Desconecte container1 de my-network
docker network disconnect my-network container1

## Intente hacer ping por nombre (esto debería fallar)
docker exec container1 ping -c 2 container2

Debería ver que el ping falla porque container1 ya no puede resolver container2 por nombre después de ser desconectado de la red compartida.

Vamos a reconectarlo:

## Vuelva a conectar container1 a my-network
docker network connect my-network container1

## Verifique que la conectividad se haya restaurado
docker exec container1 ping -c 2 container2

Ahora el ping debería funcionar nuevamente, demostrando cómo los contenedores deben estar en la misma red para que la resolución de nombres funcione.

Lista de verificación para la solución de problemas

Cuando enfrente problemas de conectividad de contenedores, siga esta lista de verificación:

  1. Verifique que los contenedores estén en ejecución: docker ps
  2. Compruebe que estén en la misma red: docker network inspect <network>
  3. Verifique que se hayan asignado direcciones IP: docker inspect <container>
  4. Pruebe la conectividad básica (ping): docker exec <container> ping <target>
  5. Compruebe que la aplicación esté escuchando: docker exec <container> netstat -tuln
  6. Verifique que la resolución DNS funcione: docker exec <container> nslookup <target>
  7. Busque problemas de firewall: docker exec <container> iptables -L
  8. Compruebe los registros de los contenedores: docker logs <container>

Utilizar este enfoque sistemático le ayudará a identificar y resolver la mayoría de los problemas de conectividad de contenedores.

Resumen

En este laboratorio, ha aprendido cómo probar y solucionar problemas de conectividad entre contenedores de Docker. Ha:

  • Creado contenedores de Docker y configurado su red
  • Aprendido los conceptos básicos de la red de Docker, incluyendo redes predeterminadas y personalizadas
  • Utilizado varias herramientas para probar la conectividad básica entre contenedores (ping, curl, netcat)
  • Explorado problemas comunes de conectividad y aprendido enfoques sistemáticos para la solución de problemas

Estas habilidades son esenciales para desarrollar y mantener aplicaciones basadas en Docker, especialmente en arquitecturas de microservicios donde múltiples contenedores deben comunicarse entre sí.

Para un aprendizaje adicional, puede explorar Docker Compose para aplicaciones de múltiples contenedores, Docker Swarm o Kubernetes para la orquestación de contenedores, y conceptos de red más avanzados como las redes de superposición para implementaciones multi-host.