在 VM 和 MIG 上部署容器

您可以設定讓 VM 執行個體或執行個體範本部署及啟動 Docker 容器。Compute Engine 會提供已安裝 Docker 的最新版 Container-Optimized OS (COS) 映像檔,並在 VM 啟動時啟動容器。如要進一步瞭解在 VM 上部署容器的優點,請參閱本主題稍後的選擇在 VM 與執行個體群組上部署容器一節。

事前準備

選擇在 VM 與執行個體群組上部署容器

在 Compute Engine 上部署容器,既可簡化應用程式的部署,又可控管 VM 基礎架構。

  • 用您在設定及管理 Compute Engine 基礎架構時,處理其他任何 VM 的相同方式,管理執行容器的 VM。
  • 使用執行容器的代管執行個體群組 (MIG) 建立可擴充的服務,可提供自動調度資源、自動修復、滾動式更新、多區域部署和負載平衡之類的功能。
  • 使用熟悉的流程與工具 (例如 gcloud 指令列工具或 Compute Engine API) 管理含有容器的 VM。

此外,您可能會考慮部署至 Google Kubernetes Engine 以達成下列目的:

  • 大量執行微服務
  • 縮短容器的啟動時間
  • 利用 Kubernetes 的自動化調度管理,包括自動升級、節點自動修復及自動調度資源

如果在 Compute Engine 的獨立虛擬機器 (VM) 上執行每個微服務,可能會使作業系統固定耗用的資源占去一大部分的成本。Google Kubernetes Engine 可讓您為每個 VM 執行個體部署多個容器及多組容器,更有效率地將主機 VM 資源分配至占用空間較小的微服務。

在 Compute Engine 上部署容器的運作方式

將軟體部署到 Compute Engine VM 執行個體的常見方法包括:

  • 使用開機指令碼cloud-init 在 VM 開機時部署軟體。
  • 建立已預先安裝軟體的自訂開機磁碟映像檔。

以上兩種方法皆結合了設定應用程式與設定主機作業系統環境的工作。身為開發人員,您必須仔細追蹤及解決任何執行階段相依性。例如,如果在 VM 上執行的兩個應用程式使用同一個程式庫的不同版本,您就必須安裝這兩個版本,並透過系統變數來指向各版本。

在同一程式庫的不同版本上執行的應用程式。
此 VM 執行個體具有直接部署到主機作業系統的應用程式

您也可以將容器中的軟體直接部署到 VM 執行個體上或部署到代管執行個體群組。每一個容器都含有應用程式軟體和必要的程式庫,並且會與主機 OS 應用程式和程式庫分隔開來。容器可在部署環境之間輕易移動,而無需處理容器及其主機 OS 中發生衝突的程式庫版本。

容器中的應用程式。
此 VM 執行個體具有部署在容器中的應用程式

以下程序說明如何在 Compute Engine 上部署容器:

  1. 將您的應用程式和必要的程式庫整合到 Docker 映像檔中,然後將這個映像檔發布到 Container Registry (或在 Docker Hub 或其他註冊資料庫上公開發布)。
  2. 為代管執行個體群組建立 VM 執行個體或執行個體範本時,指定 Docker 映像檔名稱和 docker run 設定。

在您提出要求建立 VM 執行個體或執行個體範本後,Compute Engine 就會執行下列工作:

  1. Compute Engine 使用 Google 提供的 Container-Optimized OS 映像檔,建立 VM 執行個體或執行個體範本。這個映像檔內含 Docker 執行階段及負責啟動您的容器的其他軟體。
  2. Compute Engine 將您的容器設定儲存在 gce-container-declaration 中繼資料鍵下的執行個體中繼資料中。
  3. Container-Optimized OS 映像檔從存放區提取容器映像檔,然後使用儲存於執行個體中繼資料中的 docker run 指令設定,在 VM 啟動時啟動容器。
使用容器映像檔和「docker run」指令。/>
建立執行容器的 VM 執行個體或代管執行個體群組的步驟

限制

  • 每個 VM 執行個體只能部署一個容器。如果每個 VM 執行個體必須部署多個容器,請考慮使用 Google Kubernetes Engine
  • 您只能從公開存放區或 Container Registry 的私人存放區部署容器。系統目前不支援其他私人存放區。
  • 您無法將 VM 執行個體的通訊埠對應至容器的通訊埠 (Docker 的 -p 選項)。
  • Container-Optimized OS 映像檔只能與這種部署方法搭配使用。
  • 您只能透過 Google Cloud Platform Console 或 gcloud 指令列工具 (而不是 API) 使用這項功能。

準備要部署的容器

請選用下列其中一種方法,讓 Compute Engine 可以存取您的容器映像檔:

  • 上傳您的 Docker 映像檔到 Container Registry。
  • 使用可從 Docker Hub 或其他註冊資料庫中公開取得的容器映像檔。

在新的 VM 執行個體上部署容器

您可以使用 Google Cloud Platform Consolegcloud 指令列工具,在新的 VM 執行個體上部署容器。

主控台

下列範例將容器從 Google 提供的 Nginx Docker 映像檔 https://gcr.io/cloud-marketplace/google/nginx1:latest 部署至 VM 執行個體。如要使用其他 Docker 映像檔,請在以下範例中改為指定所需的映像檔。

  1. 前往「VM instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 按一下 [Create instance] (建立執行個體) 按鈕以建立新的執行個體。
  3. 在「Container」(容器) 區段下,勾選 [Deploy container image] (部署容器映像檔)。
  4. 在「Container image」(容器映像檔) 下指定容器映像檔名稱,然後設定執行容器的相關選項 (如有需要)。例如,您可為容器映像檔指定 gcr.io/cloud-marketplace/google/nginx1:latest
  5. 按一下 [Create] (建立)。

gcloud

使用 gcloud compute instances create-with-container 指令:

 gcloud compute instances create-with-container [INSTANCE_NAME] \
     --container-image [DOCKER_IMAGE]

舉例來說,下列指令會建立名為 nginx-vm 的新 VM 執行個體,而該執行個體會啟動並執行 Docker 映像檔 gcr.io/cloud-marketplace/google/nginx1:latest

 gcloud compute instances create-with-container nginx-vm \
     --container-image gcr.io/cloud-marketplace/google/nginx1:latest

進一步瞭解 gcloud compute instances create-with-container 指令

使用 Docker Hub 公開的映像檔時,一律需指定完整的 Docker 映像檔名稱。例如,指定下列映像檔名稱來部署 Apache 容器映像檔:

docker.io/httpd:2.4

在 VM 執行個體上更新容器

您可以使用 Google Cloud Platform Console 或 gcloud 指令列工具更新 Docker 映像檔和設定選項,以在 VM 執行個體上執行容器。

更新執行容器的 VM 時,Compute Engine 會執行兩個步驟:

  • 在執行個體上更新容器宣告。Compute Engine 會將更新後的容器宣告儲存到 gce-container-declaration 中繼資料鍵下的執行個體中繼資料中。
  • 如果執行個體正在執行中,系統會停止並重新啟動執行個體,以啟用更新後的設定;如果執行個體處於停止狀態,則會更新容器宣告並使執行個體保持停止狀態。VM 執行個體會下載新的映像檔,並在 VM 啟動時啟動容器。

Console

  1. 前往「VM instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 按一下您要更新的執行個體名稱。
  3. 在執行個體的詳細資料頁面中,按一下 [Edit] (編輯)。
  4. 指定新的容器映像檔,然後更新執行容器的相關選項 (如有需要)。
  5. 按一下 [Save and restart] (儲存並重新啟動) 以儲存變更。Compute Engine 隨即儲存變更,接著自動重新啟動執行個體來執行更新。VM 重新啟動後,系統會下載新的映像檔並使用更新後的設定啟動容器。

gcloud

使用 gcloud compute instances update-container 指令更新容器宣告。例如:

gcloud compute instances update-container nginx-vm \
    --container-image gcr.io/cloud-marketplace/google/nginx1:latest

這個指令會將容器映像檔設為 gcr.io/cloud-marketplace/google/nginx1:latest,然後重新啟動執行個體來啟用變更。您也可以藉由新增對應的標記,更新設定選項以執行容器一文中所述的任何屬性。

執行個體重新啟動後,會下載新的容器映像檔並以新的設定啟動容器。

在代管執行個體群組上部署容器

您可以按照下列步驟,使用 Google Cloud Platform Consolegcloud 指令列工具,將容器部署到新的代管執行個體群組:

  1. 建立以 Docker 映像檔為基礎的執行個體範本

  2. 從新的執行個體範本建立代管執行個體群組

主控台

下列範例會建立一個執行個體範本,這個範本會從 Google 提供的 Nginx (gcr.io/cloud-marketplace/google/nginx1:15) Docker 映像檔,將容器部署到代管執行個體群組。如果要使用其他的 Docker 映像檔,請指定所需映像檔,以取代下列範例中的 gcr.io/cloud-marketplace/google/nginx1:15

  1. 前往「Instance templates」(執行個體範本) 頁面。

    前往「Instance Templates」(執行個體範本) 頁面

  2. 按一下 [Create instance template] (建立執行個體範本) 按鈕,建立新的執行個體範本。
  3. 在「Container」(容器) 區段下,勾選 [Deploy container image] (部署容器映像檔)。
  4. 在「Container image」(容器映像檔) 下指定 Docker 映像檔名稱,然後設定執行容器的相關選項 (如有需要)。例如,您可為容器映像檔指定 gcr.io/cloud-marketplace/google/nginx1:15
  5. 按一下 [Create] (建立)。

接下來,使用新的執行個體範本建立代管執行個體群組。

gcloud

使用 gcloud compute instance-templates create-with-container 指令,建立用來執行 Docker 映像檔的執行個體範本:

 gcloud compute instance-templates create-with-container [TEMPLATE_NAME] \
 --container-image [DOCKER_IMAGE]

您也可以設定執行容器的選項 (如有需要)。

舉例來說,下列指令會建立名為 nginx-template 的新執行個體範本,其內容會包括 Docker 映像檔的相關資訊。當 VM 啟動時,從這個範本建立的 VM 執行個體即會啟動並執行 Docker 映像檔 gcr.io/cloud-marketplace/google/nginx1:15

 gcloud compute instance-templates create-with-container nginx-template \
     --container-image gcr.io/cloud-marketplace/google/nginx1:15

接下來,使用新的執行個體範本建立代管執行個體群組。

現在您已擁有執行個體範本,可用此來建立代管執行個體群組。舉例來說,如果要使用 gcloud 工具搭配您剛剛建立的 nginx-template 來建立代管執行個體群組,請執行下列指令:

gcloud compute instance-groups managed create example-group \
    --base-instance-name nginx-vm \
    --size 3 \
    --template nginx-template

更新執行容器的代管執行個體群組

您可以更新代管執行個體群組,以部署新版的 Docker 映像檔或新版的 Container-Optimized OS 映像檔。

將代管執行個體群組更新為新版本的容器映像檔

您可以使用 Managed Instance Group Updater,按照下列三個步驟,將新版的 Docker 映像檔部署至代管執行個體群組:

  1. 準備要部署的新 Docker 映像檔。
  2. 建立容器型範本的相同方式,建立以新 Docker 映像檔為基礎的執行個體範本。
  3. 使用 Managed Instance Group Updater,將代管執行個體群組更新為新的執行個體範本。

將代管執行個體群組更新為新版的 Container-Optimized OS 映像檔

Google 會定期更新 Container-Optimized OS 映像檔,您可能會想將這些更新套用到容器化代管執行個體群組,而不變更 Docker 映像檔。您可以使用 Google Cloud Platform Console 或 gcloud 指令列工具,按照下列兩個步驟,將代管執行個體群組更新為新版的 Container-Optimized OS 映像檔:

  1. 使用為新代管執行個體群組建立容器型範本的相同方式,建立以目前 Docker 映像檔版本為基礎的執行個體範本。根據預設,系統會使用支援的 Container-Optimized OS 映像檔最新版本。
  2. 使用 Managed Instance Group Updater,以新的執行個體範本更新代管執行個體群組。

使用 SSH 連線到容器

您可用 SSH 連線到 VM 上的容器,請使用 gcloud 工具執行加上 --container 標記的 gcloud compute ssh

gcloud compute ssh [INSTANCE_NAME] --container [CONTAINER_NAME]

其中:

  • [INSTANCE_NAME] 是 VM 執行個體名稱。
  • [CONTAINER_NAME] 是容器名稱。

進一步瞭解 gcloud compute ssh 指令及其引數。

查看記錄檔

您可以查看容器相關的三種類型記錄。

  1. 啟動代理程式記錄,也稱為 konlet 記錄。啟動代理程式會剖析容器的設定並執行工作,以在 Compute Engine VM 執行個體上啟動容器。

  2. Docker 事件記錄會回報容器事件,其中包括容器啟動與停止事件。如果您使用 COS 69 以上版本,即可使用這些記錄。

  3. 容器中的記錄包含在容器中執行的應用程式中的 STDOUT

查看啟動代理程式記錄

在序列主控台中、透過 journald 系統服務 (包含在 OS 映像檔中) 及透過 Stackdriver Logging,都可以取得啟動代理程式記錄。

在序列主控台中查看啟動代理程式記錄

Console

  1. 前往「VM instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 選取您要查看啟動代理程式記錄的 VM 執行個體。
  3. 在「Logs」(記錄) 下,按一下 [Serial port 1 (console)] (序列埠 1 (主控台)) 即可查看序列主控台記錄。

gcloud

使用 get-serial-port-output 指令查看執行個體序列埠的記錄。

gcloud compute instances get-serial-port-output [INSTANCE_NAME]

其中的 [INSTANCE_NAME] 是 VM 執行個體名稱。

舉例來說,您可以使用下列指令來查看名為 nginx-vm 的 VM 執行個體序列埠輸出:

gcloud compute instances get-serial-port-output nginx-vm

journald 中查看啟動代理程式記錄

  1. 使用 SSH 連線到含有容器的執行個體
  2. 執行 sudo journalctl 指令,查看 VM 啟動和容器啟動記錄。使用下列指令篩選容器啟動代理程式記錄 (konlet)。

    sudo journalctl -u konlet*
    

在 Logging 中查看啟動代理程式記錄

Console

  1. 在 Google Cloud Platform Console 中,前往「VM instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 選取您要查看啟動代理程式記錄的 VM 執行個體。
  3. 在「Logs」(記錄) 底下,按一下 [Stackdriver Logging] 即可查看 Stackdriver Logging 記錄。

  4. 輸入搜尋篩選器,擷取啟動代理程式記錄。

    如果您使用 COS 68 以下版本,請使用下列篩選器。

    resource.type="global"
    logName="projects/[PROJECT_ID]/logs/gcplogs-docker-driver"
    jsonPayload.container.imageName:"gcr.io/gce-containers/konlet"
    jsonPayload.instance.name="[INSTANCE_NAME]"
    

    如果您使用 COS 69 以上版本,請使用下列篩選器。

    resource.type="gce_instance"
    logName="projects/[PROJECT_ID]/logs/cos_system"
    jsonPayload.SYSLOG_IDENTIFIER="konlet-startup"
    jsonPayload._HOSTNAME="[INSTANCE_NAME]"
    

    其中:

    • [PROJECT_ID] 是執行個體所屬的專案 ID。
    • [INSTANCE_NAME] 是您要取得記錄的執行個體名稱。

gcloud

gcloud logging read 指令與適當的篩選器搭配使用,即可查看容器啟動代理程式記錄。

如果您使用 COS 68 以下版本,請使用下列指令與篩選器。

gcloud logging read "resource.type=global AND \
    logName=projects/[PROJECT_ID]/logs/gcplogs-docker-driver AND \
    jsonPayload.instance.name=[INSTANCE_NAME]"

如果您使用 COS 69 以上版本,請使用下列指令與篩選器。

gcloud logging read "resource.type=gce_instance AND \
    logName=projects/[PROJECT_ID]/logs/cos_system AND \
    jsonPayload.SYSLOG_IDENTIFIER=konlet-startup AND \
    jsonPayload._HOSTNAME=[INSTANCE_NAME]"

其中:

  • [PROJECT_ID] 是執行個體所屬的專案 ID。
  • [INSTANCE_NAME] 是您要取得記錄的執行個體名稱。

舉例來說,如要針對執行 COS 70 且存在於 my-project 的 VM 執行個體 nginx-vm,查看其在 Logging 中最近 10 筆啟動代理程式記錄,請使用下列指令。

gcloud logging read "resource.type=gce_instance AND \
    logName=projects/my-project/logs/cos_system AND \
    jsonPayload.SYSLOG_IDENTIFIER=konlet-startup AND \
    jsonPayload._HOSTNAME=nginx-vm" \
    --limit 10

查看 Docker 事件記錄

使用 COS 69 以上版本時,您可以在 journald 和 Stackdriver Logging 中查看 Docker 事件記錄。

journald 中查看 Docker 事件記錄

  1. 使用 SSH 連線到含有容器的執行個體
  2. 搭配下列篩選器執行 sudo journalctl 指令,即可查看 Docker 事件記錄。

    sudo journalctl -u docker-events-collector
    

在 Logging 中查看 Docker 事件記錄

Console

  1. 前往「VM instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 選取您要查看啟動代理程式記錄的 VM 執行個體。
  3. 在「Logs」(記錄) 底下,按一下 [Stackdriver Logging] 即可查看 Stackdriver Logging 記錄。

  4. 輸入下列搜尋篩選器,擷取 Docker 事件記錄。

    resource.type="gce_instance"
    logName="projects/[PROJECT_ID]/logs/cos_system"
    jsonPayload._HOSTNAME="[INSTANCE_NAME]"
    jsonPayload.SYSLOG_IDENTIFIER="docker"
    

    其中:

    • [PROJECT_ID] 是執行個體所屬的專案 ID。
    • [INSTANCE_NAME] 是您要取得記錄的執行個體名稱。

gcloud

gcloud logging read 指令與適當的篩選器搭配使用,即可查看 Docker 事件記錄。

gcloud logging read "resource.type=gce_instance AND \
      logName=projects/[PROJECT_ID]/logs/cos_system AND \
      jsonPayload._HOSTNAME=[INSTANCE_NAME] AND \
      jsonPayload.SYSLOG_IDENTIFIER=docker"

其中:

  • [PROJECT_ID] 是執行個體所屬的專案 ID。
  • [INSTANCE_NAME] 是您要取得記錄的執行個體名稱。

舉例來說,如要針對執行 COS 70 且存在於 my-project 的 VM 執行個體 nginx-vm,查看其在 Logging 中最近 10 筆 Docker 事件記錄,請使用下列指令。

gcloud logging read "resource.type=gce_instance AND \
    logName=projects/my-project/logs/cos_system AND \
    jsonPayload._HOSTNAME=nginx-vm AND \
    jsonPayload.SYSLOG_IDENTIFIER=docker" \
    --limit 10

查看容器記錄

Console

  1. 前往「VM instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 選取您要查看啟動代理程式記錄的 VM 執行個體。
  3. 在「Logs」(記錄) 底下,按一下 [Stackdriver Logging] 即可查看 Stackdriver Logging 記錄。

  4. 「Stackdriver Logging」頁面會載入預設搜尋篩選器。如果您使用 COS 69 以上版本,請檢查篩選器並複製 resource.labels.instance_id 的值,以供稍後使用。

  5. 更新搜尋篩選器,擷取容器記錄。

    如果您使用 COS 68 以下版本,請使用下列篩選器。

    logName="projects/[PROJECT_ID]/logs/gcplogs-docker-driver"
    jsonPayload.container.name="/[INSTANCE_NAME]"
    

    其中:

    • [PROJECT_ID] 是執行個體所屬的專案 ID。
    • [INSTANCE_NAME] 是您要取得記錄的執行個體名稱。

    如果您使用 COS 69 以上版本,請使用下列篩選器。

    resource.type="gce_instance"
    logName="projects/[PROJECT_ID]/logs/cos_containers"
    resource.labels.instance_id="[INSTANCE_ID]"
    

    其中:

    • [PROJECT_ID] 是執行個體所屬的專案 ID。
    • [INSTANCE_ID] 是您要取得記錄的執行個體 ID。

gcloud

gcloud logging read 指令與適當的篩選器搭配使用,即可查看容器記錄。

如果您使用 COS 68 以下版本,請使用下列指令與篩選器。

gcloud logging read "logName=projects/[PROJECT_ID]/logs/gcplogs-docker-driver AND \
    jsonPayload.container.name=/[INSTANCE_NAME]"

如果您使用 COS 69 以上版本,請執行下列操作:

  1. 決定您要取得其記錄的執行個體 ID。

    gcloud compute instances describe [INSTANCE_NAME] \
        --zone [ZONE] \
        --format="value(id)"
    

    其中:

    • [ZONE] 是執行個體所在的區域。
    • [INSTANCE_NAME] 是您要取得記錄的執行個體名稱。
  2. 使用下列指令與篩選器查看執行個體的容器記錄。

    gcloud logging read "resource.type=gce_instance AND \
        logName=projects/[PROJECT_ID]/logs/cos_containers AND \
        resource.labels.instance_id=[INSTANCE_ID]"
    

    其中:

    • [PROJECT_ID] 是執行個體所屬的專案 ID。
    • [INSTANCE_ID] 是執行個體的 ID。

    舉例來說,如要針對執行 COS 70、存在於 my-project 且執行個體 ID 為 555123456789012345 的 VM 執行個體,查看其在 Stackdriver 中最近 10 筆容器記錄,請使用下列指令。

    gcloud logging read "resource.type=gce_instance AND \
        logName=projects/my-project/logs/cos_containers AND \
        resource.labels.instance_id=555123456789012345" \
        --limit 10
    

指定容器最佳化的映像檔或映像檔系列

根據預設,容器化的 VM 執行個體或執行個體範本會使用支援的最新容器最佳化映像檔。這個映像檔屬於 cos-cloud 專案。

您可用來自 cos-stablecos-betacos-dev 映像檔系列中 62 以上版本的另一映像檔,或用這其中一個映像檔系列 (全都在 cos-cloud 專案中) 覆寫此預設值。

這些映像檔系列包含來自三個不同發布版本的容器最佳化映像檔:

  • dev 版本包含所有最新的變更,經常會更新。
  • beta 版本是 Beta 版的合格映像檔,不常更新。
  • stable 版本提供經過長期測試且支援的版本,極少更新並且只有重要更新 (視需要)。

舉例來說,使用 gcloud 工具時,可提供 --image 標記來覆寫預設的容器最佳化映像檔,或提供 --image-family 標記在建立 VM 時從指定系列中挑選最新的映像檔。

以下範例會建立容器化的 VM 執行個體,並使用來自 cos-dev 映像檔系列中的最新映像檔:

 gcloud compute instances create-with-container nginx-vm \
   --image-family cos-dev \
   --image-project cos-cloud \
   --container-image gcr.io/cloud-marketplace/google/nginx1:1.15

設定防火牆規則

容器化的 VM 會啟動網路設為主機模式的容器。容器共用主機網路堆疊,而主機中的所有介面都可提供給容器使用。

根據預設,Google Cloud Platform 防火牆規則會封鎖 VM 執行個體的所有連入連線,並允許 VM 執行個體的所有連出連線。

建立防火牆規則,讓您的執行個體允許連入連線,進而允許連線連入容器。

設定執行容器的選項

您可以設定下列選項來執行容器:

  • 指定容器重新啟動政策。
  • 覆寫容器 ENTRYPOINT (在容器啟動時所要執行的預設指令)。
  • 將引數傳遞到容器 ENTRYPOINT 指令。
  • 在特權模式中執行容器。
  • 掛接主機目錄或 tmpfs 做為容器內的資料磁碟區。
  • 設定環境變數。
  • 為容器執行階段中的 STDIN 分配緩衝區。
  • 分配虛擬 TTY。

進一步瞭解如何設定執行容器的選項

後續步驟