GNU/Linux >> Znalost Linux >  >> Panels >> Docker

Jak vystavit nebo publikovat port Docker

V nastavení s více kontejnery komunikují služby běžící v kontejnerech mezi sebou prostřednictvím společné sítě. Ve stejném nastavení některé kontejnery také interagují s vnějším světem.

Tato interní a externí komunikace je řešena pomocí vystavených a publikovaných portů v Dockeru.

V tomto tutoriálu budu diskutovat o práci s porty v Dockeru. Přejdu k rozdílu mezi odhalením a publikováním portů, proč se používají a jak je používat.

Odhalení vs publikování portu v Dockeru

Existují dva způsoby, jak zacházet s porty v Dockeru:odhalením portů a publikováním portů.

Odhalení portu jednoduše znamená dát ostatním vědět, na kterém portu bude kontejnerová aplikace naslouchat nebo přijímat připojení. Slouží ke komunikaci s jinými kontejnery, nikoli s vnějším světem.

Publikování portu je spíše jako mapování portů kontejneru s porty hostitele. Tímto způsobem je kontejner schopen komunikovat s externími systémy, skutečným světem, internetem.

Tato grafika vám pomůže pochopit.

Vidíte, jak je port 80 kontejneru SERVER mapován na port 80 hostitelského systému? Tímto způsobem je kontejner schopen komunikovat s vnějším světem pomocí veřejné IP adresy hostitelského systému.

Na druhou stranu k odhaleným portům nelze přistupovat přímo z místa mimo svět kontejnerů.

Pro zapamatování:

  • Vystavené porty se používají pro interní komunikaci kontejnerů v rámci světa kontejnerů.
  • Publikované porty se používají pro komunikaci se systémy mimo svět kontejnerů.
Jaký je rozdíl mezi porty docker-compose a expose Jaký je rozdíl mezi porty a možnostmi vystavení v docker-compose.yml Přetečení zásobníkuBibek Shrestha

Odhalení portů v Dockeru

Za prvé, odhalení portu není nezbytně nutné. Proč? Protože většina obrazů dockeru, které používáte ve svém nastavení, již má ve své konfiguraci odhalený výchozí port.

Kontejnerovaná frontendová aplikace může například komunikovat s databází MariaDB pouhým zadáním IP kontejneru a libovolného portu, na kterém MariaDB přijímá připojení (výchozí 3306).

Odhalení pomáhá v situaci, kdy se nepoužívají výchozí hodnoty, jako v tomto případě, kdyby MariaDB nepřijímala připojení na portu 3306, měl by být odhalen alternativní port.

Port můžete odhalit dvěma způsoby:

  1. Pomocí EXPOSE Instrukce pro dockerfile.
  2. Pomocí --expose pomocí ukotvitelného rozhraní CLI nebo expose klíč v docker-compose.

Je čas ponořit se hlouběji do obou.

Metoda 1:Odhalení portů prostřednictvím Dockerfile

Do svého Dockerfile můžete přidat jednoduchou instrukci, abyste dali ostatním vědět, na kterém portu bude vaše aplikace přijímat připojení.

O tomto návodu musíte vědět následující:-

  • EXPOSE není přidat další vrstvy do výsledného obrazu ukotvitelného panelu. Pouze přidává metadata.
  • EXPOSE je způsob dokumentace port vaší aplikace. Jediný efekt, který to má, je z hlediska čitelnosti nebo porozumění aplikaci.

Jak funguje expozice, můžete vidět na jednoduchém obrázku kontejneru, který jsem vytvořil právě pro tento účel. Tento obrázek nic nedělá .

Vytáhněte obrázek.

docker pull debdutdeb/expose-demo:v1

Tento obrázek odhaluje celkem čtyři porty, vypište obrázek pomocí následujícího příkazu.

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

Podívejte se na SIZE ve sloupci bude 0 bajtů.

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

Důvod je jednoduchý, na tomto obrázku nejsou žádné vrstvy, všechny přidané pokyny k expozici byly metadata, žádné skutečné vrstvy.

Počet dostupných vrstev můžete také získat pomocí následujícího příkazu:-

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

Měli byste vidět výstup jako tento:-

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

Jak jsem již řekl, exponované porty jsou přidány jako metadata obrázku, abychom věděli, které porty aplikace používá.

Jak vidíte tyto informace, aniž byste se podívali na Dockerfile? Musíte si obrázek prohlédnout. Chcete-li být konkrétnější, podívejte se na příkaz níže, podobný příkaz můžete použít na libovolném obrázku a zobrazit seznam vystavených portů.

Pro demonstraci používám svůj ukázkový obrázek.

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

Ukázkový výstup:

➟ 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

Tento obrázek, který odhaluje několik portů, můžete také porovnat s debdutdeb/noexpose-demo:v1 obrázek, který neodhaluje žádné porty. Spusťte stejnou sadu příkazů také na tomto obrázku a všimněte si rozdílu.

Metoda 2:Zpřístupnění portů prostřednictvím rozhraní CLI nebo docker-compose

Někdy se vývojáři aplikací vyhýbají zahrnutí dalšího EXPOSE instrukce v jejich Dockerfile.

V takovém případě, abyste se ujistili, že ostatní kontejnery (prostřednictvím docker API) mohou snadno detekovat používaný port, můžete po sestavení vystavit více portů jako součást procesu nasazení.

Buď zvolte imperativní metodu, tj. CLI, nebo deklarativní metodu, tj. vytváření souborů.

Metoda CLI

V této metodě při vytváření kontejneru vše, co musíte udělat, je použít --expose možnost (kolikrát, kolikrát je potřeba) s číslem portu a volitelně protokol s / . Zde je jeden příklad:-

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

Používám busybox obrázek, který ve výchozím nastavení neodhaluje žádné porty.

Metoda vytvoření souboru

Pokud používáte nový soubor, můžete přidat pole expose v definici služby. Předchozí nasazení můžete převést na nový soubor takto:-

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

Jakmile budete mít kontejner spuštěný, stejně jako předtím jej můžete zkontrolovat, abyste věděli, které porty jsou vystaveny. Příkaz vypadá podobně.

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

Ukázkový výstup:-

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

Publikování portu v Dockeru

Publikování portů je synonymem pro předávání portů, kdy jsou požadavky z příchozího připojení na veřejném portu předávány na port kontejneru.

Podobně jsou odpovědi odeslané z kontejneru přes jeho port odesílány klientovi přesměrováním provozu na zadaný port v prostoru portů hostitele.

Existují dva způsoby publikování portu, jeden přes CLI a druhý pomocí nového souboru. Obě metody mají také jednu dlouhou syntaxi a jednu krátkou syntaxi.

Metoda 1:Publikování portů pomocí příkazu Docker

Tyto dvě syntaxe jsou následující:

  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]
Pro volitelnou IP hostitele můžete použít jakoukoli IP adresu spojenou s kteroukoli síťovou kartou. Pokud je IP vynechána, docker spojí port se všemi dostupnými IP adresami.

Nejvíce využijete ten první. Druhý je čitelnější. Podívejme se na příklad pomocí kontejneru nginx. Spusťte následující příkaz:-

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

Pomocí tohoto příkazu jednoduše připojím port 80 kontejneru k portu 8081 mého hostitele na localhost. Pokud nyní zamíříte na http://localhost:8081, uvidíte spuštěný nginx.

Předchozí příkaz lze snadno převést do kratšího tvaru takto

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

Přestože je kratší, hůře se čte.

Můžete také použít -p nebo --publish vícekrát pro publikování více portů.

Metoda 2:Publikování portu prostřednictvím nového souboru

Chcete-li publikovat port pomocí nového souboru, budete potřebovat pole s názvem ports v definici služby. Toto pole může být seznam řetězců, který vypadá podobně jako krátká syntaxe CLI, nebo můžete použít seznam objektů, který je podobný dlouhé syntaxi.

Pokud bych převedl předchozí nasazení nginx pomocí složeného souboru s polem řetězců pro sekci portů, vypadalo by to následovně:-

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

Dovolte mi také ukázat, jak používat syntaxi pole objektů.

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

Chcete-li zobrazit seznam všech publikovaných portů, můžete si kontejner prohlédnout takto-

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

Po spuštění uvidíte následující výstup:-

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

Existuje další, jednodušší způsob, jak vypsat seznam publikovaných portů, pomocí docker container port příkaz.

docker container port nginx

Příklad výstupu:-

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

Kdy vystavit port a kdy jej publikovat?

To je férová otázka. Vystavování a publikování nemají být konkurenty. Každá slouží jinému účelu. Pokud jste vývojářem obrázku, odkryjete porty, aby si uživatel mohl být lépe jistý, kde se pokusit o připojení. Na druhou stranu, pokud používáte obrázek a potřebujete jej zpřístupnit vnějšímu světu, budete publikovat potřebné porty.

Doufám, že vám byl tento článek užitečný. Pokud máte nějaké dotazy, dejte mi vědět v komentářích níže.


Docker
  1. Jak používat Docker Compose

  2. Jak připojit kontejnery Docker

  3. Základy dockeru – odhalte porty, vazbu portů a odkaz dockeru

  1. Jak nainstalovat Docker na Raspberry Pi

  2. Jak nainstalovat Jenkins pomocí Docker

  3. Jak spustit ssh na více portech

  1. Jak optimalizovat výkon Dockeru

  2. Jak povolit port přes firewall na AlmaLinuxu

  3. Learning Docker:Jak vytvořit kontejner Docker