Docker: diferencia entre port y expose

0
11844
Logotipo de docker

En una red informática, la comunicación entre los distintos dispositivos que la componen es algo esencial y básico. Lo mismo sucede cuando utilizamos algún tipo de sistema de containers como puede ser docker o CRIO. En esta entrada vamos a explicar la diferencia que existe entre el parámetro «PORT» y «EXPOSE» y lo vamos a explicar con dos casos prácticos para que podáis visualizarlo sin problemas.

Tal y como describe docker estos parámetros realizan la siguiente acción:

La instrucción «EXPOSE» indica los puertos en los que un contenedor escucha conexiones. En consecuencia, debe utilizar el puerto tradicional común para su aplicación.

La instrucción «PORT» hace que un puerto esté disponible para servicios fuera de Docker o para contenedores de Docker que no están conectados a la red del contenedor.

A priori puede parecer cosas parecidas pero nada más lejos de la realidad, son cosas totalmente distintas. Una cosa vendría a ser el equivalente a abrir un puerto en una red y el otro a realizar una «NAT». Aquí te dejo información oficial relativa a docker networking.

Docker utiliza redes internas para gestionar todo el tráfico de los contenedores, de esta forma los contenedores establecen las comunicaciones al igual que una red física al uso. Pero qué haremos cuando necesitamos acceder desde fuera de nuestra red de docker a un servicio alojado en docker o incluso internamente dentro de nuestra red de dockers?.

Ahí es donde entran en juego los parámetros «PORT» y «EXPOSE». Para ello usaremos el sigueinte docker-compose.yaml:

version: '3.9'
services:
  web1:
    image: nginx:stable-alpine
    ports:
      - "80:80"
  web2:
    image: nginx:stable-alpine
    ports:
      - "81:80"

Levantaremos dos servidores webs con nginx, uno en el puerto 80 y otro en el 81. Si accedemos ahora con nuestro navegador a la IP del servidor de docker o a localhost si lo estamos corriendo en local, podremos observar que tanto para el puerto 80 como el 81, nos devuelve la página por defecto de Nginx.

La diferencia es que uno se utiliza para exponer el contenedor fuera de la red de docker y el otro en la red interna de docker.

Ahora vamos a modificar el docker-compose.yml anterior de la siguiente manera:

  web2:
    image: nginx:stable-alpine
    expose:
      - "80/tcp"

Realizaremos la misma acción, pero esta vez veremos que en el puerto 81 ya no podemos visualizar la página por defecto de Nginx, qué ha pasado?

Comprobaremos las ips de nuestros contenedores:

[root@192 port_vs_expose]# docker exec -it port_vs_expose_web1_1 ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
30: eth0@if31: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:15:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.22.0.2/16 brd 172.22.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@192 port_vs_expose]# docker exec -it port_vs_expose_web2_1 ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
32: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:15:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.22.0.3/16 brd 172.22.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@192 port_vs_expose]#

Como podéis ver, las IP’s internas de docker son las siguientes, 172.22.0.2 para el contenedor que tiene port y 172.22.0.3 para el contenedor que tiene expose. Ejecutando el siguiente comando, podremos observar como el contenedor que tiene «EXPOSE» nos sigue devolviendo la web por defecto de nginx.

docker exec -it port_vs_expose_web1_1 curl 172.22.0.3

Esto sucede porque internamente, dentro de la red de docker, ese puerto está expuesto en la red, pero no está expuesto fuera de la red de docker. Esta es la diferencia entre utilizar «EXPOSE» y «PORT».

Aquí te dejo otra entrada para utilizar Amazon Linux 2 on-premise, no te la piérdas!.

¡Hasta la próxima!

DEJA UNA RESPUESTA

Por favor ingrese su comentario!
Por favor ingrese su nombre aquí