Tipos, Creación y Conexión para tus Contenedores
1. ¡Hablemos de redes! ¿Qué tipos de redes hay en Docker y para qué sirven?.
Docker ofrece varios tipos de redes para facilitar la comunicación entre contenedores y entre contenedores y el mundo exterior. Los tipos principales son:
- Bridge (Puente): Es el tipo de red por defecto. Cuando creas un contenedor sin especificar una red, se conecta a la red
bridge
por defecto. Los contenedores en la misma red puente pueden comunicarse entre sí, y también pueden acceder a la red externa a través del host. Sin embargo, no pueden comunicarse directamente con contenedores en otras redes puente. - Host (Anfitrión): Este tipo de red elimina el aislamiento de red entre el contenedor y el host de Docker. El contenedor usa directamente la pila de red del host. Esto significa que si una aplicación en el contenedor está escuchando en el puerto 80, estará accesible directamente en el puerto 80 del host. Esto proporciona el mejor rendimiento de red, pero sacrifica el aislamiento.
- None (Ninguna): Un contenedor con esta configuración no tiene interfaces de red. Está completamente aislado de la red y no puede comunicarse con otros contenedores o con el host. Se utiliza a menudo para tareas que no requieren conectividad de red, como operaciones de copia de archivos o cálculos fuera de línea.
- Overlay (Superpuesta): Este tipo de red se utiliza para la comunicación entre contenedores que se ejecutan en diferentes demonios de Docker (es decir, en diferentes hosts de Docker). Es fundamental para los enjambres de Docker (Docker Swarm), permitiendo que los servicios se comuniquen sin importar en qué host del enjambre se encuentren los contenedores. Requiere un almacén de clave-valor (como Consul, Etcd o ZooKeeper, o el motor de datos de Swarm) para coordinar la configuración de la red.
- Macvlan: Este controlador de red permite asignar una dirección MAC a un contenedor, haciéndolo aparecer como un dispositivo físico en la red. Esto es útil para aplicaciones heredadas que esperan estar directamente conectadas a la red física, o para escenarios donde los contenedores necesitan una dirección IP en la subred de la red física.
2. ¿Cómo le haces para crear una red nueva en Docker?
Puedes crear una red Docker utilizando el comando docker network create
. La sintaxis básica es:
docker network create [OPTIONS] NETWORK_NAME
Ejemplos:
- Crear una red puente simple:
docker network create my_custom_bridge_network
- Crear una red con una subred y una puerta de enlace específicas:
docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my_specific_network
- Crear una red overlay (para Docker Swarm):
docker network create --driver overlay --attachable my_overlay_network
(Nota: para redes overlay, el host debe ser parte de un Docker Swarm).
3. ¿Cómo podrías conectar un contenedor a una red específica?
Hay dos formas principales de conectar un contenedor a una red específica:
-
Al iniciar el contenedor:
La forma más común es especificar la red al crear el contenedor usando el flag--network
.docker run -d --name my_container --network my_custom_bridge_network nginx
En este ejemplo, el contenedor
my_container
se conectará a la redmy_custom_bridge_network
. -
Conectar un contenedor en ejecución a una red existente:
Puedes usar el comandodocker network connect
para conectar un contenedor que ya está en ejecución a una red.docker network connect my_custom_bridge_network my_container
Esto añadirá el contenedor
my_container
a la redmy_custom_bridge_network
. El contenedor seguirá conectado a cualquier otra red a la que estuviera conectado previamente.
4. ¿Cuál es la diferencia entre la red "bridge" de Docker que viene por defecto y una que creas tú? ¿Hay mucha diferencia?
Aunque ambas son redes de tipo "bridge", existen diferencias clave entre la red puente predeterminada de Docker (bridge
) y una red puente definida por el usuario:
-
Aislamiento y DNS:
- Red
bridge
predeterminada: Los contenedores conectados a la red puente predeterminada pueden comunicarse entre sí por dirección IP, pero no por nombre de contenedor. Para la resolución de nombres, tendrías que usar el servidor DNS del host o vincular los contenedores con el flag--link
(que está en desuso). - Red puente definida por el usuario: Los contenedores conectados a una red puente definida por el usuario pueden comunicarse entre sí tanto por dirección IP como por nombre de contenedor. Docker proporciona un servicio DNS interno que permite la resolución de nombres, lo que simplifica enormemente la comunicación entre servicios. Por ejemplo, si tienes un contenedor
web
y un contenedordb
en la misma red definida por el usuario, el contenedorweb
puede conectarse adb
simplemente usandodb
como nombre de host.
- Red
-
Inter-conectividad:
- Red
bridge
predeterminada: Los contenedores en la redbridge
predeterminada están aislados de los contenedores en otras redes puente predeterminadas. Es decir, si tienes dos aplicaciones, cada una con sus propios contenedores, y ambas usan la redbridge
predeterminada, no se verán entre sí. - Red puente definida por el usuario: Una red puente definida por el usuario es una red separada. Los contenedores conectados a una red
my_app_network
pueden comunicarse entre sí, pero no directamente con los contenedores en la redother_app_network
(a menos que un contenedor esté conectado a ambas redes).
- Red
-
Configuración y control:
- Red
bridge
predeterminada: Es una red fija con una configuración predeterminada que no se puede modificar fácilmente (aparte de las reglas deiptables
). - Red puente definida por el usuario: Ofrecen mucha más flexibilidad. Puedes especificar subredes, rangos de IP, puertas de enlace, adjuntar volúmenes y controlar el comportamiento de la red de forma más granular.
- Red
-
Uso recomendado:
- Red
bridge
predeterminada: Generalmente no se recomienda para aplicaciones de producción o entornos con múltiples servicios. Es más adecuada para pruebas rápidas o contenedores individuales que no necesitan comunicarse con otros contenedores. - Red puente definida por el usuario: Es el enfoque recomendado para la mayoría de las aplicaciones compuestas por múltiples contenedores. Permite un mejor aislamiento, una resolución de nombres más sencilla y un control más fino sobre la red.
- Red
En resumen, las redes puente definidas por el usuario son superiores a la red puente predeterminada en términos de aislamiento, capacidad de descubrimiento de servicios y flexibilidad de configuración, lo que las convierte en la opción preferida para la orquestación de aplicaciones.
5. ¿Y si tengo contenedores en diferentes máquinas (hosts), cómo logro que se 'hablen' entre sí?
Para habilitar la comunicación entre contenedores Docker que se ejecutan en diferentes hosts, la solución principal y más robusta es utilizar redes overlay (superpuestas).
Aquí se explica cómo funciona y los pasos para habilitarlo:
-
Inicializar Docker Swarm: Las redes overlay están intrínsecamente ligadas a Docker Swarm. Necesitarás tener un clúster de Docker Swarm funcionando. Esto implica inicializar un Swarm en un host y unir otros hosts como trabajadores o gerentes.
- En el primer host (manager):
docker swarm init --advertise-addr
- En los hosts adicionales (workers):
docker swarm join --token
:2377
- En el primer host (manager):
-
Crear una red overlay: Una vez que tienes un Swarm funcionando, puedes crear una red overlay. Es crucial usar el flag
--attachable
si quieres conectar contenedores standalone (no parte de un servicio Swarm) a esta red, aunque lo más común es usarla con servicios.docker network create --driver overlay --attachable my_overlay_network
Esta red se propagará automáticamente a todos los nodos del Swarm.
-
Desplegar servicios o contenedores en la red overlay:
-
Con servicios de Docker Swarm (recomendado):
Esta es la forma más común y potente de usar redes overlay. Defines tu aplicación como un servicio de Docker Swarm, especificando que use la red overlay. Docker Swarm se encargará de programar los contenedores en los diferentes nodos y de garantizar que puedan comunicarse.Ejemplo de un archivo
docker-compose.yml
para un servicio Swarm:version: '3.8' services: web: image: nginx ports: - "80:80" networks: - my_overlay_network deploy: replicas: 3 # Los contenedores de 'web' se distribuirán entre los hosts app: image: my_custom_app networks: - my_overlay_network deploy: replicas: 2 networks: my_overlay_network: external: true # Indica que la red ya ha sido creada
Para desplegar:
docker stack deploy -c docker-compose.yml my_app_stack
-
Con contenedores standalone (usando
--attachable
):
Si realmente necesitas ejecutar contenedores standalone en una red overlay (menos común para producción), puedes conectarlos manualmente.# En Host A docker run -d --name container_a --network my_overlay_network alpine ping container_b # En Host B docker run -d --name container_b --network my_overlay_network alpine ping container_a
Los contenedores
container_a
ycontainer_b
ahora podrán comunicarse entre sí por su nombre, a pesar de estar en diferentes hosts.
-
Con servicios de Docker Swarm (recomendado):
¿Cómo funcionan las redes overlay?
Las redes overlay utilizan una tecnología de tunelización (como VXLAN) para encapsular el tráfico de red de los contenedores. Esto crea una "red virtual" que se extiende por múltiples hosts físicos. Cada host del Swarm actúa como un punto final en esta red virtual, y el tráfico entre contenedores en diferentes hosts viaja a través de estos túneles. El control de este enrutamiento y el descubrimiento de servicios se gestionan internamente por Docker Swarm y el almacén de clave-valor subyacente.
Alternativas (menos comunes o para casos de uso específicos):
- Macvlan: Si necesitas que los contenedores tengan direcciones IP directamente en tu red física y se comuniquen como si fueran máquinas individuales en esa red, Macvlan podría ser una opción. Sin embargo, no proporciona el aislamiento y la simplicidad de orquestación de las redes overlay.
- VPN/Túneles a nivel de host: Podrías configurar una VPN o túneles IPsec/OpenVPN entre los hosts de Docker y luego exponer puertos de contenedores a través de esos túneles. Esto es más complejo de gestionar y no es la solución nativa de Docker.
- Exposición de puertos y comunicación a través de la IP del host: Puedes exponer puertos de contenedores en cada host y luego hacer que los contenedores se comuniquen usando la IP del host y el puerto expuesto. Esto es muy manual, no ofrece descubrimiento de servicios y es escalable. No se recomienda para arquitecturas de microservicios distribuidos.