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

您可以配置虚拟机实例或实例模板,以部署和启动 Docker 容器。Compute Engine 可提供安装了 Docker 的最新 Container-Optimized OS (COS) 映像,并在虚拟机启动时启动容器。如需详细了解在虚拟机上部署容器的优点,请阅读本主题后面的选择在虚拟机和实例组上部署容器

准备工作

选择在虚拟机和实例组上部署容器

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

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

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

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

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

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

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

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

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

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

您也可以将包含软件的容器直接部署到某个虚拟机实例或托管实例组中。每个容器都同时带有应用软件和所需的库,并且与主机操作系统的应用和库相隔离。您可以在各个部署环境之间轻松移动容器,而无需处理某个容器及其主机操作系统中存在冲突的库版本。

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

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

  1. 将您的应用和所需的库捆绑打包到一个 Docker 映像中,并将该映像发布到 Container Registry 中(或者公开发布到 Docker Hub 或其他注册表中)。
  2. 在为托管实例组创建虚拟机实例或实例模板时,您可以指定一个 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 Platform Console 或 gcloud 命令行工具使用此功能,而不能通过 API 使用。

准备要部署的容器

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

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

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

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

控制台

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

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

    转到“虚拟机实例”页面

  2. 点击创建实例按钮以创建新实例。
  3. 容器部分下,选中部署容器映像。
  4. 容器映像下指定一个容器映像名称,并根据需要配置运行容器时的选项。例如,您可以为容器映像指定 gcr.io/cloud-marketplace/google/nginx1:latest
  5. 点击创建

gcloud

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

 gcloud compute instances create-with-container [INSTANCE_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 Platform Console 或 gcloud 命令行工具更新 Docker 映像和配置选项,以在虚拟机实例上运行容器。

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

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

控制台

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

    转到“虚拟机实例”页面

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

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

  2. 利用新的实例模板创建一个托管实例组

控制台

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

  1. 转到实例模板页面。

    转到“实例模板”页面

  2. 点击创建实例模板按钮创建一个新的实例模板。
  3. 容器部分下,选中部署容器映像。
  4. 容器映像下指定 Docker 映像名称,并根据需要配置运行容器时的选项。例如,您可以为容器映像指定 gcr.io/cloud-marketplace/google/nginx1:15
  5. 点击创建

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

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

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

现在您已拥有一个实例模板,可以创建一个使用此实例模板的托管实例组。例如,要使用 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 映像。

将托管实例组更新至新版本的容器映像

您可以使用托管实例组更新程序将一个新版的 Docker 映像部署到某个托管实例组,具体分为三个步骤:

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

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

Google 会定期更新 Container-Optimized OS 映像,而您可能希望在不更改 Docker 映像的情况下将这些更新应用于容器化的托管实例组。您可以使用 Google Cloud Platform Console 或 gcloud 命令行工具将托管实例组更新为新版的 Container-Optimized OS 映像,具体分为两个步骤:

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

使用 SSH 连接到容器

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

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

其中:

  • [INSTANCE_NAME] 是虚拟机实例的名称。
  • [CONTAINER_NAME] 是容器的名称。

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

查看日志

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

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

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

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

查看启动代理日志

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

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

控制台

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

    转到“虚拟机实例”页面

  2. 选择您要查看哪个虚拟机实例的启动代理日志。
  3. 日志下,点击串行端口 1(控制台)以查看串行控制台日志。

gcloud

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

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

其中,[INSTANCE_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 Platform Console 中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 选择您要查看哪个虚拟机实例的启动代理日志。
  3. 日志下,点击 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] 是您想要获取其日志的实例的名称。

例如,如果名为 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 和 Stackdriver Logging 中查看 Docker 事件日志。

journald 中查看 Docker 事件日志

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

    sudo journalctl -u docker-events-collector
    

在 Logging 中查看 Docker 事件日志

控制台

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

    转到“虚拟机实例”页面

  2. 选择您要查看哪个虚拟机实例的启动代理日志。
  3. 日志下,点击 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] 是您想要获取其日志的实例的名称。

例如,如果名为 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. 日志下,点击 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。

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

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

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

您可以使用 cos-stablecos-betacos-dev 映像系列中版本 62 或更高版本的映像来覆盖此默认值,也可以使用这些映像系列(全部位于 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 Platform 防火墙规则会阻止目标为虚拟机实例的所有传入连接,并允许来源为虚拟机实例的所有传出连接。

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

配置运行容器时的选项

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

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

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

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Compute Engine 文档