tutorial - docker windows




Quelle est la différence entre "exposer" et "publier" dans Docker? (4)

J'expérimente Dockerfiles, et je pense que je comprends la plupart de la logique. Cependant, je ne vois pas la différence entre "exposer" et "publier" un port dans ce contexte.

Tous les tutoriels que j'ai vu en premier comprennent la commande EXPOSE dans le Dockerfile:

...
EXPOSE 8080
...

Ils construisent ensuite une image à partir de ce Dockerfile:

$ docker build -t an_image - < Dockerfile

Puis publiez le même port que ci-dessus lors de l'exécution de l'image:

$ docker run -d -p 8080 an_image

ou publier tous les ports en utilisant

$ docker run -d -P an_image

À quoi sert d'exposer un port dans le Dockerfile, s'il sera publié de toute façon? Serait-il nécessaire d'exposer un port en premier et de ne pas le publier plus tard? Effectivement, je voudrais spécifier tous les ports que je vais utiliser dans le Dockerfile lors de la création de l'image, puis ne pas les déranger à nouveau, en les exécutant simplement avec:

$ docker run -d an_image

Est-ce possible?


Réponse courte:

  • EXPOSE est un moyen de documenter
  • --publish est un moyen de mapper un port hôte à un port de conteneur

Notez ci-dessous les liens entre:

  • EXPOSE et Dockerfile
  • --publish et run-time ( docker run ... )

Exposer et publier des ports

Dans la mise en réseau Docker, il existe deux mécanismes différents qui impliquent directement les ports réseau: l'exposition et la publication des ports. Cela s'applique au réseau de pont par défaut et aux réseaux de ponts définis par l'utilisateur.

  • Vous exposez les ports en utilisant le mot clé EXPOSE dans le fichier Docker ou l'indicateur --expose l' --expose du --expose . L'exposition des ports permet de documenter les ports utilisés, mais ne permet pas de mapper ou d'ouvrir les ports. L'exposition des ports est facultative .

  • Vous publiez des ports en utilisant l' --publish ou --publish-all pour l' docker run . Cela indique à Docker quels ports ouvrir sur l'interface réseau du conteneur. Lorsqu'un port est publié, il est mappé sur un port d'ordre supérieur disponible (supérieur à 30000 ) sur la machine hôte, sauf si vous spécifiez le port à mapper sur la machine hôte lors de l'exécution. Vous ne pouvez pas spécifier le port à mapper sur l'ordinateur hôte lorsque vous générez l'image (dans le fichier Docker), car il est impossible de garantir que le port sera disponible sur l'ordinateur hôte sur lequel vous exécutez l'image .

de: Mise en réseau des conteneurs Docker

Aussi,

EXPOSER

... L'instruction EXPOSE ne publie pas le port. Il fonctionne comme un type de documentation entre la personne qui construit l'image et la personne qui gère le conteneur, à propos des ports qui sont destinés à être publiés .

de: documentation

Accès au service lorsque EXPOSE / --publish n'est pas défini:

À réponse de il est indiqué que:

"Si vous n'en spécifiez aucun, le service dans le conteneur ne sera accessible que depuis l'intérieur du conteneur lui-même ."

Peut-être que c'était le cas au moment où la réponse a été écrite, mais maintenant il semble que même si vous n'utilisez pas EXPOSE ou --publish , l' host et les autres containers du même réseau pourront accéder à un service que vous pouvez commencer à l'intérieur de ce conteneur .

Pour mes tests j'ai utilisé le Dockerfile suivant. Fondamentalement, je commence avec ubuntu et installe un minuscule serveur web:

FROM ubuntu
RUN apt-get update && apt-get install -y mini-httpd

Je build l'image comme "testexpose" et run un nouveau conteneur avec:

docker run --rm -it testexpose bash

À l'intérieur du conteneur, je lance quelques instances de mini-httpd :

[email protected]:/# mini_httpd -p 80
[email protected]:/# mini_httpd -p 8080
[email protected]:/# mini_httpd -p 8090

Je suis alors capable d'utiliser curl partir de l'hôte ou d'autres conteneurs pour aller chercher la page d'accueil de mini-httpd .


Fondamentalement, vous avez trois options:

  • Ni spécifier EXPOSE ni -p .
  • EXPOSE .
  • Spécifiez EXPOSE et -p .

Si vous n'en spécifiez aucun, le service dans le conteneur ne sera accessible que depuis l'intérieur du conteneur lui-même.

Si vous EXPOSE un port, le service dans le conteneur n'est pas accessible depuis l'extérieur de Docker, mais à partir d'autres conteneurs Docker. C'est donc bon pour la communication entre conteneurs.

Si vous EXPOSE et -p un port, le service dans le conteneur est accessible de n'importe où, même en dehors de Docker.

La raison pour laquelle les deux sont séparés est à mon humble avis parce que

  • le choix d'un port hôte dépend de l'hôte et n'appartient donc pas au fichier Docker (sinon, cela dépend de l'hôte),
  • et souvent c'est suffisant si un service dans un conteneur est accessible à partir d'autres conteneurs.

La documentation indique explicitement:

L'instruction EXPOSE expose les ports à utiliser dans les liens.

Il vous indique également comment lier les conteneurs , ce qui est essentiellement la communication inter-conteneurs dont j'ai parlé.

PS: Si vous faites -p , mais EXPOSE pas, Docker fait un EXPOSE implicite. En effet, si un port est ouvert au public, il est automatiquement ouvert aux autres conteneurs Docker. Par conséquent, -p comprend EXPOSE . C'est pourquoi je ne l'ai pas listé ci-dessus comme un quatrième cas.


La plupart des gens utilisent docker composer avec des réseaux. La documentation stipule:

La fonction de réseau Docker prend en charge la création de réseaux sans avoir à exposer les ports du réseau. Pour plus d'informations, voir la présentation de cette fonctionnalité).

Ce qui signifie que si vous utilisez des réseaux pour la communication entre les conteneurs, vous n'avez pas à vous soucier d'exposer les ports.


Vous exposez les ports en utilisant le mot clé EXPOSE dans le fichier Docker ou l'indicateur --expose sur l'exécution du menu fixe. L'exposition des ports permet de documenter les ports utilisés, mais ne permet pas de mapper ou d'ouvrir les ports. L'exposition des ports est facultative.

Source: commit de github







docker