AWS CodeDeploy
User Guide (API Version 2014-10-06)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。点 击 Getting Started with Amazon AWS to see specific differences applicable to the China (Beijing) Region.

解决 Auto Scaling 问题

一般 Auto Scaling 问题排查

针对 Auto Scaling 组中的 Amazon EC2 实例的部署可能因以下原因而失败:

  • Auto Scaling 持续启动和终止 Amazon EC2 实例。如果 AWS CodeDeploy 无法自动部署应用程序修订,Auto Scaling 将持续启动和终止 Amazon EC2 实例。

    解除 Auto Scaling 组与 AWS CodeDeploy 部署组的关联或更改 Auto Scaling 组的配置,使所需的实例数量与当前实例数量匹配(从而防止 Auto Scaling 启动更多的 Amazon EC2 实例)。有关更多信息,请参阅更改部署组设置配置您的 Auto Scaling 组

  • AWS CodeDeploy 代理没有响应。如果 Amazon EC2 实例启动或开始后立即运行的初始化脚本(例如,cloud-init 脚本)需要 1 个小时以上的时间才能运行,则 AWS CodeDeploy 代理可能无法安装。AWS CodeDeploy 具有 1 个小时的超时时间,以便 AWS CodeDeploy 代理响应挂起的部署。要解决此问题,请将您的初始化脚本移至 AWS CodeDeploy 应用程序修订中。

  • Auto Scaling 组中的 Amazon EC2 实例在部署期间将重启。如果 Amazon EC2 实例在部署期间重启或 AWS CodeDeploy 代理在处理部署命令时关闭,您的部署可能会失败。有关更多信息,请参阅 终止或重启 Auto Scaling 实例可能会导致部署失败

  • 同时向一个 Auto Scaling 组中的相同 Amazon EC2 实例部署多个应用程序修订。同时向一个 Auto Scaling 组中的相同 Amazon EC2 实例部署多个应用程序修订可能会失败(如果其中某个具有运行几分钟以上的脚本)。请不要向一个 Auto Scaling 组中的相同 Amazon EC2 实例部署多个应用程序修订。

  • 对于作为 Auto Scaling 组的一部分启动的新 Amazon EC2 实例,部署将失败。通常,在这种情况下,在部署中运行脚本可能会阻止 Auto Scaling 组中的 Amazon EC2 实例启动。(Auto Scaling 组中的其他 Amazon EC2 实例可能看起来运行正常。)要解决此问题,请确保先完成所有其他脚本:

    • 您的 AMI 中不包括 AWS CodeDeploy 代理:如果您在启动新实例时使用 cfn-init 命令安装 AWS CodeDeploy 代理,请将代理安装脚本置于 AWS CloudFormation 模板的 cfn-init 部分的末尾。

    • 您的 AMI 中包括 AWS CodeDeploy 代理:如果您在 AMI 中包括 AWS CodeDeploy 代理,请配置该代理以使其在创建实例时处于 Stopped 状态,然后在 cfn-init 脚本库中包括一个将启动代理作为最后一步的脚本。

终止或重启 Auto Scaling 实例可能会导致部署失败

如果通过 Auto Scaling 启动 Amazon EC2 实例,然后终止或重启该实例,则针对该实例的部署可能会因以下原因而失败:

  • 在部署正在进行中时,缩小事件或任何其他终止事件将导致实例与 Auto Scaling 组分离并终止。由于无法完成部署,因此它将失败。

  • 实例已重启,但需要 5 分钟以上的时间才能启动。AWS CodeDeploy 将此情况视为超时。该服务将使针对该实例的所有当前和将来部署失败。

解决此问题:

  • 一般来说,请确保实例终止或重启之前完成所有部署。确保所有部署在实例启动或重启后开始。

  • 如果您为 Auto Scaling 配置指定 Windows Server 基础 Amazon 系统映像 (AMI),并使用 EC2Config 服务设置实例的计算机名称,此行为可能导致部署失败。要禁用此行为,请在 Windows Server 基础 AMI 中,在 Ec2 Service Properties 对话框的 General 选项卡上,清除 Set Computer Name 框。清除此框后,将对使用该 Windows Server 基础 AMI 启动的所有新的 Windows Server Auto Scaling 实例禁用此行为。对于已启用此行为的 Windows Server Auto Scaling 实例,无需清除此框。仅在重启实例后对其重新部署失败的部署。

避免将多个部署组与一个 Auto Scaling 组关联

作为最佳实践,您应仅为每个 Auto Scaling 组关联一个部署组。

这是因为,如果 Auto Scaling 向上扩展一个具有与多个部署组关联的钩子的实例,它会一次性为所有钩子发送通知。这会导致针对每个实例的多个部署同时开始。当多个部署同时将命令发送到 AWS CodeDeploy 代理时,可能会超出 AWS CodeDeploy 超时逻辑中的 5 分钟限制。(如果一个部署的步骤未在 5 分钟内完成,即使部署过程按预期运行,AWS CodeDeploy 逻辑也会将该部署视为失败的部署。)

如果尝试同时运行多个部署,则无法控制部署发生的顺序。

最后,如果针对任一实例的部署失败,Auto Scaling 将立即终止该实例。当第一个实例关闭时,正在运行的其他部署将开始失败。由于 AWS CodeDeploy 具有 1 小时的超时以便 AWS CodeDeploy 代理响应挂起的部署,则每个实例的最大超时时间为 60 分钟。

有关尝试同时对一个实例进行多个部署时可能遇到的问题的更多信息,请参阅避免对同一 Amazon EC2 实例进行并行部署

有关 Auto Scaling 的更多信息,请参阅深入剖析:AWS CodeDeploy 和 Auto Scaling 集成

Auto Scaling 组中的 Amazon EC2 实例无法启动,收到错误“Heartbeat Timeout”

Auto Scaling 组可能无法启动新的 Amazon EC2 实例,并生成与以下内容类似的消息:

Launching a new Amazon EC2 instance <instance-Id>. Status Reason: Instance failed to complete user's Lifecycle Action: Lifecycle Action with token<token-Id> was abandoned: Heartbeat Timeout

此消息通常指示 AWS CodeDeploy 中的应用程序已在其关联的部署组更新或删除之前被删除。

当您删除某个应用程序或部署组时,AWS CodeDeploy 会尝试清除与其关联的任何 Auto Scaling 钩子,但某些钩子可能会保留。如果您运行命令来删除部署组,则剩余的钩子将在输出中返回;但如果您运行命令来删除应用程序,则剩余的钩子将不会在输出中显示。

因此,作为最佳实践,在删除某个应用程序之前,您应删除与该应用程序关联的所有部署组。您可以使用命令输出来标识必须手动删除的生命周期钩子。

如果您收到了“Heartbeat Timeout”错误消息,则可通过执行以下操作来确定剩余的生命周期钩子是否为导致出现错误的原因并解决问题:

  1. 运行 update-deployment-group 命令或 delete-deployment-group 命令。检查调用的输出。如果输出包含 hooksNotCleanedUp 结构和一个 Auto Scaling 生命周期钩子的列表,则剩余的生命周期钩子很有可能是导致错误的原因。

  2. 调用 describe-lifecycle-hooks 命令,并指定与无法启动的 Amazon EC2 实例关联的 Auto Scaling 组的名称。在输出中,查找与您在步骤 1 中标识的 hooksNotCleanedUp 结构对应的任何 Auto Scaling 生命周期钩子名称。或者,查找包含部署组名称的 Auto Scaling 生命周期钩子名称。

  3. 对每个 Auto Scaling 生命周期钩子调用 delete-lifecycle-hook 命令。指定 Auto Scaling 组和生命周期钩子。

如果您删除(从 Auto Scaling 组中)由 AWS CodeDeploy 创建的所有 Auto Scaling 生命周期钩子,则 AWS CodeDeploy 将不再针对作为 Auto Scaling 组的一部分向上扩展的 Amazon EC2 实例进行部署。

不匹配的 Auto Scaling 生命周期钩子可能导致针对 Auto Scaling 组的自动部署停止或失败

Auto Scaling 和 AWS CodeDeploy 使用生命周期钩子确定应将哪些应用程序修订部署到哪些已在 Auto Scaling 组中启动的 Amazon EC2 实例。如果 Auto Scaling 和 AWS CodeDeploy 中的生命周期钩子及其相关信息未准确匹配,则自动部署可能会停止或失败。

如果针对某个 Auto Scaling 组的部署失败,请检查 Auto Scaling 和 AWS CodeDeploy 中的生命周期钩子名称是否匹配。如果不匹配,请使用这些 AWS CLI 命令调用。

首先,获取 Auto Scaling 组和部署组的生命周期钩子名称的列表:

  1. 调用 describe-lifecycle-hooks 命令,并在 AWS CodeDeploy 中指定与部署组关联的 Auto Scaling 组的名称。在输出中,在 LifecycleHooks 列表中,记下每个 LifecycleHookName 值。

  2. 调用 get-deployment-group 命令,并指定与 Auto Scaling 组关联的部署组的名称。在输出中,在 autoScalingGroups 列表中,查找名称值与 Auto Scaling 组名称匹配的每个项目,然后记下相应的 hook 值。

现在比较两组生命周期钩子的名称。如果它们完全匹配(字符对字符),则它不是问题。您可能需要尝试本部分中的其他位置描述的其他 Auto Scaling 问题排查步骤。

但是,如果两组生命周期钩子的名称未完全匹配(字符对字符),请执行以下操作:

  1. 如果 describe-lifecycle-hooks 命令输出中包含 get-deployment-group 命令输出中未包含的生命周期钩子名称,则执行以下操作:

    1. 对于 describe-lifecycle-hooks 命令输出中的每个生命周期钩子名称,请调用 delete-lifecycle-hook 命令。

    2. 调用 update-deployment-group 命令,并指定原始 Auto Scaling 组的名称。AWS CodeDeploy 将在 Auto Scaling 组中创建新的替代生命周期钩子,并将这些生命周期钩子与部署组关联。现在,自动部署应恢复,因为新的实例已添加到 Auto Scaling 组。

  2. 如果 get-deployment-group 命令输出中包含 describe-lifecycle-hooks 命令输出中未包含的生命周期钩子名称,则执行以下操作:

    1. 调用 update-deployment-group 命令,但不指定原始 Auto Scaling 组的名称。

    2. 再次调用 update-deployment-group 命令,但这次指定原始 Auto Scaling 组的名称。AWS CodeDeploy 将在 Auto Scaling 组中重新创建缺失的生命周期钩子。现在,自动部署应恢复,因为新的实例已添加到 Auto Scaling 组。

在您将两组生命周期钩子名称完全匹配后(字符对字符),应用程序修订应重新部署,但仅重新部署到新的实例,因为它们已被添加到 Auto Scaling 组。将不会自动针对 Auto Scaling 组中已包含的实例进行部署。