GNU/Linux >> Tutoriels Linux >  >> Panels >> Docker

Comment exposer ou publier le port Docker

Dans une configuration multi-conteneurs, les services exécutés dans les conteneurs communiquent entre eux sur un réseau commun. Dans la même configuration, certains conteneurs interagissent également avec le monde extérieur.

Cette communication interne et externe est gérée respectivement avec les ports exposés et publiés dans Docker.

Dans ce didacticiel, je vais discuter de la gestion des ports dans Docker. Je vais continuer sur la différence entre l'exposition et la publication des ports, pourquoi ils sont utilisés et comment les utiliser.

Exposer vs publier un port dans Docker

Il existe deux manières de gérer les ports dans Docker :exposer les ports et publier les ports.

Exposer un port signifie simplement faire savoir aux autres sur quel port l'application conteneurisée va écouter ou accepter les connexions. C'est pour communiquer avec d'autres conteneurs, pas avec le monde extérieur.

Publier un port ressemble plus à mapper les ports d'un conteneur avec les ports de l'hôte. De cette façon, le conteneur est capable de communiquer avec des systèmes externes, le monde réel, Internet.

Ce graphique vous aidera à comprendre.

Vous voyez, comment le port 80 du conteneur SERVER est mappé sur le port 80 du système hôte ? De cette façon, le conteneur est capable de communiquer avec le monde extérieur en utilisant l'adresse IP publique du système hôte.

Les ports exposés, en revanche, ne sont pas accessibles directement depuis l'extérieur du monde des conteneurs.

A retenir :

  • Les ports exposés sont utilisés pour la communication interne des conteneurs, dans le monde des conteneurs.
  • Les ports publiés sont utilisés pour communiquer avec des systèmes extérieurs au monde des conteneurs.
Quelle est la différence entre les ports docker-compose et exposeQuelle est la différence entre les ports et les options d'exposition dans docker-compose.yml Débordement de pileBibek Shrestha

Exposer les ports dans Docker

Tout d'abord, exposer un port n'est pas strictement nécessaire. Pourquoi? Parce que la plupart des images Docker que vous utilisez dans votre configuration ont déjà un port par défaut exposé dans leur configuration.

Par exemple, une application frontale conteneurisée peut communiquer avec une base de données MariaDB en spécifiant simplement l'adresse IP du conteneur et le port sur lequel MariaDB accepte les connexions (3306 par défaut).

L'exposition aide dans une situation où les valeurs par défaut ne sont pas utilisées, comme dans ce cas si MariaDB n'acceptait pas les connexions sur le port 3306, un port alternatif doit être mentionné en l'exposant.

Il existe deux manières d'exposer un port :

  1. Utiliser EXPOSE Instruction Dockerfile.
  2. Utiliser --expose avec docker CLI ou expose clé dans docker-compose.

Il est temps de plonger plus profondément dans les deux.

Méthode 1 :exposer les ports via Dockerfile

Vous pouvez ajouter une instruction simple dans votre Dockerfile pour faire savoir aux autres sur quel port votre application acceptera les connexions.

À propos de cette instruction, ce que vous devez savoir est ce qui suit :-

  • EXPOSE ne le fait pas ajoutez des couches supplémentaires à l'image docker résultante. Il ajoute simplement des métadonnées.
  • EXPOSE est un moyen de documenter votre port d'application. Le seul effet qu'il a est en termes de lisibilité ou de compréhension de l'application.

Vous pouvez voir comment expose fonctionne avec une simple image de conteneur que j'ai créée à cet effet. Cette image ne fait rien .

Tirez l'image.

docker pull debdutdeb/expose-demo:v1

Cette image expose un total de quatre ports, répertoriez l'image à l'aide de la commande suivante.

docker image ls --filter=reference=debdutdeb/expose-demo:v1

Jetez un oeil à la SIZE colonne, il indiquera 0 octet.

➟ docker image ls --filter=reference=debdutdeb/expose-demo:v1
REPOSITORY              TAG       IMAGE ID       CREATED   SIZE
debdutdeb/expose-demo   v1        ad3d8ffa9bfe   N/A       0B

La raison est simple, il n'y a pas de calques dans cette image, toutes les instructions d'exposition ajoutées étaient des métadonnées, pas de vrais calques.

Vous pouvez également obtenir le nombre de calques disponibles à l'aide de la commande suivante :-

docker image inspect -f '{{len .RootFS.Layers}}' debdutdeb/expose-demo:v1

Vous devriez voir une sortie comme celle-ci :-

➟ docker image inspect -f '{{len .RootFS.Layers}}' debdutdeb/expose-demo:v1 
0

Comme je l'ai dit précédemment, les ports exposés sont ajoutés en tant que métadonnées d'image, pour nous faire savoir quels ports l'application utilise.

Comment voyez-vous ces informations sans consulter un Dockerfile ? Vous devez inspecter l'image. Pour être plus précis, voir la commande ci-dessous, vous pouvez utiliser une commande similaire sur n'importe quelle image pour répertorier les ports exposés.

J'utilise mon exemple d'image pour la démonstration.

docker image inspect -f \
	'{{range $exposed, $_ := .Config.ExposedPorts}}{{printf "%s\n" $exposed}}{{end}}' \
    debdutdeb/expose-demo:v1

Exemple de sortie :

➟ docker image inspect -f '{{range $exposed, $_ := .Config.ExposedPorts}}{{printf "%s\n" $exposed}}{{end}}' debdutdeb/expose-demo:v1 
443/tcp
80/tcp
8080/tcp
9090/tcp

Vous pouvez également comparer cette image, qui expose quelques ports, avec le debdutdeb/noexpose-demo:v1 image, qui n'expose aucun port. Exécutez également le même ensemble de commandes sur cette image et remarquez la différence.

Méthode 2 :exposer les ports via CLI ou docker-compose

Parfois, les développeurs d'applications hésitent à inclure un EXPOSE supplémentaire instruction dans leur Dockerfile.

Dans un tel cas, pour vous assurer que d'autres conteneurs (via l'API Docker) peuvent détecter facilement le port utilisé, vous pouvez exposer plusieurs ports après la construction, dans le cadre du processus de déploiement.

Choisissez soit la méthode impérative, c'est-à-dire la CLI, soit la méthode déclarative, c'est-à-dire composer des fichiers.

Méthode CLI

Dans cette méthode, lors de la création d'un conteneur, tout ce que vous avez à faire est d'utiliser le --expose option (autant de fois que nécessaire) avec le numéro de port et éventuellement le protocole avec un / . Voici un exemple :-

docker container run \
	--expose 80 \
    --expose 90 \
    --expose 70/udp \
    -d --name port-expose busybox:latest sleep 1d

J'utilise la busybox image qui n'expose aucun port par défaut.

Méthode de composition de fichier

Si vous utilisez un fichier de composition, vous pouvez ajouter un tableau expose dans la définition du service. Vous pouvez convertir le déploiement précédent en un fichier de composition comme ceci :-

version: "3.7"
services:
	PortExpose:
    	image: busybox
        command: sleep 1d
        container_name: port-expose
        expose:
        	- 80
            - 90
            - 70/udp

Une fois que le conteneur est en cours d'exécution, comme avant, vous pouvez l'inspecter pour savoir quels ports sont exposés. La commande ressemble.

docker container inspect -f \
	'{{range $exposed, $_ := .NetworkSettings.Ports}}
    {{printf "%s\n" $exposed}}{{end}}' \
    port-expose

Exemple de sortie :-

➟ docker container inspect -f '{{range $exposed, $_ := .NetworkSettings.Ports}}{{printf "%s\n" $exposed}}{{end}}' port-expose 
70/udp
80/tcp
90/tcp

Publier un port dans Docker

La publication de port est synonyme de redirection de port où les requêtes d'une connexion entrante sur un port public sont transmises au port du conteneur.

De même, les réponses envoyées depuis le conteneur via son port sont envoyées au client en transférant le trafic vers le port spécifié dans l'espace de port de l'hôte.

Il existe deux manières de publier un port, l'une via la CLI et l'autre à l'aide d'un fichier de composition. Les deux méthodes ont également une syntaxe longue et une syntaxe courte.

Méthode 1 :publier les ports via la commande Docker

Les deux syntaxes sont les suivantes :

  1. -p [optional_host_ip]:[host_port]:[container_port]/[optional_protocol]
  2. --publish target=[container_port],published=[optional_host_ip]:[host_port],protocol=[optional_protocol]
Pour l'adresse IP facultative de l'hôte, vous pouvez utiliser n'importe quelle adresse IP associée à l'une des cartes réseau. Si l'adresse IP est omise, docker liera le port avec toutes les adresses IP disponibles.

Vous utiliserez le plus le premier. Le second est plus lisible. Voyons un exemple utilisant un conteneur nginx. Exécutez la commande suivante :-

docker container run --rm --name nginx \
	--publish target=80,published=127.0.0.1:8081,protocol=tcp \
    -d nginx

Avec cette commande, je lie simplement le port 80 du conteneur au port 8081 de mon hôte sur localhost. Maintenant, si vous vous dirigez vers http://localhost:8081, vous verrez nginx en cours d'exécution.

La commande précédente peut être facilement convertie en une forme plus courte comme ceci

docker container run --rm --name nginx \
	-p 80:127.0.0.1:8081/tcp -d nginx

Bien qu'il soit plus court, il est plus difficile à lire.

Vous pouvez également utiliser -p ou --publish plusieurs fois pour publier plusieurs ports.

Méthode 2 :publication d'un port via un fichier de composition

Pour publier un port à l'aide d'un fichier de composition, vous aurez besoin d'un tableau nommé ports dans la définition du service. Ce tableau peut être une liste de chaînes qui ressemble à la syntaxe courte de la CLI, ou vous pouvez utiliser une liste d'objets qui est similaire à la syntaxe longue.

Si je devais convertir le déploiement précédent de nginx à l'aide d'un fichier de composition avec un tableau de chaînes pour la section des ports, cela ressemblerait à ceci :-

version: "3.7"
services:
	Nginx:
    	image: nginx
		container_name: nginx
        ports:
        	- 80:127.0.0.1:8081/tcp

Permettez-moi également de montrer comment utiliser la syntaxe du tableau d'objets.

version: "3.7"
services:
	Nginx:
    	image: nginx
        container_name: nginx
        ports:
        	- target: 80
              published: 127.0.0.1:8081
              protocol: tcp

Pour voir la liste de tous les ports publiés, vous pouvez inspecter le conteneur comme ceci-

docker container inspect -f '{{range $container, $host := .NetworkSettings.Ports}}{{printf "%s -> %s\n" $container $host}}{{end}}' nginx

S'il est exécuté, vous verrez la sortie suivante :-

➟ docker container inspect -f '{{range $container, $host := .NetworkSettings.Ports}}{{printf "%s -> %s\n" $container $host}}{{end}}' nginx 
80/tcp -> [{127.0.0.1 8081}]

Il existe un autre moyen plus simple de répertorier les ports publiés, en utilisant le docker container port commande.

docker container port nginx

Exemple de sortie :-

➟ docker container port nginx
80/tcp -> 127.0.0.1:8081

Quand exposer un port et quand le publier ?

C'est une bonne question. L'exposition et l'édition ne sont pas censées être des concurrents. Chacun sert un objectif différent. Si vous êtes le développeur d'une image, vous exposerez les ports afin que l'utilisateur puisse mieux savoir où tenter une connexion. D'un autre côté, si vous utilisez une image et que vous devez la rendre accessible au monde extérieur, vous allez publier les ports nécessaires.

J'espère que cet article vous a été utile. Si vous avez des questions, faites-le moi savoir dans les commentaires ci-dessous.


Docker
  1. Comment installer Jenkins avec Docker

  2. Comment utiliser Docker Compose

  3. Comment connecter des conteneurs Docker

  4. Comment exécuter ssh sur plusieurs ports

  5. Docker Basics - Exposez les ports, la liaison de port et le lien docker

Comment installer Docker CE dans Linux Mint 20

Comment utiliser Netcat pour analyser les ports ouverts sous Linux

Comment exposer ou publier le port Docker

Comment supprimer les conteneurs Docker

Comment arrêter les conteneurs Docker

Comment installer Docker sur Mac