Skip to content

0GiS0/youtube-docker-networking

Repository files navigation

5. Cómo funciona el networking en Docker

¡Hola developer 👋🏻! Este repo contiene las demos mostradas en el vídeo de mi canal de Youtube 5. Cómo funciona el networking en Docker.

3.Crea tus propias imágenes de Docker

Si no has visto el vídeo, te recomiendo que lo hagas para que entiendas el contexto de las demos que se muestran aquí.

Port mapping

Si tenemos contenedores que están a la escucha a través de algún puerto, podemos mapear esos puertos a puertos de nuestro host para poder acceder a ellos.

docker run -d -p 8080:80 nginx

En este caso es fácil adivinar que el contenedor de nginx está a la escucha en el puerto 80, por lo que mapeamos el puerto 8080 de nuestro host al puerto 80 del contenedor. Pero en el caso de que no sepamos en qué puerto está a la escucha el contenedor, podemos averiguarlo con el siguiente comando:

La instrucción EXPOSE nos ayuda a saber en qué puerto está a la escucha el contenedor, siempre y cuando la misma está bien documentada, ya que esta instrucción no tiene ningún efecto en el comportamiento del contenedor.

Podemos inspeccionar una imagen para saber en qué puerto está a la escucha el contenedor:

docker inspect nginx

En el vídeo te muestro otras formas de averiguarlo de una forma gráfica y más sencilla.

También puedes usar un parámetro como parte de la instrucción docker run para que Docker asigne un puerto aleatorio de tu host al puerto del contenedor:

docker run -d --publish-all nginx

o bien, si quieres utilizar un comando más corto:

docker run -d -P nginx

Al igual que cualquier servidor, un contenedor puede estar a la escucha en varios puertos, solo tendrías que hacer que tu código esté a la escucha en varios puertos y en el Dockerfile puedes especificar los puertos que quieres exponer.

FROM nginx

EXPOSE 80/tcp
EXPOSE 80/udp

EXPOSE 8080
EXPOSE 8081
EXPOSE 8082

Este lo tienes en el archivo Dockerfile.port-mapping de este repositorio.

Y de la misma forma que lo hicimos antes, podríamos usar el comando docker run -P para que Docker asigne puertos aleatorios de nuestro host a los puertos del contenedor.

Cómo podemos hacer que los contenedores se comuniquen entre sí

Todos los contenedores que hemos creado hasta ahora siempre han pertenecido a una red, sin tu saberlo. Docker crea una red por defecto para que los contenedores puedan comunicarse entre sí.

Si echamos un vistazo a las redes que tenemos en nuestro sistema, podemos ver que Docker ha creado una red llamada bridge:

docker network ls

Esta es la red por defecto que Docker crea para que los contenedores puedan comunicarse entre sí.

Network bridge

Si queremos ver el detalle de la misma, podemos hacerlo con el siguiente comando:

docker network inspect bridge

El resultado tiene un apartado llamado Containers que nos muestra los contenedores que pertenecen a esta red. Cada uno de ellos tiene su propia dirección IP. Te puedes dar cuenta además de que los rangos de esta red no son el mismo que el de tu host, esto es porque Docker crea una red virtual para que los contenedores puedan comunicarse entre sí. Si quieres que los contenedores se comuniquen entre sí, puedes hacerlo a través de la dirección IP de cada contenedor.

Puedes utilizar el contenedor busybox para hacer ping a otro contenedor.

docker run -it --rm busybox

Una vez dentro del contenedor, puedes hacer una llamada a otro contenedor. Por ejemplo, si el otro contenedor es un servidor web y está a la escucha en el puerto 80, puedes hacer un wget a la dirección IP del contenedor:

wget -qO-  http://172.17.0.2

Network host

Esta red nos permite que el contenedor comparta la red del host. Esto significa que el contenedor no tendrá su propia dirección IP, sino que compartirá la misma que el host.

docker run -d --network host nginx

En este caso el contenedor de nginx no tiene su propia dirección IP, sino que comparte la misma que el host. Por lo que si abro un navegador y pongo http://localhost, veré el contenido del contenedor de nginx.

En el pasado esto no era posible probarlo con Docker Desktop pero con las versiones más recientes del mismo ya es posible como puedes ver en el vídeo.

Network none

Este tipo de red no tiene acceso a la red del host ni a la red de otros contenedores.

docker run -it --rm --network none busybox

Si ahora lanzo un ifconfig dentro del contenedor, verás que no tiene ninguna interfaz de red.

ifconfig

Solo tiene la interfaz lo que es la interfaz de loopback.

Crea tus propias redes

Cuando instalamos Docker viene de caja un servidor DNS pero solo funciona en las redes que creamos nosotros. Y para crear nuestras propias redes, podemos hacerlo con el siguiente comando:

docker network create returngis

A partir de este momento tenemos una nueva red para nuestros contenedores. He creado un nuevo Dockerfile llamado Dockerfile.network-testpara las pruebas con esta red. Puedes generar la imagen utilizando este comando:

docker build -t ubuntu-with-net-tools -f Dockerfile.network-test .

Y ahora lo siguiente que vamos a hacer es crearnos dos contenedores que formen parte de la nueva red:

docker run --name donpepito --network returngis -it ubuntu-with-net-tools

Ahora haz un split del terminal para crear el segundo contenedor:

docker run --name donjose --network returngis -it ubuntu-with-net-tools

Y a partir de este momento puedes hacer ping de un contenedor a otro:

ping donjose

o desde el otro contenedor:

ping donpepito

También podrías hacer un ping directamente a la dirección IP del contenedor:

ping 172.18.0.2

O desde el otro contenedor:

ping 172.18.0.3

Cómo ejecutar la aplicación de ejemplo Tour Of Heroes

Durante el vídeo te explico todos los cambios que he realizado en la API de Tour Of Heroes para que pueda comunicarse con la base de datos. El código de la misma esta en el directorio tour-of-heroes-api.

Ahora para ejecutar la misma lo primero que necesitas es crear una red:

docker network create tour-of-heroes-vnet

Creamos la base de datos dentro de la red:

docker run --name db -e ACCEPT_EULA=Y -e SA_PASSWORD=Password123 -d -p 1433:1433 --network tour-of-heroes-vnet -d mcr.microsoft.com/azure-sql-edge

Ahora generamos la imagen de la API:

cd tour-of-heroes-api
docker build -t tour-of-heroes-api:v1 .

Y una vez que finalice la misma, ejecutamos el contenedor:

docker run --name api --network tour-of-heroes-vnet -p 5051:5000 -d  tour-of-heroes-api:v1

En este caso la API si que está expuesto porque el frontal web necesita comunicarse con la misma.

Si quieres probar el frontal web en Angular necesitas crear la imagen de la misma:

cd tour-of-heroes-angular
docker build -t tour-of-heroes-web:v1 -f Dockerfile.gh-copilot .

Y y a para finalizar ejecutamos el contenedor:

docker run --name web --network tour-of-heroes-vnet -p 80:80 -d tour-of-heroes-web:v1

Para entender mejor todos estos conceptos, te recomiendo que veas el vídeo de mi canal de Youtube 5. Cómo funciona el networking en Docker.

¡Nos vemos 👋🏻!