Docker 中 expose 和 port 之間的區別
在 Docker 中,當我們使用 docker create
或 docker run
建立容器後,我們可能希望我們的容器與外部服務或其他外部容器互動。我們需要向外部世界提供埠來實現這一點。
在本文中,我們將介紹兩種可以用來在 Docker 中公開埠的重要方法。我們還將討論如何將容器埠對映到主機埠以及方法的差異。
Docker 中的 EXPOSE
DockerFile 指令
docker 檔案只是一個文字檔案,它指定使用 docker build
命令組裝映象的指令。其中包括 EXPOSE
指令。
EXPOSE
指令用於通知 Docker 我們正在構建的容器應該在執行時監聽特定的網路埠。但是請注意,該指令只是一個參考點,並沒有將容器埠對映到主機埠。
語法:
EXPOSE <port>/<protocol>
我們不必指定協議,因為 Docker 可以使用預設的 TCP 協議。但是,我們可以提供其他協議,例如 UDP 協議。
Docker 將使用預設的 TCP 協議,因為 Nginx 官方 docker 檔案中沒有指定該協議。
COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE 80
STOPSIGNAL SIGQUIT
CMD ["nginx", "-g", "daemon off;"]
假設我們從 Docker 註冊中心拉取官方 Nginx 映象,建立一個容器,並執行該容器。在這種情況下,我們可以從容器中快速確定一些有用的資訊,例如埠號和使用的協議。
~/isaac$ docker ps -a
輸出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99edfdea0443 nginx "/docker-entrypoint.…" 3 minutes ago Up 2 minutes 80/tcp nice_volhard
上面的輸出顯示 Nginx 容器在 Dockerfile 和 TCP 協議中所述的埠 80 上執行。
或者,我們也可以在建立容器時使用 --expose
標籤在執行時公開埠,如下所示。
docker run --expose 80 nginx
現在,將此埠繫結到主機埠號。我們需要使用大寫的 -P
標籤或小寫的 -p
標籤。
儘管我們可以使用其中任何一個來獲得結果,但這些標籤有很大的不同。
大寫的 -P
標籤,當在執行時使用時,允許我們將所有暴露的標籤繫結到主機上的隨機埠。這使我們能夠避免埠衝突。
$ docker run -d -P nginx
006b88a06e51eac45895f13b33a89221676029e8fa654aaaccc79b81f74efb4d
程式碼:
isaac$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
006b88a06e51 nginx "/docker-entrypoint.…" 27 seconds ago Up 6 seconds 0.0.0.0:49153->80/tcp angry_babbage
我們還可以使用小寫的 -p
標籤將容器釋出到主機上的特定埠。
Docker Compose 埠
Docker-compose 是一個實用工具,它允許我們在 Docker 上執行多容器應用程式。
在 docker-compose.yml
檔案下,我們可以指定容器在其他檔案中的配置方式,例如服務、檔案版本、使用的卷以及連線服務的網路。
就像我們在 Dockerfile 中指定埠號一樣,我們也需要在 docker-compose.yml
檔案中指定埠號。我們可以使用 expose
或 ports
指令來做到這一點。
rabbitmq:
image: rabbitmq
expose:
- 3000
- 5000
expose
指令允許我們在不釋出埠或將它們繫結到主機埠的情況下公開埠,即埠不暴露給主機,只暴露給其他服務。
另一方面,ports
指令允許我們指定主機和容器埠號。此外,這些埠將在其他服務之間共享,並向主機暴露給隨機或給定的埠。
rabbitmq:
image: rabbitmq
ports:
- "8000:80"
- "5000: 70"
Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.
LinkedIn