GNU/Linux >> LINUX-Kenntnisse >  >> Panels >> Docker

So zeigen oder veröffentlichen Sie den Docker-Port

In einem Multi-Container-Setup kommunizieren die in den Containern ausgeführten Dienste über ein gemeinsames Netzwerk miteinander. Im selben Setup interagieren einige Container auch mit der Außenwelt.

Diese interne und externe Kommunikation wird mit exponierten bzw. veröffentlichten Ports in Docker abgewickelt.

In diesem Tutorial werde ich den Umgang mit Ports in Docker besprechen. Ich werde weiter auf den Unterschied zwischen dem Freigeben und Veröffentlichen von Ports eingehen, warum sie verwendet werden und wie sie verwendet werden.

Offenlegen vs. Veröffentlichen eines Ports in Docker

Es gibt zwei Möglichkeiten, Ports in Docker zu behandeln:Offenlegen der Ports und Veröffentlichen der Ports.

Einen Port verfügbar machen bedeutet einfach, anderen mitzuteilen, auf welchem ​​Port die containerisierte Anwendung lauschen wird, oder Verbindungen zu akzeptieren. Dies dient der Kommunikation mit anderen Containern, nicht mit der Außenwelt.

Veröffentlichen eines Ports ist eher wie das Mapping der Ports eines Containers mit den Ports des Hosts. Auf diese Weise kann der Container mit externen Systemen, der realen Welt, dem Internet kommunizieren.

Diese Grafiken helfen Ihnen beim Verständnis.

Sehen Sie, wie der Port 80 des SERVER-Containers auf den Port 80 des Hostsystems abgebildet wird? Auf diese Weise kann der Container über die öffentliche IP-Adresse des Hostsystems mit der Außenwelt kommunizieren.

Auf die exponierten Ports hingegen kann von außerhalb der Containerwelt nicht direkt zugegriffen werden.

Zur Erinnerung:

  • Offengelegte Ports werden für die interne Containerkommunikation innerhalb der Containerwelt verwendet.
  • Veröffentlichte Ports werden für die Kommunikation mit Systemen außerhalb der Containerwelt verwendet.
Was ist der Unterschied zwischen Docker-Compose-Ports und ExposeWas ist der Unterschied zwischen Ports und Expose-Optionen in docker-compose.yml StapelüberlaufBibek Shrestha

Ports in Docker verfügbar machen

Zunächst einmal ist das Freilegen eines Ports nicht unbedingt erforderlich. Wieso den? Weil die meisten Docker-Images, die Sie in Ihrem Setup verwenden, bereits einen Standardport in ihrer Konfiguration offengelegt haben.

Beispielsweise kann eine containerisierte Frontend-Anwendung mit einer MariaDB-Datenbank kommunizieren, indem sie einfach die IP des Containers und den Port angibt, auf dem MariaDB Verbindungen akzeptiert (Standard 3306).

Das Offenlegen hilft in einer Situation, in der die Standardwerte nicht verwendet werden, wie in diesem Fall, wenn MariaDB keine Verbindungen auf Port 3306 akzeptieren würde, sollte ein alternativer Port durch Offenlegen erwähnt werden.

Es gibt zwei Möglichkeiten, wie Sie einen Port verfügbar machen können:

  1. Mit dem EXPOSE Dockerfile-Anweisung.
  2. Mit --expose mit docker CLI oder expose Geben Sie docker-compose ein.

Zeit, tiefer in beide einzutauchen.

Methode 1:Ports über Dockerfile verfügbar machen

Sie können Ihrer Docker-Datei eine einfache Anweisung hinzufügen, um andere wissen zu lassen, an welchem ​​Port Ihre Anwendung Verbindungen akzeptiert.

Was Sie über diese Anleitung wissen müssen, ist Folgendes:-

  • EXPOSE nicht Fügen Sie dem resultierenden Docker-Image zusätzliche Ebenen hinzu. Es fügt nur Metadaten hinzu.
  • EXPOSE ist eine Art der Dokumentation Ihr Anwendungsport. Der einzige Effekt ist die Lesbarkeit oder das Verständnis der Anwendung.

Sie können sehen, wie Expose mit einem einfachen Container-Image funktioniert, das ich nur für diesen Zweck erstellt habe. Dieses Bild macht nichts .

Ziehen Sie das Bild.

docker pull debdutdeb/expose-demo:v1

Dieses Image legt insgesamt vier Ports offen, listen Sie das Image mit dem folgenden Befehl auf.

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

Sehen Sie sich die SIZE an Spalte, es wird 0 Bytes sagen.

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

Der Grund ist einfach, es gibt keine Ebenen in diesem Bild, alle hinzugefügten Belichtungsanweisungen waren Metadaten, keine echten Ebenen.

Sie können die Anzahl der verfügbaren Ebenen auch mit dem folgenden Befehl abrufen:-

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

Sie sollten eine Ausgabe wie diese sehen:-

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

Wie ich bereits sagte, werden die exponierten Ports als Bildmetadaten hinzugefügt, um uns mitzuteilen, welche Ports die Anwendung verwendet.

Wie sehen Sie diese Informationen, ohne sich eine Dockerfile anzusehen? Sie müssen das Bild überprüfen. Um genauer zu sein, siehe den folgenden Befehl. Sie können einen ähnlichen Befehl für jedes Image verwenden, um die exponierten Ports aufzulisten.

Ich verwende mein Beispielbild zur Demonstration.

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

Beispielausgabe:

➟ 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

Sie können dieses Image, das einige Ports offenlegt, auch mit debdutdeb/noexpose-demo:v1 vergleichen Bild, das keine Ports offenlegt. Führen Sie denselben Befehlssatz auch für dieses Bild aus und bemerken Sie den Unterschied.

Methode 2:Verfügbarmachen von Ports über CLI oder docker-compose

Manchmal scheuen Anwendungsentwickler davor zurück, ein zusätzliches EXPOSE einzufügen Anleitung in ihrer Dockerfile.

Um sicherzustellen, dass andere Container (über die Docker-API) den verwendeten Port problemlos erkennen können, können Sie in einem solchen Fall mehrere Ports nach dem Build als Teil des Bereitstellungsprozesses verfügbar machen.

Wählen Sie entweder die imperative Methode, d. h. die CLI, oder die deklarative Methode, d. h. Dateien erstellen.

CLI-Methode

Bei dieser Methode müssen Sie beim Erstellen eines Containers lediglich --expose verwenden Option (so oft wie nötig) mit der Portnummer und optional dem Protokoll mit einem / . Hier ist ein Beispiel:-

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

Ich verwende die busybox Bild, das standardmäßig keine Ports verfügbar macht.

Dateimethode erstellen

Wenn Sie eine Compose-Datei verwenden, können Sie ein Array expose hinzufügen in der Dienstdefinition. Sie können die vorherige Bereitstellung wie folgt in eine Compose-Datei konvertieren:-

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

Sobald Sie den Container ausgeführt haben, können Sie ihn genau wie zuvor überprüfen, um zu wissen, welche Ports verfügbar gemacht werden. Der Befehl sieht ähnlich aus.

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

Beispielausgabe:-

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

Veröffentlichen eines Ports in Docker

Port-Publishing ist ein Synonym für Port-Forwarding, bei dem die Anfragen einer eingehenden Verbindung auf einem öffentlichen Port an den Port des Containers weitergeleitet werden.

In ähnlicher Weise werden die vom Container über seinen Port gesendeten Antworten an den Client gesendet, indem der Datenverkehr an den angegebenen Port im Portbereich des Hosts weitergeleitet wird.

Es gibt zwei Möglichkeiten, einen Port zu veröffentlichen, eine über die CLI und eine andere mithilfe einer Compose-Datei. Beide Methoden haben auch eine lange Syntax und eine kurze Syntax.

Methode 1:Ports per Docker-Befehl veröffentlichen

Die beiden Syntaxen lauten wie folgt:

  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]
Für die optionale Host-IP können Sie jede IP-Adresse verwenden, die mit einer der NICs verknüpft ist. Wenn die IP weggelassen wird, bindet Docker den Port mit allen verfügbaren IP-Adressen.

Sie werden den ersten am häufigsten verwenden. Der zweite ist besser lesbar. Sehen wir uns ein Beispiel mit einem Nginx-Container an. Führen Sie den folgenden Befehl aus:-

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

Mit diesem Befehl binde ich einfach den Port 80 des Containers an den Port 8081 meines Hosts auf localhost. Wenn Sie jetzt zu http://localhost:8081 gehen, sehen Sie, dass nginx ausgeführt wird.

Der vorherige Befehl kann einfach so in die kürzere Form umgewandelt werden

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

Obwohl es kürzer ist, ist es schwieriger zu lesen.

Sie können auch -p verwenden oder --publish mehrmals, um mehrere Ports zu veröffentlichen.

Methode 2:Veröffentlichen eines Ports über eine Compose-Datei

Um einen Port mit einer Compose-Datei zu veröffentlichen, benötigen Sie ein Array namens ports in der Dienstdefinition. Dieses Array kann eine Liste von Strings sein, die der kurzen Syntax der CLI ähneln, oder Sie können eine Liste von Objekten verwenden, die der langen Syntax ähnelt.

Wenn ich die vorherige nginx-Bereitstellung mithilfe einer Compose-Datei mit einem Array von Zeichenfolgen für den Ports-Abschnitt konvertieren würde, würde es wie folgt aussehen:-

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

Lassen Sie mich auch zeigen, wie die Array-of-Objects-Syntax verwendet wird.

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

Um die Liste aller veröffentlichten Ports zu sehen, können Sie den Container wie folgt untersuchen:

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

Wenn Sie es ausführen, sehen Sie die folgende Ausgabe:-

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

Es gibt eine andere, einfachere Möglichkeit, die veröffentlichten Ports aufzulisten, indem Sie den docker container port verwenden Befehl.

docker container port nginx

Beispielausgabe:-

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

Wann soll ein Port offengelegt und wann veröffentlicht werden?

Das ist eine berechtigte Frage. Ausstellen und Publizieren sollen keine Konkurrenten sein. Jeder dient einem anderen Zweck. Wenn Sie der Entwickler eines Images sind, legen Sie die Ports offen, damit der Benutzer besser sicher sein kann, wo er eine Verbindung herstellen muss. Wenn Sie andererseits ein Image verwenden und es der Außenwelt zur Verfügung stellen müssen, werden Sie die erforderlichen Ports veröffentlichen.

Ich hoffe, dieser Artikel war hilfreich für Sie. Wenn Sie Fragen haben, lassen Sie es mich in den Kommentaren unten wissen.


Docker
  1. So installieren Sie Jenkins mit Docker

  2. So verwenden Sie Docker Compose

  3. So verbinden Sie Docker-Container

  4. So führen Sie ssh auf mehreren Ports aus

  5. Docker-Grundlagen – Offenlegen von Ports, Portbindung und Docker-Link

So installieren Sie Docker CE unter Linux Mint 20

So verwenden Sie Netcat zum Scannen offener Ports in Linux

So zeigen oder veröffentlichen Sie den Docker-Port

So entfernen Sie Docker-Container

So stoppen Sie Docker-Container

So installieren Sie Docker auf dem Mac