Sto facendo esperimenti con Dockerfiles e penso di capire la maggior parte della logica. Tuttavia, non vedo la differenza tra “esporre” e “pubblicare” una porta in questo contesto.
Tutte le esercitazioni che ho visto prima includono il comando EXPOSE nel Dockerfile:
... EXPOSE 8080 ...
Quindi creano un’immagine da questo Dockerfile:
$ docker build -t an_image - < Dockerfile
E quindi pubblica la stessa porta come sopra durante l’esecuzione dell’immagine:
$ docker run -d -p 8080 an_image
o pubblicare tutte le porte usando
$ docker run -d -P an_image
Qual è il punto di esposizione di una porta nel Dockerfile, se verrà comunque pubblicata? Ci sarebbe mai bisogno di esporre prima una porta e non pubblicarla più tardi? Effettivamente, vorrei specificare tutte le porte che userò nel Dockerfile quando creo l’immagine, e quindi non disturbarmi più con esse, eseguendole semplicemente con:
$ docker run -d an_image
È ansible?
Fondamentalmente, hai tre opzioni:
EXPOSE
né -p
. EXPOSE
. EXPOSE
e -p
. Se non si specifica nessuno di questi, il servizio nel contenitore non sarà accessibile da nessuna parte tranne che dall’interno del contenitore stesso.
Se EXPOSE
una porta, il servizio nel contenitore non è accessibile da Docker esterno, ma dall’interno di altri contenitori Docker. Quindi questo è un bene per la comunicazione tra container.
Se EXPOSE
e -p
una porta, il servizio nel contenitore è accessibile da qualsiasi luogo, anche al di fuori di Docker.
Il motivo per cui entrambi sono separati è IMHO perché
La documentazione afferma esplicitamente:
L’istruzione
EXPOSE
espone le porte per l’uso all’interno dei collegamenti.
Ti indica anche come colbind i contenitori , che in pratica è la comunicazione inter-container di cui ho parlato.
PS: Se fai -p
, ma non EXPOSE
, Docker esegue un EXPOSE
implicita. Questo perché se una porta è aperta al pubblico, è automaticamente aperta anche ad altri container Docker. Quindi -p
include EXPOSE
. Ecco perché non l’ho elencato sopra come un quarto caso.
EXPOSE
è un modo di documentare --publish
(o -p
) è un modo di mappare una porta host a una porta del contenitore Notare sotto le connessioni tra:
Dockerfile
e Dockerfile
--publish
e run-time ( docker run ...
) Esporre e pubblicare porte
Nella rete Docker, esistono due meccanismi diversi che coinvolgono direttamente le porte di rete: l’esposizione e la pubblicazione delle porte. Questo vale per la rete bridge predefinita e le reti bridge definite dall’utente.
Esponi le porte utilizzando la parola chiave EXPOSE nel Dockerfile o il flag
--expose
nella finestra mobile. L’esposizione delle porte è un modo per documentare quali porte vengono utilizzate, ma in realtà non mappa o non apre alcuna porta. L’esposizione delle porte è facoltativa .Pubblichi le porte usando il
--publish
o--publish-all
delladocker run
. Questo dice a Docker quali porte aprire sull’interfaccia di rete del contenitore. Quando una porta viene pubblicata, viene mappata su una porta disponibile di ordine superiore (superiore a30000
) sul computer host, a meno che non si specifichi la porta su cui eseguire il mapping sulla macchina host in fase di runtime. Non è ansible specificare la porta su cui eseguire la mapping sulla macchina host quando si costruisce l’immagine (nel Dockerfile), perché non c’è modo di garantire che la porta sia disponibile sul computer host su cui viene eseguita l’immagine .da: rete di container Docker
Anche,
ESPORRE
… L’istruzione
EXPOSE
realtà non pubblica la porta. Funziona come un tipo di documentazione tra la persona che crea l’immagine e la persona che gestisce il contenitore, su quali porte devono essere pubblicate .da: riferimento Dockerfile
--publish
/ --publish
non sono definiti: Alla risposta di @Golo Roden si afferma che:
“Se non si specifica nessuno di questi, il servizio nel contenitore non sarà accessibile da nessuna parte tranne che all’interno del contenitore stesso .”
Forse era il caso al momento della --publish
della risposta, ma ora sembra che anche se non usi --publish
o --publish
, l’ host
e altri containers
della stessa rete saranno in grado di accedere a un servizio che potresti iniziare all’interno di quel contenitore .
Ho usato il seguente Dockerfile
. Fondamentalmente, comincio con Ubuntu e installo un piccolo web server:
FROM ubuntu RUN apt-get update && apt-get install -y mini-httpd
build
l’immagine come “testexpose” ed eseguo un nuovo contenitore con:
docker run --rm -it testexpose bash
All’interno del contenitore, lancio alcune istanze di mini-httpd
:
[email protected]:/# mini_httpd -p 80 [email protected]:/# mini_httpd -p 8080 [email protected]:/# mini_httpd -p 8090
Sono quindi in grado di utilizzare l’ curl
dall’host o da altri contenitori per recuperare la pagina iniziale di mini-httpd
.
EXPOSE
consente di definire porte private (container) e pubbliche (host) da esporre al momento della creazione dell’immagine per quando il contenitore è in esecuzione. La porta pubblica è facoltativa, se non viene specificata una porta pubblica, verrà selezionata una porta casuale sull’host dalla finestra mobile per esporre la porta del contenitore specificata su Dockerfile.
Una buona pratica non è specificare la porta pubblica, perché limita solo un contenitore per host (un secondo contenitore getterà una porta già in uso).
È ansible utilizzare -p
nella docker run
per controllare quale porta pubblica le porte del container esposte saranno collegabili.
Ad ogni modo, se non usi EXPOSE
né -p
, nessuna porta sarà esposta.
Se si usa sempre -p
alla docker run
non è necessario EXPOSE
ma se si utilizza EXPOSE
il comando di docker run
può essere più semplice, EXPOSE
può essere utile se non si cura quale porta verrà esposta sull’host o se si è sicuro di un solo container verrà caricato.
La maggior parte delle persone usa la finestra mobile comporre con le reti. La documentazione afferma:
La funzione di rete Docker supporta la creazione di reti senza la necessità di esporre le porte all’interno della rete, per informazioni dettagliate consultare la panoramica di questa funzionalità).
Ciò significa che se si utilizzano le reti per la comunicazione tra i contenitori non è necessario preoccuparsi di esporre le porte.
Esponi le porte utilizzando la parola chiave EXPOSE nel Dockerfile o il flag –expose nella finestra mobile. L’esposizione delle porte è un modo per documentare quali porte vengono utilizzate, ma in realtà non mappa o non apre alcuna porta. L’esposizione delle porte è facoltativa.
Fonte: github commit