Docker - 埠管理



根據設計,Docker 容器是隔離的,將內部埠保留給自己,不允許響應外部。可以在使用-p--publish Docker 標誌建立容器時完成 Docker 主機上埠的此配置;然後,它允許釋出埠。此對映使容器內執行的應用程式可訪問,因為它們接收來自外部源的流量。可以為一個容器啟用多個埠對映,這可以滿足在同一容器內執行各種服務的場景。

此外,Docker Compose 為多容器應用程式抽象了埠對映的複雜性。透過定義所有服務及其埠對映的 docker-compose.yml 檔案,Docker Compose 可以更輕鬆地建立和連線容器。這樣做是為了自動分配唯一的埠,以避免衝突,從而使應用程式中容器之間的通訊變得輕鬆。

能夠避免衝突並使通訊無縫進行,使其能夠有效地控制埠,因此成為增強從開發到複雜應用程式部署工作流程的非常有用的工具。它是管理容器化環境的寶貴工具。

在本章中,讓我們詳細瞭解 Docker 埠管理。

EXPOSE 與 PUBLISH:瞭解差異

EXPOSE 和 PUBLISH(或 -p)都處理 Docker 中的埠,但它們是兩個不同的東西 -

EXPOSE

EXPOSE 充當有關容器化應用程式打算用於通訊的埠的文件。它是 Dockerfile 中的一條指令,讓任何構建或執行容器的人都知道它可以提供的潛在服務。

但請記住,僅 EXPOSE 不會使這些容器埠在容器外部可訪問;該指令本身或多或少充當開發人員或系統管理員的註釋。

PUBLISH

這是實際的埠對映。當您釋出埠時,即當您在 docker run 中包含 -p 或在 docker-compose.yml 中包含 ports 部分時,您就是在 Docker 容器中的某個埠與 Docker 主機上的埠之間建立關聯。這就是使外部流量能夠訪問容器內執行的應用程式的原因,即您公開的“意圖”成為現實的地方。

如何在 Docker 中使用 PUBLISH 公開埠?

Docker 提出了幾種可以做到這一點的方法,但最直接且最廣為人知的方法是在執行容器時使用 -p。以下是一個示例 -

基本語法

在執行 Docker 容器時公開埠的基本語法為 -

$ docker run -p <host_port>:<container_port> <image_name>
  • <host_port> − 這表示您要在 Docker 主機上公開應用程式的埠號。
  • <container_port> − 容器中您的應用程式偵聽流量的埠號。
  • <image_name> − 您要執行的 Docker 映象的名稱。

示例:公共 Web 伺服器埠

例如,您有一個應用程式配置為在容器中的埠 80 上執行 Web 伺服器。您可以透過執行以下操作將其對映到本地機器埠 8080 -

$ docker run -p 8080:80 <your_web_server_image>

現在,您可以使用您喜歡的 Web 瀏覽器開啟https://:8080並檢視您的應用程式正在提供服務!

在 Docker 中釋出多個埠

如果您的應用程式需要開啟多個埠,您可以多次新增-p標誌。

$ docker run -p 8080:80 -p 4433:443 <your_app_image>

這將主機上的埠 80(用於 HTTP)和埠 443(用於 HTTPS)公開到服務。

使用 Docker Compose 釋出埠

使用 Docker Compose 為多容器應用程式維護埠對映非常簡單。您可以在 docker-compose.yml 檔案中每個服務的 ports 部分內執行此操作 -

services:
   web:
      image: <your_web_server_image>
      ports:
      - "8080:80"
   db:
      image: <your_database_image>
      # ... other configurations

關鍵注意事項

  • 埠衝突 − 確保您自己選擇的埠尚未被系統中的任何其他應用程式或服務使用。
  • 防火牆 − 如果 Docker 在遠端伺服器上執行,您可能需要配置防火牆以允許跨公開埠的流量。
  • 安全 − Docker 漏洞很容易暴露 - 您的埠將被暴露,攻擊者可以入侵容器。請考慮使用反向代理或其他安全措施來保護您的容器。

如何在 Dockerfile 中公開埠?

雖然 Dockerfile 中的 `EXPOSE` 指令不會發布埠,但它提供了有關容器在執行時預期偵聽的埠的資訊。實際上,它記錄了 Docker 映象將使用的埠,以便使用者知道他們可以考慮在容器中釋出哪些埠。以下是在 Dockerfile 中定義它的方法 -

EXPOSE 指令

語法很簡單 -

EXPOSE <port> [<port>/<protocol>]
  • `<port>` − 您希望公開的埠。
  • `<protocol>` − 可選,預設為 TCP。可以是 TCP 或 UDP。

示例:公開 Web 伺服器埠

在 Web 伺服器映象的 Dockerfile 中,您將擁有 -

# ... other Dockerfile instructions
EXPOSE 80

這會通知任何檢視您的映象的人,內部應用程式很可能正在偵聽埠 80(標準 HTTP 埠)上的傳入連線。

開啟多個埠和協議

您可以在 Dockerfile 中擁有多個 `EXPOSE` -

EXPOSE 80
EXPOSE 443/tcp
EXPOSE 443/udp

這意味著您的應用程式預設使用 TCP 埠 80 和 TCP/UDP 埠 443。

關鍵要點

`EXPOSE` 不是必需的;但是,記錄容器的網路使用情況是一個好習慣。

它不會將埠釋出到主機 - 執行此操作仍然需要在執行容器時使用 `-p` 或在 `docker-compose.yml` 檔案中定義 `ports`。

當從您的 Dockerfile 構建映象時,來自 `EXPOSE` 的指令會在圖片的元資料中自動記下注釋,您可以使用`docker inspects <image_name>`公開它。

Dockerfile 和執行容器

FROM nginx

EXPOSE 80

# ... any additional configuration you need

執行此容器,Web 伺服器現在可以在主機的埠 8080 上訪問 -

$ docker run -p 8080:80 <your_nginx_image>

結論

掌握 Docker 中的埠管理對於任何處理容器中執行的應用程式的人員至關重要。瞭解 EXPOSE 和 PUBLISH 之間的區別並應用公開埠的最佳實踐,確保所有容器通訊都與外部世界完美配合。

無論您是開發簡單的應用程式還是管理規模龐大的多容器環境,Docker 埠管理都具有靈活性和控制能力,可以建立有效且可訪問的解決方案。

在繼續您的 Docker 之旅時,請始終考慮安全最佳實踐。請記住保持埠對映更新,使用安全的通訊協議,並考慮更多安全層 - 例如,反向代理。然後,這使您能夠充分利用 Docker 的強大功能,同時透過專注於積極主動來保護應用程式和基礎設施安全。

常見問題解答

問 1. docker 中 EXPOSE 和 -p(或 PUBLISH)有什麼區別?

它們都處理埠,但方式完全不同。EXPOSE 是 Dockerfile 中的一條指令,它更像是一個規則語句,用於描述您的應用程式將利用哪些埠進行通訊。

將其視為構建或執行您的容器的人員的友好註釋。另一方面,-p 或 PUBLISH 是一個實際的執行時命令,用於將 Docker 主機上的埠對映到容器中的埠,以使您的應用程式可從外部訪問。

問 2. 即使在公開埠後,為什麼也無法訪問我的應用程式?

這裡可能有幾個罪魁禍首。確保主機上的防火牆沒有阻止在此公開埠上的流量。確保您沒有選擇已被其他應用程式使用的埠。

如果您在某些虛擬機器或遠端伺服器上執行 Docker,請再次確保網路配置正確。最後,請確保您提供的埠對映(主機埠到容器埠)是正確的,並且與應用程式的配置方式相符。

問 3. 如何為單個容器公開多個埠?

Docker 可以輕鬆地管理它。只需為您的 docker run 命令指定多個 -- -p 標誌,每個標誌都有不同的埠對映即可。當使用 Docker Compose 時,必須在 docker-compose.yml 檔案的 ports 部分中進行多個對映。

每個對映將為外部流量提供一條通往容器內執行的不同服務或元件的單獨路徑。

問 4. 在 Docker 中公開埠安全嗎?

每個為訪問您的應用程式而公開的埠都會為潛在攻擊者建立越來越大的攻擊面。請遵守所有安全最佳實踐以減少風險。啟用強身份驗證,僅允許來自受信任來源的訪問,並可能新增更多安全層,例如反向代理或防火牆。

監視系統並在常規更新可用時更新 Docker 映象以修補已知的漏洞。

問 5. 在 Docker 中管理埠時應避免哪些常見錯誤?

最常見的錯誤是在埠公開方面存在安全疏忽,將應用程式暴露給攻擊者。另一個是使用先前啟動的其他服務使用的埠;在這種情況下,會出現衝突。

在埠對映方面要非常小心,並確保主機上的正確埠和容器內的正確埠連線。

最後,別忘了記錄你的埠對映,無論是在 Dockerfile 中使用 EXPOSE 還是在專案文件中,以便你或其他人將來可以輕鬆參考。

廣告

© . All rights reserved.