在虚拟机和托管实例组 (MIG) 上部署容器

您可以配置虚拟机实例或实例模板,以部署和启动 Docker 容器。Compute Engine 可提供安装了 Docker 的最新 Container-Optimized OS (COS) 映像,并在虚拟机启动时启动容器。

准备工作

选择在虚拟机和代管实例组 (MIG) 上部署容器

通过在 Compute Engine 上部署容器,您可以在控制虚拟机基础架构的同时简化应用部署。

  • 在配置和管理 Compute Engine 基础架构时,可采用与其他任何虚拟机相同的处理方式来管理正在运行容器的虚拟机。
  • 使用正在运行容器的代管实例组 (MIG) 来创建可扩缩的服务,这些实例组可以提供自动扩缩、自动修复、滚动更新、多区域部署和负载平衡等功能。
  • 使用熟悉的流程和工具(如 gcloud 命令行工具或 Compute Engine API)来管理具有容器的虚拟机。

或者,您可以考虑部署到 Google Kubernetes Engine 上,以便:

  • 运行大量的微服务
  • 拥有更快的容器启动速度
  • 利用 Kubernetes 自动编排功能,包括自动升级、节点自动修复和自动扩缩

如果在 Compute Engine 上使用单独的虚拟机来运行每个微服务,则可能会使操作系统开销占据费用的很大一部分。而借助 Google Kubernetes Engine,您可以在每个虚拟机实例上部署多个容器和容器组,从而更高效地将主机虚拟机资源分配给规模较小的微服务。

在 Compute Engine 上部署容器的工作原理

将软件部署到 Compute Engine 虚拟机实例上的常用方法包括:

  • 使用启动脚本cloud-init 在虚拟机启动时部署软件。
  • 创建一个预先安装了相应软件的自定义启动磁盘映像。

上述两种方法都可完成配置应用和设置操作系统环境的任务。作为开发者,您必须仔细跟踪和解析所有运行时依赖项。例如,如果在某个虚拟机上运行的两个应用使用的是同一个库的不同版本,您必须同时安装这两个版本,并通过系统变量指向它们。

在同一个库的不同版本上运行的应用。
一个虚拟机实例,其中的应用直接部署到操作系统

您也可以将容器中的软件部署到虚拟机实例或 MIG。容器包含应用软件和必要的库,并且与操作系统应用和库隔离。您可以在两个部署环境之间轻松迁移容器,而无需处理该容器及其操作系统中存在冲突的库版本。

容器中的应用。
将应用部署到容器中的一个虚拟机实例

以下是在 Compute Engine 上部署容器的流程:

  1. 将您的应用和所需的库捆绑打包到一个 Docker 映像中,并将该映像发布到 Container Registry 中(或者公开发布到 Docker Hub 或其他注册表中)。
  2. 在为 MIG管实例组创建虚拟机实例或实例模板时,您可以指定一个 Docker 映像名称和 docker run 配置。

在您发出创建虚拟机实例的请求后,Compute Engine 会执行以下任务:

  1. Compute Engine 会创建一个使用 Google 提供的Container-Optimized OS 映像的虚拟机实例。此映像中包含了 Docker 运行时环境和其他软件,用于启动您的容器。
  2. Compute Engine 将容器设置存储在实例元数据中的 gce-container-declaration 元数据键下。
  3. 在虚拟机启动时,Container-Optimized OS 映像使用存储在实例元数据中的 docker run 命令配置,从代码库中拉取容器映像,然后启动容器。
使用容器映像和 docker run命令。
创建一个运行容器的虚拟机实例或代管实例组的步骤

限制

  • 您只能为每个虚拟机实例部署一个容器。如果您需要为每个虚拟机实例部署多个容器,可考虑使用 Google Kubernetes Engine
  • 您只能从公共代码库或者从您有权访问的私有 Container Registry 代码库部署容器。不支持其他私有代码库。
  • 您无法将虚拟机实例的端口映射到容器的端口(Docker 的 -p 选项)。
  • 您只能通过这种部署方法来使用 Container-Optimized OS 映像
  • 您只能通过 Google Cloud Console 或 gcloud 命令行工具使用此功能,而不能通过 API 使用。

准备要用于部署的容器

选择以下方法之一,让 Compute Engine 能够访问您的容器映像:

  • 将您的 Docker 映像上传到 Container Registry。
  • 使用 Docker Hub 或其他注册表中任何公开提供的容器映像。

在新的虚拟机实例上部署容器

您可以使用 Google Cloud Consolegcloud 命令行工具在新的虚拟机实例上部署容器。

控制台

以下示例将 Google 提供的 Nginx Docker 映像 (https://gcr.io/cloud-marketplace/google/nginx1:latest) 中的一个容器部署到了虚拟机实例。如需使用其他 Docker 映像,请改为在下面的示例中指定您需要的映像。

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 点击创建实例以创建实例。

  3. 容器下,选择部署容器映像

  4. 容器映像下,指定容器映像名称,并根据需要配置运行容器时的选项。例如,您可以为容器映像指定 gcr.io/cloud-marketplace/google/nginx1:latest

  5. 点击创建

gcloud

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

gcloud compute instances create-with-container VM_NAME \
    --container-image DOCKER_IMAGE

例如,以下命令会创建名为 nginx-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

更新虚拟机实例上的容器

您可以使用 Google Cloud Console 或 gcloud 命令行工具更新 Docker 映像和配置选项,以在虚拟机实例上运行容器。

当您更新某个正在运行容器的虚拟机时,Compute Engine 会执行两个步骤:

  • 更新实例上的容器声明。Compute Engine 将更新后的容器声明存储在实例元数据中的 gce-container-declaration 元数据键下。
  • 如果实例正在运行,则停止并重启实例以使更新后的配置生效。如果实例已停止,则更新容器声明并使该实例保持停止状态。该虚拟机实例将下载新的映像并在虚拟机启动时启动容器。

控制台

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 点击要更新的实例的名称。

  3. 在“实例详情”页面上,点击修改

  4. 指定新的容器映像,并根据需要更新运行容器时的选项

  5. 点击保存并重启以保存您的更改。Compute Engine 将保存更改并自动重启实例以执行更新操作。虚拟机重启后,将下载新的映像并使用更新后的配置启动容器。

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 Consolegcloud 命令行工具将容器部署到新的代管实例组 (MIG):

  1. 根据某个 Docker 映像创建一个实例模板

  2. 根据新的实例模板创建MIG

控制台

以下示例将创建一个实例模板,用于将 Google 提供的 Nginxx (gcr.io/cloud-marketplace/google/nginx1:15) Docker 映像中的容器部署到 MIG。如需使用其他 Docker 映像,请在以下示例中指定所需的映像,而不使用 gcr.io/cloud-marketplace/google/nginx1:15

  1. 在 Google Cloud Console 中,转到实例模板页面。

    转到“实例模板”页面

  2. 如需创建实例模板,请点击创建实例模板

  3. 容器下,选择部署容器映像

  4. 容器映像下,指定 Docker 映像名称,并根据需要配置运行容器时的选项。例如,您可以为容器映像指定 gcr.io/cloud-marketplace/google/nginx1:15

  5. 点击创建

接下来,创建一个使用新实例模板的 MIG。

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 映像的信息。当虚拟机启动时,使用此模板创建的虚拟机实例将启动并运行 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

接下来,使用新的实例模板创建一个代管实例组。

您已拥有了一个实例模板,现在即可创建一个使用此实例模板的 MIG。例如,要使用gcloud工具和刚刚创建的nginx-template创建 MIG,请运行以下命令:

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

更新正在运行容器的代管实例组

您可以更新代管实例组 (MIG)以部署新版本的 Docker 映像或新版本的 Container-Optimized OS 映像。

将 MIG 更新至新版本的容器映像

您可以通过以下三个步骤使,用代管实例组更新程序将新版本的 Docker 映像部署到 MIG:

  1. 准备一个要部署的新 Docker 映像。
  2. 根据新的 Docker 映像创建一个实例模板,方法与创建基于容器的模板相同。
  3. 使用代管实例组更新程序,将代管实例组更新为使用新实例模板。

将代管实例组更新至新版本的 Container-Optimized OS 映像

Google 会定期更新 Container-Optimized OS 映像,而您可能希望在不更改 Docker 映像的情况下,将这些更新应用于容器化的 MIG。您可以通过以下两个步骤,使用 Google Cloud Console 或 gcloud 命令行工具将 MIG 更新至 Container-Optimized OS到容器优化的 OS 映像的新版本:

  1. 基于当前版本的 Docker 映像创建一个实例模板,创建方法与为新 MIG 创建基于容器的模板时相同。默认情况下,系统将使用最新的受支持 Container-Optimized OS 映像版本。
  2. 使用代管实例组更新程序,通过新的实例模板更新 MIG。

使用 SSH 连接到容器

您可以使用 SSH 连接到虚拟机上的容器。使用 gcloud 工具运行带有 --container 标志的 gcloud compute ssh 命令:

gcloud compute ssh VM_NAME --container CONTAINER_NAME

替换以下内容:

  • VM_NAME:虚拟机实例的名称
  • CONTAINER_NAME:容器的名称

详细了解 gcloud compute ssh 命令及其参数。

查看日志

您可以查看与容器相关的三种类型的日志:

  1. 启动代理日志(也称为 konlet{ class="external" target="github" } 日志)。启动代理会解析容器的配置并运行任务,以在 Compute Engine 虚拟机实例上启动容器。

  2. Docker 事件日志可报告容器事件(包括容器启动和停止事件)。如果您使用的是 COS 69 或更高版本,则可以使用这些日志。

  3. 容器中的日志包括在容器中运行的应用的 STDOUT

查看启动代理日志

您可以通过串行控制台、操作系统映像中包含的 journald 系统服务以及 Cloud Logging 查看启动代理日志。

在串行控制台中查看启动代理日志

控制台

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 选择您要查看启动代理日志的虚拟机实例。

  3. 日志下,点击串行端口 1(控制台)以查看串行控制台日志。

    日志串行端口 1。

gcloud

使用 get-serial-port-output 命令可查看实例串行端口上的日志。

gcloud compute instances get-serial-port-output VM_NAME

VM_NAME 替换为虚拟机实例的名称。

例如,使用以下命令可查看名为 nginx-vm 的虚拟机实例的串行端口输出:

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

journald 中查看启动代理日志

  1. 使用 SSH 通过容器连接到您的实例
  2. 执行 sudo journalctl 命令可查看虚拟机启动日志和容器启动日志。使用以下命令可过滤出容器启动代理日志 (konlet)。

    sudo journalctl -u konlet*
    

在 Logging 中查看启动代理日志

控制台

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 选择您要查看启动代理日志的虚拟机实例。

  3. 日志下,点击 Cloud Logging 以查看 Cloud Logging 日志。

    日志串行端口 1。

  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="VM_NAME"
    

    如果使用的是 COS 69 或更高版本,请使用以下过滤条件。

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

    替换以下内容:

    • PROJECT_ID:包含实例的项目 ID
    • VM_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=VM_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=VM_NAME"

替换以下内容:

  • PROJECT_ID:包含实例的项目 ID
  • VM_NAME:您要获取其日志的实例的名称

例如,如果名为 my-project 的虚拟机实例运行 COS 70 且位于 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 和 Cloud Logging 中查看 Docker 事件日志。

journald 中查看 Docker 事件日志

  1. 使用 SSH 通过容器连接到您的实例
  2. 使用以下过滤条件执行 sudo journalctl 命令可查看 Docker 事件日志。

    sudo journalctl -u docker-events-collector
    

在 Logging 中查看 Docker 事件日志

控制台

  1. 转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 选择您要查看启动代理日志的虚拟机实例。

  3. 日志下,点击 Cloud Logging 以查看 Cloud Logging 日志。

    日志串行端口 1。

  4. 输入以下搜索过滤条件,检索 Docker 事件日志。

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

    替换以下内容:

    • PROJECT_ID:包含实例的项目 ID
    • VM_NAME:您要获取其日志的实例的名称

gcloud

gcloud logging read 命令与相应的过滤条件结合使用可查看 Docker 事件日志。

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

替换以下内容:

  • PROJECT_ID:包含实例的项目 ID
  • VM_NAME:您要获取其日志的实例的名称

例如,如果名为 nginx-vm 的虚拟机实例运行 COS 70 且位于 my-project 中,则使用以下命令可在 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

查看容器日志

控制台

  1. 转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 选择您要查看启动代理日志的虚拟机实例。

  3. 日志下,点击 Cloud Logging 以查看 Cloud Logging 日志。

    日志串行端口 1。

  4. Cloud Logging 页面会加载默认搜索过滤条件。如果您使用的是 COS 69 或更高版本,请检查过滤条件并复制 resource.labels.instance_id 的值。您稍后会用到这个值。

  5. 更新搜索过滤条件以检索容器日志。

    如果使用的是 COS 68 或更低版本,请使用以下过滤条件。

    logName="projects/PROJECT_ID/logs/gcplogs-docker-driver"
    jsonPayload.container.name="/VM_NAME"
    

    替换以下内容:

    • PROJECT_ID:包含实例的项目 ID
    • VM_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=/VM_NAME"

如果使用的是 COS 69 或更高版本

  1. 确定您想要获取日志的实例的 ID。

    gcloud compute instances describe VM_NAME \
       --zone ZONE \
       --format="value(id)"
    

    替换以下内容:

    • `<ZONEVM_NAME: the zone where the instance is located
    • `VM_NAMEVM_NAME: the name of the instance that you want to get logs for
  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。

    例如,如果实例 ID 为 555123456789012345 的虚拟机实例运行 COS 70 且位于 my-project 中,则使用以下命令可在 Cloud Logging 中查看该实例的最后 10 个容器日志。

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

指定容器优化型映像或映像系列

默认情况下,系统会创建容器化虚拟机实例或实例模板,以使用受支持的最新容器优化型映像。该映像属于 cos-cloud 项目。

您可以使用 cos-stablecos-betacos-dev 映像系列(均在 cos-cloud 项目内)中的其他映像替换此默认值。

这些映像系列包括三个不同发布渠道的容器优化型映像:

  • dev 版包含所有最新更改,并且经常更新。
  • beta 版是目前处于测试阶段的合格映像,更新频率较低。
  • stable 版经过了更长时间的测试并且提供技术支持,只进行少量的关键更新(在必要情况下)。

例如,在创建虚拟机时,如果使用 gcloud 工具,则可以提供 --image 标志以替换默认的容器优化型映像,或者提供 --image-family 标志以从指定系列中选择最新映像。

以下示例可创建一个容器化虚拟机实例,该实例使用 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

配置防火墙规则

容器化虚拟机会将网络设置为主机模式并启动容器。容器可共享主机网络堆栈,并且主机提供的所有接口都可供容器使用。

默认情况下,Google Cloud 防火墙规则会阻止目标为虚拟机实例的所有传入连接,并允许来源为虚拟机实例的所有传出连接。

您可以创建防火墙规则以允许目标为实例的传入连接,从而允许目标为容器的传入连接。

配置运行容器时的选项

您可以配置以下运行容器时的选项:

  • 指定一项容器重启政策。
  • 替换容器 ENTRYPOINT(容器启动时要执行的默认命令)。
  • 将参数传递给容器 ENTRYPOINT 命令。
  • 在特权模式下运行容器。
  • 将主机目录或 tmpfs 装载为容器内的一个数据卷。
  • 设置环境变量。
  • 在容器运行时环境中为 STDIN 分配一个缓冲区。
  • 分配一个伪 TTY。

详细了解如何配置运行容器时的选项

后续步骤