向托管实例组 (MIG) 发布更新

托管实例组 (MIG) 包含一个或多个使用实例模板控制的虚拟机 (VM) 实例。如需更新 MIG 中的实例,您可以使用托管实例组更新程序功能对整个实例组发出更新请求。

如需了解详情,请参阅实例组

借助托管实例组更新程序,您可以将新版软件部署到托管实例组中的实例,并能控制部署速度、服务中断级别和更新范围。该更新程序有两个主要优势:

  • 自动根据您的要求发布更新,用户在发出初始请求后无需再进行额外输入。
  • 您可以执行部分发布并可用于测试。

允许在现有托管实例组中部署新软件后,您就无需在每次有新版软件发布时,都重新配置实例组或者重新连接负载平衡、自动扩缩或自动修复功能。如果没有此更新程序,那么在部署新软件版本时,您就必须新建一个使用新软件版本的托管实例组(在这种情况下,每次都要进行额外设置),或者由用户逐一手动重新创建实例。采用这两种方法时,整个操作过程都会涉及大量手动步骤。

准备工作

启动基本滚动更新

滚动更新是逐步向实例组中的所有实例应用更新,直到所有实例均已更新为止。您可以控制滚动更新的各个方面,例如可以脱机进行更新的实例数、两次更新实例之间的等待时间、更新是影响所有实例还是仅影响部分实例等等。

进行滚动更新时,请注意以下事项:

  • 更新是基于意图的。在您发出初始更新请求时,API 会返回一条成功响应消息来确认请求有效,但这并不表示更新已成功完成。您必须检查托管实例组的状态来确定您的更新是否已成功部署。

  • Instance Group Updater API 属于声明式 API。该 API 需要收到一个指定该托管实例组所需更新后配置的请求,而非显式函数调用。

  • 更新程序功能最多支持托管实例组中的两个实例模板版本。 这意味着您可以为托管实例组指定两个不同的实例模板版本,这对执行 Canary 更新很有帮助。

如需启动基本滚动更新以将更新应用于托管实例组中的所有实例,请按照以下说明操作。

控制台

  1. 转到 GCP Console 中的实例组页面。

    转到“实例组”页面

  2. 选择您要更新的实例组。
  3. 点击页面顶部的滚动更新
  4. 模板下,向下拉动下拉菜单并选择要据以更新的新模板。
  5. 对于目标大小,请输入 100% 以更新所有实例。
  6. 您可以视需要切换配置选项,例如更新是主动式(即托管实例组会主动替换实例)还是寻机式(即托管实例组不会主动替换实例,但会在以其他方式替换实例时应用更新)。 您还可以提供超额配置数量上限不可用选项数上限最短等待时间等选项。
  7. 点击更新以开始更新。

gcloud

使用 gcloud 命令行工具,运行 rolling-action start-update 命令:

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP] \
    --version template=[INSTANCE_TEMPLATE] [--zone [ZONE] | --region [REGION]]

其中:

  • [INSTANCE_GROUP] 是要更新的实例组的名称。
  • [INSTANCE_TEMPLATE] 是要据以更新实例组的新实例模板。
  • [ZONE][REGION] 分别是此实例组所在的地区和区域。如果为地区实例组,请提供地区。如果为区域实例组,请提供区域。

API

在 API 中,对以下网址发出 PATCH 请求:

https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instanceGroupManagers/[MANAGED_INSTANCE_GROUP_NAME]

如果是区域托管实例组,请将 zones/[ZONE] 替换为 regions/[REGION]

该请求载荷包含以下内容:

  • 要据以更新实例组的实例模板。
  • 该请求的更新政策和其他更新选项

以下示例展示了在 API 中启动更新所需的最低配置。

如果您未另行指定,则 maxSurgemaxUnavailable 属性将默认为 1 与受影响地区数量的乘积,这表示在更新期间,此更新程序仅将每个受影响地区中的 1 个实例设为不可用,并且仅在每个地区额外创建 1 个实例。

此示例请求将根据新的实例模板更新所有实例。

{
  "instanceTemplate": "global/instanceTemplates/example-template",
  "updatePolicy": {
    "type": "proactive"
   }
 }

发出请求后,您可以监控更新以便了解更新完成时间。

配置更新选项

对于较为复杂的更新,您可以针对特定更新请求配置额外选项。下文将对这些选项加以介绍。

超额配置数量上限

如果您要允许该更新程序在更新期间临时创建大小超过 targetSize 的新实例,请设置 maxSurge 属性。例如,如果您将 maxSurge 设置为 5,则托管实例组会使用新的实例模板创建最多 5 个大小超过目标大小的新实例。设置较高的 maxSurge 值可加快更新速度,但代价是会产生额外的实例,而这些实例将根据 Compute Engine 价格表进行计费。

如果您未设置 maxSurge 值,系统会采用默认值。对于地区托管实例组,maxSurge 的默认值为 1。对于区域托管实例组,默认值为 [NUMBER_OF_ZONES],其中 [NUMBER_OF_ZONES] 是与该区域托管实例组关联的地区数。

此选项仅在配置了 REPLACE 最少操作时才会发挥作用,但不可与 RESTART 操作设置一起使用。您可以指定固定数量;如果托管实例组中的实例数大于或等于 10 个,则可指定百分比。指定百分比时,该更新程序会根据需要将实例数向上舍入。

maxSurge 仅在您有足够的配额或资源来支持额外资源时才会发挥作用。

不可用实例数上限

如果您希望确保在更新期间的任何时候都只有特定数量的实例不可用,请设置 maxUnavailable 配置。例如,如果您将 maxUnavailable 设置为 5,那么系统一次只会将 5 个实例离线以进行更新。使用此参数可以控制更新对您的服务造成的干扰程度和更新的部署速度。

此数量也包含所有由于其他原因而无法使用的实例。举例来说,如果实例组正在执行调大规模的操作,那么正在创建中的实例可能就无法使用,并会计入 maxUnavailable 数量中。您可以指定固定数量;如果托管实例组中的实例数大于或等于 10 个,则可指定百分比。指定百分比时,该更新程序会根据需要将实例数向下舍入。

在地区托管实例组中,maxUnavailable 的默认值为 1。 在区域托管实例组中,[NUMBER_OF_ZONES](即选择的地区数)的默认值为 3

最短等待时间

如果您想要指定在等待多长时间后新创建或重启的实例才会被视为已更新,请设置 minReadySeconds。使用此功能可以控制更新的部署速度。在同时满足以下两个条件时,系统会启动计时器:

  • 实例的状态为 RUNNING
  • 已启用运行状况检查,且运行状况检查返回 HEALTHY

请注意,为了让运行状况检查返回 HEALTHY,该更新程序将执行以下操作:

  1. autohealingPolicies.initialDelaySec 指定的时间内,等待运行状况检查返回 HEALTHY
  2. 接着,按照 minReadySeconds 指定的时间进行等待。

如果运行状况检查未在 initialDelaySec 内返回 HEALTHY,则该更新程序将声明虚拟机实例运行状况不佳并可能会停止更新。当虚拟机实例在 initialDelaySecminReadySeconds 时间段内等待验证时,该实例的 currentAction 会显示为 VERIFYING。不过,底层虚拟机实例状态将仍为 RUNNING

如果未针对实例组进行运行状况检查,则计时器会在实例状态为 RUNNING 时启动。minReadySeconds 属性的最大值为 3600 秒(1 小时)。

最少操作

如果您想控制该更新程序为更新实例组中的实例而必须执行的最少操作,请设置最少操作属性。例如,如果您将 REPLACE 设置为最少操作,则无论是否有必要,都将删除所有受影响的实例并将其替换为新实例。

设置最少操作可保证该更新程序至少会执行该操作。但是,如果该更新程序确定您指定的最少操作不足以执行更新,它可能会执行更具中断性的操作。例如,如果将 RESTART 设置为最少操作,则该更新程序会尝试重启实例以应用更新。但是,如果更新需要更具中断性的操作,该更新程序将会执行这项操作。 举例来说,由于无法通过重启实例来完成实例操作系统的更改,因此该更新程序会将实例组中的实例替换为新的虚拟机实例。

适用的操作为 REPLACERESTART

  • RESTART:重启实例(执行 stopstart 请求)。 请注意,如果您的更新请求需要替换实例才能获取更改(例如,必须删除并替换实例才能更改映像),则系统将强制执行 REPLACE

  • REPLACE:删除现有实例并根据目标模板创建实例。该更新程序会使用所有新的实例属性(例如新的内部和外部 IP 地址)创建实例。

下图显示了这些选项会如何影响您的实例。

更新程序选项如何影响您的请求。

其他更新示例

下面介绍一些包含常用配置选项的命令行示例。

执行所有虚拟机实例的滚动更新,但一次最多创建 5 个超过目标大小的新实例

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[NEW_TEMPLATE] --max-surge 5 [--zone [ZONE] | --region [REGION]]

执行滚动更新时最多有 3 台机器不可用,并且至少要等待 3 分钟才能将新实例标记为可用

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[NEW_TEMPLATE] --min-ready 3m \
    --max-unavailable 3 [--zone [ZONE] | --region [REGION]]

例如,如果您有 1000 个实例并且运行了此命令,则该更新程序将先创建最多 100 个新实例,然后才会开始移除运行旧实例模板的实例。

执行所有虚拟机实例的滚动更新,但一次最多创建 10% 的超过目标大小的新实例

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[NEW_TEMPLATE] --max-surge 10% [--zone [ZONE] | --region [REGION]]

启动 Canary 更新

通过实例组更新程序功能,您可以执行 Canary 更新,如此便能先随机对部分实例测试您的更新,然后再将更新提交到整个实例组。

Canary 更新是对实例组中的部分实例应用的更新,可让您对部分实例进行新功能或升级的测试,从而避免向所有实例发布可能造成中断的更新。如果更新不顺利,您只需要回滚少量实例即可,这样就最大限度地减少了对用户造成的中断。从服务器的角度来看,Canary 更新与标准滚动更新相同,只不过应更新的实例数小于实例组的总大小。与标准滚动更新一样,Canary 更新会造成受影响的实例中断;也就是说,在更新期间,受影响的实例会被删除并替换为新的虚拟机实例。

如需启动 Canary 更新,请执行以下操作:

  • 您最多可以指定两个实例模板版本,通常新实例模板用于 Canary 更新,而当前实例模板则用于其余实例。例如,您可以指定系统根据 new-instance-template 创建 20% 的实例,同时继续在 old-instance-template 上运行其余实例。不能同时指定两个以上的实例模板。

  • 您必须始终为 Canary 版本指定目标大小 (targetSize)。如果您省略 Canary 版本的目标大小,就无法启动 Canary 更新。例如,如果您指定应将 10% 的实例用于 Canary 更新,则剩余的 90% 将不受影响并使用当前实例模板。

控制台

  1. 转到 GCP Console 中的实例组页面。

    转到“实例组”页面

  2. 选择您要更新的实例组。
  3. 点击页面顶部的滚动更新
  4. 点击添加模板并选择要执行 Canary 的新实例模板。
  5. 目标大小下,输入要用于对新实例模板执行 Canary 更新的实例数百分比或固定实例数。
  6. 您可以视需要切换配置选项,例如更新是主动式(即托管实例组会主动删除并替换实例)还是寻机式(即托管实例组不会主动替换实例,但会在出于其他目的创建实例时应用更新)。 您还可以提供超额配置数量上限不可用选项数上限最短等待时间等选项。
  7. 点击更新以开始更新。

gcloud

使用 gcloud 命令行工具,提供当前模板和新模板,以明确表示应该使用每个模板的实例数量:

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[CURRENT_TEMPLATE] \
    --canary-version template=[NEW_TEMPLATE],target-size=[SIZE] \
    [--zone [ZONE] | --region [REGION]]

其中:

  • [CURRENT_TEMPLATE] 是实例组正在运行的当前模板的名称。
  • [NEW_TEMPLATE] 是您要执行 Canary 更新的新模板。
  • [SIZE] 是您要应用此更新的实例数量或百分比。您必须将 target-size 属性应用于 --canary-version 模板。只有在实例组包含 10 个或更多实例时才能设置百分比。
  • [ZONE][REGION] 分别是此实例组所在的地区和区域。如果为地区实例组,请提供地区。 如果为区域实例组,请提供区域。

例如,以下命令在执行 Canary 更新时会将 my-template-b 发布到实例组中 10% 的实例:

gcloud compute instance-groups managed rolling-action start-update my-ig1 \
        --version template=my-template-A --canary-version template=my-template-B,target-size=10%

API

在 API 中,向以下 URI 发出 PATCH 请求:

https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instanceGroupManagers/[INSTANCE_GROUP_NAME]

请求载荷应包含当前实例模板和您要执行 Canary 更新的新实例模板。例如:

{
 "versions": [
  {
   "instanceTemplate": "global/instanceTemplates/[NEW_TEMPLATE]",
   "targetSize": {
    "[percent|fixed]": [NUMBER|PERCENTAGE] # Use `fixed` for a specific number of instances
   }
  },
  {
   "instanceTemplate": "global/instanceTemplates/[CURRENT_TEMPLATE]"
  }
 ]
}

其中:

  • [NEW_TEMPLATE] 是您要执行 Canary 更新的新模板的名称。
  • [NUMBER|PERCENTAGE] 是要执行此 Canary 更新的实例的固定数量或百分比。只有在实例组包含 10 个或更多实例时才能设置百分比。否则,请提供固定数量。
  • [CURRENT_TEMPLATE] 是该实例组正在运行的当前模板的名称。

前滚 Canary 更新

运行 Canary 更新后,您可以决定是要将更新提交至整个实例组,还是要回滚更新。

控制台

  1. 转到 GCP Console 中的实例组页面。

    转到“实例组”页面

  2. 选择您要更新的实例组。
  3. 点击页面顶部的滚动更新
  4. 模板下,将 Canary 模板的目标大小更新为 100%,以将模板前滚到所有实例。或者,您可以将主模板替换为 Canary 模板,并将目标大小设置为 100%。然后,您可以将第二个模板字段完全移除。
  5. 点击更新以开始更新。

gcloud

如果要提交 Canary 更新,请前滚更新,方法是发出相同的更新请求,但仅设置 version 并省略 --canary-version。使用 gcloud 命令行工具:

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[NEW_TEMPLATE] [--zone [ZONE] | --region [REGION]]

API

在 API 中,向以下 URI 发出 PATCH 请求:

https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instanceGroupManagers/[INSTANCE_GROUP_NAME]

在请求正文中,将新实例模板指定为 version,并从请求正文中省略旧实例模板。省略目标大小规格可将更新发布到所有实例。例如,您的请求正文应如下所示:

{
"versions": [
   {
   "instanceTemplate": "global/instanceTemplates/[NEW_TEMPLATE]" # New instance template
   }
 ]
}

请将 [NEW_TEMPLATE] 替换为您要前滚的新实例模板的名称。

启动寻机更新或主动更新

默认情况下,使用 gcloud 命令行工具进行的更新是主动更新,而在 API 中发起的更新则是寻机更新。

对于主动更新,Compute Engine 会主动调度操作以根据需要将请求的更新应用于实例。在许多情况下,这通常意味着主动删除并重新创建实例。

此外,如果主动更新可能更具中断性,您可以选择执行寻机更新。只有在手动启动对选定实例的更新或托管实例组创建新实例时,系统才会应用寻机更新。如果托管实例组由其他服务(例如自动扩缩程序)调整大小或由用户手动调整大小,则托管实例组会创建新实例。 Compute Engine 不会主动发出应用寻机更新的请求。

在某些情况下,寻机更新非常有用,因为如果可避免的话,您肯定不希望导致系统不稳定。例如,如果您有可根据需要应用、没有任何紧急性的非关键更新,并且您的托管实例组会主动进行自动扩缩,则可执行寻机更新,以免 Compute Engine 主动删除要应用该更新的现有实例。

如需选择寻机更新或主动更新,请使用 gcloud 命令行工具或 API 将类型属性设置为 OPPORTUNISTICPROACTIVE

控制台

  1. 转到 GCP Console 中的实例组页面。

    转到“实例组”页面

  2. 选择您要更新的实例组。
  3. 点击页面顶部的滚动更新
  4. 模板下,选择要据以更新您的实例组的模板,并为该模板选择目标大小。
  5. 更新模式下,选择寻机更新或主动更新。
  6. 点击更新以开始更新。

gcloud

使用 gcloud 命令行工具:

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[INSTANCE_TEMPLATE] \
    --type [opportunistic|proactive] [--zone [ZONE] | --region [REGION]]

API

在要启动更新的请求载荷中,请将 type 属性添加到 updatePolicy 中:

{
"updatePolicy": {
  "type": "PROACTIVE" # Performs a proactive update
},
"versions": [{
  "instanceTemplate": "global/instanceTemplates/[NEW_TEMPLATE]",
  }]
}

其中,[NEW_TEMPLATE] 是您要执行 Canary 更新的新模板的名称。 如果您要进行寻机更新,请将 PROACTIVE 替换为 OPPORTUNISTIC

更新选定实例

启动寻机更新时,您必须等待 Compute Engine 发布更新的机会。但是,如果您希望加强对发布的控制,则可以立即在托管实例组中的特定实例上手动启动这项更新。

手动启动更新可让您进行以下操作:

  • 选择您要更新的实例。
  • 应用更新时尽量避免为完成更新而必须执行的中断性操作。例如,如果您只是更新元数据,可能不需要重启实例就能完成更新。手动启动更新时,系统将自动执行最少的必要操作。
  • 强制执行实例重启或重新创建,即使这些并不是应用更新所必需的操作。例如,即使您只是更新元数据,也可能想要重启虚拟机,因为您的访客软件只有在虚拟机启动时才能获得新的元数据。
  • 在更新造成的中断程度超出您的承受范围时阻止更新。
  • 立即执行所有选定实例的更新,而无需通过 maxSurgemaxUnavailable 限制条件来限制发布。

最少操作和允许的最具中断性的操作

更新可能会导致实例状态中断,具体取决于更新的性质。例如,如果要更改实例的机器类型,则必须重启虚拟机;而如果要更改实例的启动映像,则必须删除并替换实例。

您可以使用 minimal-actionmost-disruptive-allowed-action 标志来控制中断级别:

  • minimal-action 可让您强制执行中断程度高于需求的操作。
  • most-disruptive-allowed-action 可让您在中断程度超出您的承受范围时阻止更新。

更新选定的实例时,这两个标志都接受以下操作:

操作说明可更新哪些实例属性?
NONE完全不中断实例。无。
REFRESH不停止实例。辅助磁盘、实例元数据、标签。
RESTART停止实例并重启。机器类型。
REPLACE删除实例并重新创建。实例模板中存储的所有实例属性。

minimal-action 的默认值为 NONE。如果您的更新需要执行中断程度高于此标志设置的操作,则 Compute Engine 会执行必要的操作来执行更新。

most-disruptive-allowed-action 的默认值为 REPLACE。如果您的更新需要执行中断程度高于此标志设置的操作,则更新请求将失败。举例来说,如果您将“重启”设置为允许的最具中断性的操作,则更新启动磁盘映像的尝试将失败,因为该更新需要重新创建实例,此操作比重启更具中断性。

您可以使用 gcloud 工具或 API 更新选定实例。

gcloud

启动寻机更新后,使用 update-instances 子命令将更新应用于特定实例。

gcloud beta compute instance-groups managed update-instances [INSTANCE_GROUP] \
    --instances [INSTANCE_NAMES] \
    --most-disruptive-allowed-action [DISRUPTION_LEVEL] \
    --minimal-action [DISRUPTION_LEVEL]

其中:

  • [INSTANCE_GROUP] 是具有待执行更新的实例组的名称。
  • [INSTANCE_NAMES] 是要立即更新的一系列实例。
  • [DISRUPTION_LEVEL] 是最低或最高中断级别,可能的值为 NONEREFRESHRESTARTREPLACE
    • minimal-action 的默认值为 NONE
    • most-disruptive-allowed-action 的默认值为 REPLACE

如果您需要等待所有指定的实例完成更新,请查看实例组的状态,并等到实例组达到稳定状态。

API

启动寻机更新后,构造对测试版 regionInstanceGroupManagers.applyUpdatesToInstances 方法的 POST 请求。对于地区托管实例组,请使用地区 instanceGroupManagers.applyUpdatesToInstances 方法。

POST https://compute.googleapis.com/compute/beta/projects/[PROJECT]/regions/[REGION]/instanceGroupManagers/[INSTANCE_GROUP_NAME]/applyUpdatesToInstances
{
  "instances": "zones/[ZONE]/instances/[INSTANCE_NAME]","zones/[ZONE]/instances/[INSTANCE_NAME]"
  "minimalAction": [DISRUPTION_LEVEL],
  "mostDisruptiveAllowedAction": [DISRUPTION_LEVEL]
}

其中:

  • [INSTANCE_GROUP_NAME] 是具有待执行更新的实例组的名称。
  • [ZONE] 是要立即更新的实例所在的地区。
  • [INSTANCE_NAME] 是要立即更新的实例的名称。
  • [DISRUPTION_LEVEL] 是最低或最高中断级别,可能的值为 NONEREFRESHRESTARTREPLACE
    • minimalAction 的默认值为 NONE
    • mostDisruptiveAllowedAction 的默认值为 REPLACE

与其他托管实例组方法类似,applyUpdatesToInstances 也是基于意图,这意味着该方法会返回操作响应。操作状态变为 DONE 后,listManagedInstances 将包含一系列实例,这些实例的 currentAction 字段已更改为 REFRESHINGRESTARTINGRECREATING。如果操作失败(例如,因对实例组进行并发更改而失败),系统将在 lastAttempt.errors 字段中记录为失败。

如果您需要等待所有指定的实例完成更新,请查看实例组的状态,并等到实例组达到稳定状态。

执行滚动替换或重启

您也可以使用 restartreplace 命令,对托管实例组中的虚拟机实例执行滚动重启或滚动替换。与 start-update 命令类似,您可以为重启或替换指定任意配置选项。滚动重启或替换不会更改有关实例组的任何内容,包括实例模板。它只是使用您选择的方法来刷新组中的实例。

需要执行滚动替换或滚动重启的原因可能有许多。例如,您可能想要不时地刷新虚拟机实例以实现以下目标:

  • 清除内存泄漏问题。
  • 重启您的应用,让它可从全新机器运行。
  • 强制将定期替换作为测试虚拟机的最佳做法。
  • 更新虚拟机的操作系统映像,或重新运行启动脚本来更新软件。

如需执行替换以删除所有实例并将其替换为新实例,请执行以下操作:

控制台

  1. 转到 GCP Console 中的实例组页面。

    转到“实例组”页面

  2. 选择您要更新的实例组。
  3. 点击页面顶部的滚动式重新启动/替换
  4. 选择您要重启还是替换实例。重启操作会对实例执行 stopstart 方法,而替换操作会主动删除并创建实例。
  5. 您可以视需要切换超额配置数量上限不可用选项数上限最短等待时间等配置选项。
  6. 点击重启或替换按钮以开始更新。

gcloud

gcloud compute instance-groups managed rolling-action replace [INSTANCE_GROUP]

此命令会以一次一个的方式替换托管实例组中的所有实例。如果完全替换操作会造成过大的中断影响,您可以改为指定滚动重启,这样就不会删除任何实例,而只是重启每个实例。

gcloud compute instance-groups managed rolling-action restart [INSTANCE_GROUP]

您可以使用更新所适用的选项(例如 maxSurgemaxUnavailablemin-ready)进一步自定义其中的每条命令。

API

在 API 中,针对实例组发出 PATCH 请求并设置主动 updatePolicy,其中 minimalActionRESTARTREPLACE,具体取决于您是要执行滚动替换以删除每个实例并将其替换为新实例,还是要执行滚动重启以停止并重启每个实例。在 RESTARTREPLACE 这两种情况下,您都必须始终提供 versions.instanceTemplateversions.name 属性(例如 v2)以触发操作。

对于滚动替换,请求可能如下所示:

PATCH https://compute.googleapis.com/compute/v1/projects/myproject/zones/[ZONE]/instanceGroupManagers/[INSTANCE_GROUP_NAME]

{
 "updatePolicy": {
  "minimalAction": "REPLACE",
  "type": "PROACTIVE"
 },
 "versions": [
  {
   "instanceTemplate": "global/instanceTemplates/example-template",
   "name": "v2"
  }
 ]
}

对于滚动重启,请求可能如下所示:

PATCH https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instanceGroupManagers/[INSTANCE_GROUP_NAME]

{
 "updatePolicy": {
  "minimalAction": "RESTART",
  "type": "PROACTIVE"
 },
 "versions": [
  {
   "instanceTemplate": "global/instanceTemplates/example-template",
   "name": "v2"
  }
 ]
}

其他替换/重启示例

以一次两个的方式执行所有虚拟机的滚动重启

以下命令会以一次两个的方式重启实例组中的所有虚拟机。 请注意,此命令没有指定新实例模板。

gcloud compute instance-groups managed rolling-action restart [INSTANCE_GROUP_NAME] \
    --max-unavailable 2 [--zone [ZONE] | --region [REGION]]

尽快对所有虚拟机执行滚动重启

gcloud compute instance-groups managed rolling-action restart [INSTANCE_GROUP_NAME] \
    --max-unavailable 100% [--zone [ZONE] | --region [REGION]]

尽快对所有虚拟机执行滚动替换

gcloud compute instance-groups managed rolling-action replace [INSTANCE_GROUP_NAME]  \
    --max-unavailable 100% [--zone [ZONE] | --region [REGION]]

更新区域托管实例组

区域托管实例组包含分布在同一区域内多个地区的虚拟机实例,这与地区托管实例组(仅包含一个地区中的实例)不同。通过区域托管实例组,您可以将实例分布到多个地区,从而提高应用的可用性,并能应对一个地区发生故障或整个实例组停止响应等极端情况。

使用实例组更新程序功能更新区域托管实例组的过程与对地区托管实例组执行更新的过程相同,但有一些例外,具体如下所述。在您启动对区域实例组的更新时,该更新程序将始终按比例均匀地在各地区之间更新实例;您无法选择要优先更新哪些地区的哪些实例,也无法仅更新一个地区的实例。

更新区域托管实例组与更新地区托管实例组之间的差异

在启动对区域托管实例组的更新之前,您应该先了解它与地区托管实例组更新之间的几点不同表现。

  • 区域托管实例组的默认更新参数是 maxUnavailable=[NUMBER_OF_ZONES]maxSurge=[NUMBER_OF_ZONES],其中 [NUMBER_OF_ZONES] 是为区域托管实例组选择的地区数,默认值为 3

  • 如果您在指定更新时使用的是固定数量,则该固定数量必须为 0,或是大于等于区域托管实例组的关联地区数。例如,如果实例组分布于三个地区,您就不能将 maxSurge 设置为 12,因为该更新程序必须分别在这三个地区中创建一个额外实例。

在更新请求中使用固定数量或百分比

如果您在更新请求中指定固定数量,则系统会将您指定的数量与区域托管实例组中的地区数相除,并根据所得的结果均匀分配实例。例如,如果您指定了 maxSurge=10,那么该更新程序将用 10 除以该区域中的地区数,并根据计算所得的值创建实例。如果实例数不能被地区数整除,则该更新程序会将多余的实例随机添加到其中一个地区。因此,举例来说,如果将 10 个实例分布到 3 个地区,那么其中的两个地区会得到 3 个实例,一个地区会得到 4 个实例。该逻辑同样适用于 Canary 更新的 maxUnavailabletargetSize 参数。

只有在您的托管实例组包含 10 个或更多虚拟机实例时,您才能指定百分比。百分比的处理方式因具体情况而略有不同:

  • 如果您以百分比形式指定要进行 Canary 更新的虚拟机实例数量,则该更新程序会尝试在各地区之间均匀分布实例。每个地区的余数会向上或向下舍入,但每个实例组的总差不会超过 1 个虚拟机实例。例如,对于有 10 个实例且目标大小百分比为 25% 的托管实例组,系统会将更新发布到 2 到 3 个虚拟机实例。

  • 如果您以百分比形式指定了 maxSurgemaxUnavailable 等更新选项,则系统会分别针对每个地区舍入余数。适用于更新地区托管实例组的规则也同样适用于此处。

监控更新

启动滚动更新后,更新需要一段时间才能完成。如需监控更新进度,您可以检查托管实例组的 status,或者检查托管实例组中每个实例的 currentAction

实例组状态

在实例组级层,Compute Engine 会填充一个名为 status 的只读字段,该字段包含 versionTarget.isReachedisStable 标志。您可以使用 gcloud 工具API 来访问这些标记。

如需验证您对实例组的更新已完成发布,请查看 status.versionTarget.isReached==true。如需验证实例组中的所有实例正在运行且运行状况良好(即每个托管实例的 currentAction 均为 NONE),请查看 status.isStable==true。请注意,托管实例组的稳定性取决于更新程序之外的实例组配置;举例来说,如果您的实例组采用自动扩缩机制,并且当前正在纵向扩容,那么由于自动扩缩程序操作的关系,状态值将显示为 isStable==false

此外,您还可以使用控制台来查看更新中实例的当前数量和计划数量。

控制台

您可以转到特定实例组的详情页面来监控实例组的滚动更新。

  1. 转到 GCP Console 中的实例组页面。

    转到“实例组”页面

  2. 选择要监控的实例组。实例组的概览页面显示每个实例正在使用的模板。
  3. 如需查看详细信息,请点击详情标签页。

详情页面会显示各实例模板的更新中实例的当前数量和计划数量,同时还会显示更新参数。

gcloud

gcloud beta compute instance-groups managed describe [INSTANCE_GROUP_NAME] \
    [--zone [ZONE] | --region [REGION]]

gcloud 工具会返回实例组的的相关详细信息,包括 status.versionTarget.isReachedstatus.isStable 字段。

API

在 API 中,向以下 URI 发出 POST 请求:

POST https://compute.googleapis.com/compute/beta/projects/[PROJECT_ID]/zones/[ZONE]/instanceGroupManagers/[INSTANCE_GROUP_NAME]/get

如果是区域托管实例组,请将 zones/[ZONE] 替换为 regions/[REGION]

API 会返回实例组的相关详细信息,包括 status.versionTarget.isReachedstatus.isStable 字段。

status.versionTarget.isReached(测试版)

当实例组中的所有虚拟机实例都已经是目标版本或正在创建为目标版本时,系统即认为更新发布完成。在完全发布的情况下,所有实例都配置为使用新的实例模板。而在部分发布的情况下,系统会根据实例模板之间的指定拆分目标配置实例。

您可以通过检查 instanceGroupManagers(或 regionInstanceGroupManagers)资源的 status.versionTarget.isReached 字段值来确认更新发布是否已完成。

  • 如果所有虚拟机实例都已经是目标版本或正在创建为目标版本 (versions[]),则 status.versionTarget.isReached 会设置为 true
  • 如果至少有一个虚拟机尚未使用目标版本 (versions[]),则 status.versionTarget.isReached 会设置为 false。或者,在 Canary 更新的情况下,如果使用目标版本 (versions[].instanceTemplates) 的虚拟机数量与其目标大小 (versions[].targetSize) 不匹配,则 status.versionTarget.isReached 会设置为 false

您还可以使用带 --version-target-reached 标志的 gcloud beta compute instance-groups managed wait-until 命令,等待该实例组的 status.versionTarget.isReached 设置为 true

gcloud beta compute instance-groups managed wait-until INSTANCE_GROUP_NAME \
    --version-target-reached \
    [--zone [ZONE] | --region [REGION]]

status.isStable

如需验证托管实例组正在运行且运行状况良好,检查关联 instanceGroupManagersregionInstanceGroupManagers 资源的 status.isStable 字段值即可。

您还可以将 gcloud 命令行工具 wait-until 命令与 --stable 标志搭配使用,等待该实例组的 status.isStable 设置为 true

gcloud beta compute instance-groups managed wait-until INSTANCE_GROUP_NAME \
    --stable \
    [--zone [ZONE] | --region [REGION]]

status.isStable 设置为 false 时,表示更改已生效、有待处理的更改或托管实例组本身正被修改。

status.isStable 设置为 true 时,则表示以下含义:

  • 托管实例组中的任何实例都未在进行任何类型的更改,并且所有实例的 currentAction 均为 NONE
  • 托管实例组中的实例没有任何待处理的更改。
  • 托管实例组本身未在进行修改。

您可以通过多种方式来修改托管实例组,例如:

  • 发出发布新实例模板的请求。
  • 发出创建、删除、调整或更新实例组中实例的请求。
  • 通过自动扩缩程序请求调整实例组的大小。
  • 通过自动修复程序资源替换托管实例组中一个或多个运行状况不佳的实例。
  • 重新分配区域托管实例组中的部分实例。

完成所有操作后,该托管实例组的 status.isStable 会立即重新设置为 true

当前对实例的操作

如需查看托管实例组中每个实例的 status 及其正在执行的 currentAction,您可以使用 gcloud 命令行工具API

gcloud

gcloud compute instance-groups managed list-instances [INSTANCE_GROUP_NAME] [--filter="zone:([ZONE])" | --filter="region:([REGION])"]

gcloud 会返回实例组中的实例列表,以及各实例的状态和当前操作。例如:

NAME               ZONE           STATUS    ACTION    INSTANCE_TEMPLATE  VERSION_NAME  LAST_ERROR
vm-instances-9pk4  us-central1-f            CREATING  my-new-template
vm-instances-h2r1  us-central1-f  STOPPING  DELETING  my-old-template
vm-instances-j1h8  us-central1-f  RUNNING   NONE      my-old-template
vm-instances-ngod  us-central1-f  RUNNING   NONE      my-old-template

API

在 API 中,向 regionInstanceGroupManagers.listManagedInstances 方法发出 POST 请求。对于地区托管实例组,请使用 instanceGroupManagers.listManagedInstances 方法。

POST https://compute.googleapis.com/compute/v1/projects/project-id/regions/region/instanceGroupManagers/instance-group-name/listManagedInstances

API 会返回该实例组的实例列表,其中包含每个实例的 instanceStatuscurrentAction

{
 "managedInstances": [
  {
   "instance": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/vm-instances-prvp",
   "id": "5317605642920955957",
   "instanceStatus": "RUNNING",
   "instanceTemplate": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/instanceTemplates/[INSTANCE_TEMPLATE_NAME]",
   "currentAction": "REFRESHING"
  },
  {
   "instance": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/vm-instances-pz5j",
   "currentAction": "DELETING"
  },
  {
   "instance": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/vm-instances-w2t5",
   "id": "2800161036826218547",
   "instanceStatus": "RUNNING",
   "instanceTemplate": "https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/instanceTemplates/[INSTANCE_TEMPLATE_NAME]",
   "currentAction": "REFRESHING"
  }
 ]
}

对于托管实例组中的每个实例,实例的状态均由其 instanceStatus 字段描述。如需查看有效 instanceStatus 字段值的列表,请参阅检查实例的状态

如果实例正在进行某类更改,则系统会在 currentAction 字段中填入以下某一操作,以帮助您跟踪更改进度。否则,currentAction 字段为 NONE

可能的 currentAction 值如下:

  • ABANDONING:正在将该实例从托管实例组中移除。
  • CREATING:该实例正在创建中。
  • CREATING_WITHOUT_RETRIES:正在创建该实例,且不会重试;如果第一次尝试并未创建该实例,则托管实例组将不会再次尝试替换该实例。
  • DELETING:正在删除该实例。
  • RECREATING:该实例已被删除并且正在被替换。
  • REFRESHING:该实例正从其当前目标池中移除,并正在被读取到当前目标池列表中(此列表与现有目标池可能相同,也可能不同)。
  • RESTARTING:正在使用 stopstart 方法重启该实例。
  • VERIFYING:该实例已创建并且正在接受验证。
  • NONE:当前并未对该实例执行任何操作。

回滚更新

目前没有明确的命令可用于将更新回滚到以前的版本,但是,如果您决定要回滚更新(无论是完全提交的更新还是 Canary 更新),则可以发出新的更新请求并传入要回滚到的目前实例模板。

例如,以下命令会尽快回滚更新:

gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
    --version template=[OLD_INSTANCE_TEMPLATE] --max-unavailable 100% [--zone [ZONE] | --region [REGION]]

请将 [OLD_INSTANCE_TEMPLATE] 替换为您要回滚到的目标实例模板的名称。

在 API 中,向以下 URI 发出 PATCH 请求:

https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instanceGroupManagers/[INSTANCE_GROUP_NAME]

如果是区域托管实例组,请将 zones/[ZONE] 替换为 regions/[REGION]

在请求正文中,将 version 指定为旧实例模板:

{ "updatePolicy":
  {
    "maxUnavailable":
    {
      "percent": 100
    }
  },
 "versions": [
    {
      "instanceTemplate": "global/instanceTemplates/[OLD_TEMPLATE]" # Old instance template
    }
   ]
}

如果是实例数少于 10 个的区域托管实例组,您必须在 maxUnavailable 中使用固定值,并将该值设置为该实例组中的实例数:

{ "updatePolicy":
  {
    "maxUnavailable":
    {
      "fixed": [NUMBER_OF_INSTANCES_IN_GROUP]
    }
  },
 "versions": [
    {
      "instanceTemplate": "global/instanceTemplates/[OLD_TEMPLATE]" # Old instance template
    }
   ]
}

实例组更新程序服务会将此视为常规更新请求,因此本文中所述的所有更新选项都可以与您的请求一起指定。

控制更新速度

默认情况下,当您发出更新请求时,服务会尽快执行更新。如果您不确定是要完全应用更新还是尝试性测试更改,可以使用以下方法来控制更新速度。

  1. 启动 Canary 更新而非完全更新。
  2. 设置较大的 minReadySeconds 值。设置此值可确保服务在等待此指定秒数后,才会将实例视为已成功更新并继续处理下一个实例。
  3. 启用运行状况检查。这种方式可确保服务等到应用启动并报告运行状况良好信号后,才会将实例视为已成功更新并继续处理下一个实例。
  4. 设置较低的 maxUnavailablemaxSurge 值。这种方式可确保一次只更新最少数量的实例。
  5. 手动启动特定实例的更新。这种方式可让系统立即更新这些实例。

您也可以组合使用这些参数来控制更新速度。

停止更新

目前没有明确的方法或命令可用于停止更新。您可以从主动更新变更为寻机更新;如果托管实例组未在使用自动扩缩程序等其他服务来调整大小,则变更为寻机更新可有效地停止更新。

如需从主动更新变更为寻机更新,请运行以下命令:

gcloud compute instance-groups managed rolling-action stop-proactive-update [INSTANCE_GROUP_NAME] \
    [--zone [ZONE] | --region [REGION]]

如果您要在从主动更新转为寻机更新之后彻底停止更新,您可以按照以下步骤操作:

  1. 发出请求以确定已经更新的实例数。

    gcloud compute instance-groups managed list-instances [INSTANCE_GROUP_NAME] \
        [--zone [ZONE] | --region [REGION]]

    gcloud 工具返回的响应会提供实例组中的实例列表以及各实例的当前状态:

    NAME               ZONE           STATUS   ACTION    INSTANCE_TEMPLATE  VERSION_NAME  LAST_ERROR
    vm-instances-9pk4  us-central1-f  RUNNING  NONE      my-new-template
    vm-instances-j1h8  us-central1-f  RUNNING  NONE      my-new-template
    vm-instances-ngod  us-central1-f  RUNNING  NONE      my-old-template
    

    在本示例中,有两个实例已更新。

  2. 接下来,发出请求以执行新的“更新”,但传入已经更新的实例数作为目标大小:

    gcloud compute instance-groups managed rolling-action start-update [INSTANCE_GROUP_NAME] \
        --version template=my-old-template \
        --canary-version template=my-new-template,target-size=2 \
        [--zone [ZONE] | --region [REGION]]

    对于该更新程序服务,这项更新将显示为“完成”,因此不会更新其他实例,从而有效地停止更新。

托管实例组的 versions 和 instanceTemplate 属性之间的关系

Google 建议使用 versions 字段来为托管实例组配置实例模板。

旧版 instanceTemplate 字段在功能上与 versions 有所重叠,因为这两个字段都可让您指定托管实例组将使用哪个实例模板来创建新实例。但是,只有 versions 字段可让您指定高级双模板 (Canary) 配置。

为了实现向后兼容性,托管实例组会继续支持设置顶级 instanceTemplate 字段,但我们建议您只使用 versions 字段。同时使用顶级 instanceTemplate 字段和 versions 字段可能会导致歧义和混淆。

如果您在调用 update()patch() 方法时同时指定 instanceTemplate 字段和 versions 字段,则可能会出现以下三种情况:

  • 您将这两个字段设置为相同值

    这是有效的请求。在这种情况下,该请求不会产生歧义,且新的实例模板会应用于托管实例组。

    例如,在以下请求中,顶级 instanceTemplateversions 字段会指定与当前现有模板不同的同一实例模板。系统将根据新的实例模板更新托管实例组:

    {
     "instanceTemplate": "global/instanceTemplates/new-template",
     "versions": [
      {
       "instanceTemplate": "global/instanceTemplates/new-template"
      }
     ],
     "updatePolicy": {
       "type": "PROACTIVE"
     }
    }
    
  • 您将这两个字段设置为不同的值,但其中只有一个值与托管实例组中的当前实例模板不同

    这是有效的请求。系统会将与当前设置不同的字段视为预期值。例如,您可以调用 get() 方法,再更改这两个字段中的一个字段,然后仅使用这个已更改的字段来调用 update()

    {
     "instanceTemplate": "global/instanceTemplates/current-template",
     "versions": [
      {
       "instanceTemplate": "global/instanceTemplates/new-template"
      }
     ],
     "updatePolicy": {
       "type": "PROACTIVE"
     }
    }
    
  • 您将这两个字段设置为不同的值,且这两个值都与托管实例组中的当前实例模板不同

    此设置无效并且将返回错误,因为意图不明确。

    {
     "instanceTemplate": "global/instanceTemplates/new-template",
     "versions": [
      {
       "instanceTemplate": "global/instanceTemplates/a-different-new-template"
      }
     ],
     "updatePolicy": {
       "type": "PROACTIVE"
     }
    }
    

versions 字段、instanceTemplate 字段和 get() 方法

如果您仅指定一个实例模板,无论是通过顶级 instanceTemplate 字段、versions 字段还是通过两者,则 get() 方法都会在其响应中返回这两个字段。这可使新的 versions 字段向后兼容。只要您在这两个字段的任何一个中指定一个实例模板,get()instanceTemplate 字段中返回的内容就不会改变。

如果您在 versions 字段中指定了两个实例模板,则 get() 方法将返回空的顶级 instanceTemplate 字段。目前无法在顶级 instanceTemplate 字段中明确表示双实例模板 (Canary) 配置,因此在 Canary 更新期间不使用该字段。

versions 字段和 setInstanceTemplate() 方法

为了向后兼容,setInstanceTemplate() 方法的行为会保持不变,让您能够更改托管实例组用于创建新实例的模板。在您调用此方法时,系统将使用 setInstanceTemplate() 方法指定的实例模板来替换 versions 字段。

此外,setInstanceTemplate() 方法还会将 updatePolicy 设置为 OPPORTUNISTIC。这样可防止托管实例组主动部署 versions 字段中未明确指定的实例模板。

后续步骤

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

发送以下问题的反馈:

此网页
Compute Engine 文档