AWS CodeDeploy
用户指南 (API 版本 2014-10-06)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

本指南中的过程支持新的控制台设计。如果您选择使用较旧版本的控制台,可以在本指南中找到许多仍然适用的概念和基本过程。要访问新控制台中的帮助,请选择信息图标。

排查 Amazon EC2 Auto Scaling 问题

一般 Amazon EC2 Auto Scaling 排查

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

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

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

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

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

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

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

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

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

在部署修订之前,Amazon EC2 Auto Scaling 组中的实例不断被预置和终止

在某些情况下,一个错误可能导致无法在 Amazon EC2 Auto Scaling 组中成功部署新预置的实例。结果是没有运行正常的实例,部署失败。由于无法运行部署或无法成功完成部署,实例在创建之后很快即被终止。Amazon EC2 Auto Scaling 组配置将预置另一组实例,试图达到正常运行的主机数的最低要求。这批实例也会被终止,并不断进行这一循环。

可能的原因包括:

  • Amazon EC2 Auto Scaling 组运行状况检查失败

  • 应用程序修订中有错误

要解决这一问题,请遵循以下步骤:

  1. 手动创建一个 Amazon EC2 实例,该实例不在 Amazon EC2 Auto Scaling 组中。用唯一的 EC2 实例标签标记该实例。

  2. 将这个新实例添加到受影响的部署组。

  3. 将没有错误的新应用程序修订部署到部署组。

这会提示 Amazon EC2 Auto Scaling 组将此应用程序修订部署到 Amazon EC2 Auto Scaling 组中将来的实例。

注意

确认部署成功后,您可以删除所创建的实例,避免继续产生相应费用。

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

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

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

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

解决此问题:

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

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

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

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

这是因为,如果 Amazon EC2 Auto Scaling 向上扩展一个具有与多个部署组关联的钩子的实例,它将一次性为所有钩子发送通知。这会导致针对每个实例的多个部署同时开始。当多个部署同时向 CodeDeploy 代理发送命令时,可能会达到生命周期事件与部署开始或前一个生命周期事件结束之间的五分钟超时值。如果发生这种情况,即使部署过程按预期运行,部署也会失败。

注意

生命周期事件中脚本的默认超时时间为 30 分钟。您可以在AppSpec file中将超时时间更改为其他值。有关更多信息,请参阅 为 EC2/本地部署添加 AppSpec 文件

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

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

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

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

Amazon EC2 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 限制

  • CodeDeploy 中的一个应用程序已在其关联的部署组更新或删除之前被删除。

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

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

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

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

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

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

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

不匹配的 Amazon EC2 Auto Scaling 生命周期挂钩可能导致至 Amazon EC2 Auto Scaling 组的自动部署停止或失败

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

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

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

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

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

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

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

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

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

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

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

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

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

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