覆蓋容器預設值

解釋

當 Docker 容器啟動時,它會執行一個應用程式或命令。容器從其映象的配置中獲取這個可執行檔案(指令碼或檔案)。容器帶有通常執行良好的預設設定,但如果需要,您可以更改它們。這些調整有助於容器的程式完全按照您想要的方式執行。

例如,如果您有一個現有的資料庫容器正在監聽標準埠,並且您想運行同一個數據庫容器的新例項,那麼您可能需要更改新容器監聽的埠設定,以免與現有容器衝突。有時,您可能需要增加容器可用的記憶體,如果程式需要更多資源來處理繁重的工作負載,或者設定環境變數以提供程式正常執行所需的特定配置細節。

`docker run` 命令提供了一種強大的方式來覆蓋這些預設值,並根據您的喜好定製容器的行為。該命令提供了幾個標誌,讓您可以動態地自定義容器行為。

以下是您可以實現此目的的幾種方法。

覆蓋網路埠

有時您可能希望為開發和測試目的使用獨立的資料庫例項。在同一埠上執行這些資料庫例項可能會發生衝突。您可以在 `docker run` 中使用 `-p` 選項將容器埠對映到主機埠,從而允許您執行多個容器例項而不會發生任何衝突。

$ docker run -d -p HOST_PORT:CONTAINER_PORT postgres

設定環境變數

此選項在容器內設定一個名為 `foo` 的環境變數,其值為 `bar`。

$ docker run -e foo=bar postgres env

你將看到類似以下的輸出:

HOSTNAME=2042f2e6ebe4
foo=bar
提示

`.env` 檔案提供了一種方便的方式來為您的 Docker 容器設定環境變數,而無需在命令列中使用大量的 `-e` 標誌。要使用 `.env` 檔案,您可以在 `docker run` 命令中傳遞 `--env-file` 選項。

$ docker run --env-file .env postgres env

限制容器消耗資源

您可以在 `docker run` 命令中使用 `--memory` 和 `--cpus` 標誌來限制容器可以使用的 CPU 和記憶體量。例如,您可以為 Python API 容器設定記憶體限制,以防止其在主機上消耗過多資源。命令如下:

$ docker run -e POSTGRES_PASSWORD=secret --memory="512m" --cpus="0.5" postgres

此命令將容器記憶體使用量限制為 512 MB,並將 CPU 配額定義為 0.5,即半個核心。

監控即時資源使用情況

您可以使用 `docker stats` 命令來監控執行中容器的即時資源使用情況。這有助於您瞭解分配的資源是否足夠或需要調整。

透過有效使用這些 `docker run` 標誌,您可以根據您的具體要求定製容器化應用程式的行為。

試一試

在本實踐指南中,您將瞭解如何使用 `docker run` 命令覆蓋容器的預設設定。

  1. 下載並安裝 Docker Desktop。

執行多個 Postgres 資料庫例項

  1. 使用以下命令,透過 Postgres 映象 啟動一個容器

    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres
    

    這將在後臺啟動 Postgres 資料庫,監聽標準容器埠 `5432`,並對映到主機上的埠 `5432`。

  2. 啟動第二個對映到不同埠的 Postgres 容器。

    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5433:5432 postgres
    

    這將在後臺啟動另一個 Postgres 容器,在容器內監聽標準的 postgres 埠 `5432`,但對映到主機上的埠 `5433`。您覆蓋主機埠只是為了確保這個新容器不會與正在執行的現有容器衝突。

  3. 透過 Docker Desktop 儀表板中的**容器**檢視,驗證兩個容器都在執行。

    A screenshot of the Docker Desktop Dashboard showing the running instances of Postgres containers

在受控網路中執行 Postgres 容器

預設情況下,當您執行容器時,它們會自動連線到一個名為橋接網路(bridge network)的特殊網路。這個橋接網路就像一個虛擬橋樑,允許同一主機上的容器相互通訊,同時將它們與外部世界和其他主機隔離。對於大多數容器互動來說,這是一個方便的起點。然而,對於特定場景,您可能需要更多地控制網路配置。

這時自定義網路就派上用場了。您可以透過在 `docker run` 命令中傳遞 `--network` 標誌來建立自定義網路。所有沒有 `--network` 標誌的容器都會被附加到預設的橋接網路上。

按照以下步驟瞭解如何將 Postgres 容器連線到自定義網路。

  1. 使用以下命令建立一個新的自定義網路:

    $ docker network create mynetwork
    
  2. 透過執行以下命令來驗證網路:

    $ docker network ls
    

    此命令列出了所有網路,包括新建立的“mynetwork”。

  3. 使用以下命令將 Postgres 連線到自定義網路

    $ docker run -d -e POSTGRES_PASSWORD=secret -p 5434:5432 --network mynetwork postgres
    

    這將在後臺啟動 Postgres 容器,對映到主機埠 5434 並附加到 `mynetwork` 網路。您傳遞了 `--network` 引數來覆蓋容器預設設定,透過將容器連線到自定義 Docker 網路,以實現更好的隔離和與其他容器的通訊。您可以使用 `docker network inspect` 命令來檢視容器是否已繫結到這個新的橋接網路。

    預設橋接網路和自定義網路之間的主要區別

    1. DNS 解析:預設情況下,連線到預設橋接網路的容器可以相互通訊,但只能透過 IP 地址(除非您使用被認為是舊版的 `--link` 選項)。由於存在各種技術缺陷,不建議在生產環境中使用。在自定義網路上,容器可以透過名稱或別名相互解析。
    2. 隔離:所有未指定 ` --network` 的容器都附加到預設的橋接網路,因此可能存在風險,因為不相關的容器能夠相互通訊。使用自定義網路提供了一個有範圍的網路,只有連線到該網路的容器才能通訊,從而提供了更好的隔離。

管理資源

預設情況下,容器的資源使用是不受限制的。然而,在共享系統上,有效管理資源至關重要。重要的是不要讓一個正在執行的容器消耗過多主機的記憶體。

`docker run` 命令再次發揮了它的作用。它提供了像 `--memory` 和 `--cpus` 這樣的標誌來限制容器可以使用的 CPU 和記憶體量。

$ docker run -d -e POSTGRES_PASSWORD=secret --memory="512m" --cpus=".5" postgres

`--cpus` 標誌指定容器的 CPU 配額。這裡,它被設定為半個 CPU 核心(0.5),而 `--memory` 標誌指定容器的記憶體限制。在這種情況下,它被設定為 512 MB。

在 Docker Compose 中覆蓋預設的 CMD 和 ENTRYPOINT

有時,您可能需要覆蓋 Docker 映象中定義的預設命令 (`CMD`) 或入口點 (`ENTRYPOINT`),尤其是在使用 Docker Compose 時。

  1. 建立一個包含以下內容的 `compose.yml` 檔案:

    services:
      postgres:
        image: postgres
        entrypoint: ["docker-entrypoint.sh", "postgres"]
        command: ["-h", "localhost", "-p", "5432"]
        environment:
          POSTGRES_PASSWORD: secret 

    該 Compose 檔案定義了一個名為 `postgres` 的服務,它使用官方的 Postgres 映象,設定了一個入口點指令碼,並以密碼認證方式啟動容器。

  2. 透過執行以下命令來啟動服務:

    $ docker compose up -d
    

    此命令啟動 Docker Compose 檔案中定義的 Postgres 服務。

  3. 使用 Docker Desktop 儀表板驗證身份驗證。

    開啟 Docker Desktop 儀表板,選擇 **Postgres** 容器,然後選擇 **Exec** 進入容器的 shell。您可以輸入以下命令連線到 Postgres 資料庫:

    # psql -U postgres
    
    A screenshot of the Docker Desktop Dashboard selecting the Postgres container and entering into its shell using EXEC button
    注意

    PostgreSQL 映象在本地設定了信任認證,所以您可能會注意到從 localhost(在同一個容器內)連線時不需要密碼。但是,如果從不同的主機/容器連線,則需要密碼。

使用 `docker run` 覆蓋預設的 CMD 和 ENTRYPOINT

您也可以使用 `docker run` 命令直接覆蓋預設值,命令如下:

$ docker run -e POSTGRES_PASSWORD=secret postgres docker-entrypoint.sh -h localhost -p 5432

此命令執行一個 Postgres 容器,為密碼認證設定一個環境變數,覆蓋預設的啟動命令,並配置主機名和埠對映。

其他資源

後續步驟

現在您已經瞭解瞭如何覆蓋容器的預設值,是時候學習如何持久化容器資料了。

持久化容器資料