¿Cuál es la diferencia entre los puertos docker-compose y los de exposición?

Respuestas:

527

De acuerdo con la referencia docker-compose ,

Los puertos se definen como:

Exponer puertos . Especifique ambos puertos (HOST: CONTAINER) o solo el puerto del contenedor (se elegirá un puerto de host aleatorio).

  • Los puertos mencionados en docker-compose.yml se compartirán entre los diferentes servicios iniciados por docker-compose.
  • Los puertos estarán expuestos a la máquina host a un puerto aleatorio o un puerto determinado.

Mi se docker-compose.ymlparece a:

mysql:
  image: mysql:5.7
  ports:
    - "3306"

Si lo hago docker-compose ps, se verá así:

  Name                     Command               State            Ports
-------------------------------------------------------------------------------------
  mysql_1       docker-entrypoint.sh mysqld      Up      0.0.0.0:32769->3306/tcp

Exponer se define como:

Exponga los puertos sin publicarlos en la máquina host: solo serán accesibles para los servicios vinculados. Solo se puede especificar el puerto interno.

Los puertos no están expuestos a máquinas host, solo están expuestos a otros servicios.

mysql:
  image: mysql:5.7
  expose:
    - "3306"

Si lo hago docker-compose ps, se verá así:

  Name                  Command             State    Ports
---------------------------------------------------------------
 mysql_1      docker-entrypoint.sh mysqld   Up      3306/tcp
bibstha
fuente
24
¿sería posible explicar qué ventajas hay para especificar exposeen un docker-compose? Por lo que puedo decir, no es necesario especificar la exposición para que los puertos sean accesibles a los servicios vinculados.
Jugoso
3
¿No debería decir que los puertos expuestos solo estarán disponibles para los servicios en la misma red de acopladores (el enlace se está reemplazando en la mayoría de las partes)?
miau
8
@Juicy Supongo que es similar a exposeen Dockerfiles: "La instrucción EXPOSE en realidad no publica el puerto. Funciona como un tipo de documentación ..." docs.docker.com/engine/reference/builder/#expose
tsauerwein
1
¿Los puertos anulan cualquier configuración en el nivel de firewall? Acabo de notar que no abrí puertos para mysql en el firewall, pero eran accesibles de forma remota. Tenía los puertos establecidos en "3306: 3306" en lugar de exponer.
TekiusFanatikus
3
Y recuerde, si usa docker-compose run, la definición de puerto en docker-compose.ymlse ignora por defecto. Utilice docker-compose upo proporcione el parámetro--service-ports
Juha Untinen
178

puertos :

  1. Activa el contenedor para escuchar los puertos especificados del mundo fuera de la ventana acoplable (puede ser la misma máquina host o una máquina diferente) Y también un mundo accesible dentro de la ventana acoplable.
  2. Se puede especificar más de un puerto (es por eso que los puertos no son portuarios)

ingrese la descripción de la imagen aquí

exponer :

  1. Activa el contenedor para escuchar un puerto específico solo del mundo dentro de la ventana acoplable Y el mundo no accesible fuera de la ventana acoplable.
  2. Se puede especificar más de un puerto

ingrese la descripción de la imagen aquí

Mehraj Malik
fuente
3
Tenga en cuenta que exponer permite múltiples puertos - docs.docker.com/compose/compose-file/#expose - sin embargo, solo suministra el puerto interno en lugar de interno + externo
Stuart Moore
¿Pero qué hacer si quiero acceder al mundo exterior desde mi contenedor? stackoverflow.com/questions/61322256/…
gstackoverflow
26

Puertos Esta sección se utiliza para definir la asignación entre el servidor host y el contenedor Docker.

ports:
   - 10005:80

Significa que la aplicación que se ejecuta dentro del contenedor está expuesta en el puerto 80. Pero el sistema / entidad externa no puede acceder a ella, por lo que debe asignarse al puerto del servidor host.

Nota: debe abrir el puerto host 10005 y modificar las reglas del firewall para permitir que entidades externas accedan a la aplicación.

Pueden usar

http: // {host IP}: 10005

algo como esto

EXPOSE Esto se usa exclusivamente para definir el puerto en el que se ejecuta la aplicación dentro del contenedor docker.

También puede definirlo en dockerfile. En general, es una práctica buena y ampliamente utilizada definir EXPOSE dentro del dockerfile porque muy raramente alguien los ejecuta en otro puerto que no sea el puerto predeterminado 80

Sorabzone
fuente
19

Puertos

La portssección publicará puertos en el host. Docker configurará un reenvío para un puerto específico desde la red host al contenedor. Por defecto, esto se implementa con un proceso proxy de espacio de usuario ( docker-proxy) que escucha en el primer puerto y reenvía al contenedor, que necesita escuchar en el segundo punto. Si el contenedor no está escuchando en el puerto de destino, aún verá algo escuchando en el host, pero se le negará una conexión si intenta conectarse a ese puerto host, desde el error hacia adelante en su contenedor.

Tenga en cuenta que el contenedor debe estar escuchando en todas las interfaces de red ya que este proxy no se ejecuta dentro del espacio de nombres de red del contenedor y no puede alcanzar 127.0.0.1 dentro del contenedor. El método IPv4 para eso es configurar su aplicación para escuchar 0.0.0.0.

También tenga en cuenta que los puertos publicados no funcionan en la dirección opuesta. No puede conectarse a un servicio en el host desde el contenedor publicando un puerto. En su lugar, encontrará errores de Docker que intentan escuchar el puerto host ya en uso.

Exponer

Exponer es documentación. Establece metadatos en la imagen y, cuando se ejecuta, también en el contenedor. Por lo general, configura esto en el Dockerfile con las EXPOSEinstrucciones, y sirve como documentación para los usuarios que ejecutan su imagen, para que sepan en qué puertos escuchará su aplicación de forma predeterminada. Cuando se configura con un archivo de composición, estos metadatos solo se establecen en el contenedor. Puede ver los puertos expuestos cuando ejecuta un docker inspecten la imagen o el contenedor.

Hay algunas herramientas que dependen de los puertos expuestos. En Docker, el -Pindicador publicará todos los puertos expuestos en puertos efímeros en el host. También hay varios proxys inversos que usarán de manera predeterminada un puerto expuesto al enviar tráfico a su aplicación si no configura explícitamente el puerto del contenedor.

Aparte de esas herramientas externas, la exposición no tiene ningún impacto en la red entre contenedores. Solo necesita una red de acopladores común y conectarse al puerto del contenedor para acceder a un contenedor desde otro. Si esa red es creada por el usuario (por ejemplo, no la red puente predeterminada nombrada bridge), puede usar DNS para conectarse a los otros contenedores.

BMitch
fuente
3

Estoy totalmente de acuerdo con las respuestas anteriores. Solo quiero mencionar que la diferencia entre exposición y puertos es parte del concepto de seguridad en Docker. Va de la mano con la red de Docker. Por ejemplo:

Imagine una aplicación con un front-end web y un back-end de base de datos. El mundo exterior necesita acceso al front-end web (quizás en el puerto 80), pero solo el back-end necesita acceso al host y al puerto de la base de datos. Al usar un puente definido por el usuario, solo se necesita abrir el puerto web, y la aplicación de la base de datos no necesita ningún puerto abierto, ya que el front-end web puede alcanzarlo a través del puente definido por el usuario.

Este es un caso de uso común cuando se configura una arquitectura de red en Docker. Entonces, por ejemplo, en una red puente predeterminada, no se puede acceder a los puertos desde el mundo exterior. Por lo tanto, puede abrir un punto de entrada con "puertos". Con el uso de "exponer" usted define la comunicación dentro de la red. Si desea exponer los puertos predeterminados, no necesita definir "exponer" en su archivo docker-compose.

medTech
fuente