如何延迟 Auto Scaling 终止不正常 Amazon EC2 实例的过程,以便对实例进行问题排查?

上次更新时间:2020 年 11 月 18 日

我的 Amazon Elastic Compute Cloud (Amazon EC2) 实例被标记为运行状况不佳,并移至“Auto Scaling Terminating (Auto Scaling 终止)”状态。在此之后,我的 Amazon EC2 实例必须先终止我才能确定问题的原因。我应该如何排查此问题?

简短描述

向 AWS Auto Scaling 组添加生命周期挂钩,从而将实例从 Terminating (正在终止) 状态转变为 Terminating:Wait(正在终止:等待)状态。在此状态下,您可以在实例终止之前访问它们,然后排查它们被标记为运行状况不佳的原因。

默认情况下,实例将保持 Terminating:Wait(正在终止:等待)状态 3600 秒(1 小时)。要增加此时间,可在 put-lifecycle-hook API 调用中使用 heartbeat-timeout 参数。您可以将实例保持在 Terminating:Wait(正在终止:等待)状态的最长时间是 48 小时或检测信号超时的 100 倍(以较小者为准)。

解决方法

注意:如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请确保您正在运行最新版本的 AWS CLI

使用 AWS CLI,通过以下步骤配置生命周期挂钩。然后,创建必要的 Amazon Simple Notification Service (Amazon SNS) 主题和 AWS Identity and Access Management (IAM) 权限。

或者,您也可以使用 AWS 管理控制台配置生命周期挂钩。然后,请参阅以下内容以在控制台中管理 Amazon SNS 主题和 IAM 权限:

创建 Amazon SNS 主题

1.    创建 AWS Auto Scaling 可发送生命周期通知的主题。以下示例调用 create-topic 命令创建 ASNotifications 主题:

$ aws sns create-topic --name ASNotifications

返回的是类似以下内容的 Amazon 资源名称 (ARN):

"TopicArn": "arn:aws:sns:us-west-2:123456789012:ASNotifications"

2.    创建主题订阅。您必须拥有接收延长待处理状态检测信号超时或完成生命周期操作必需的 LifecycleActionToken 的订阅。以下示例使用 subscribe 命令创建使用电子邮件协议 (SMTP) 及终端节点电子邮件地址 user@amazon.com 的订阅。

$ aws sns subscribe --topic-arn arn:aws:sns:us-west-2:123456789012:ASNotifications --protocol email --notification-endpoint user@amazon.com

配置 IAM 权限

IAM 权限通过创建 IAM 角色进行配置;IAM 角色授予 AWS Auto Scaling 服务向 SNS 主题发送内容的权限。要完成此任务,请创建一个包含相应策略的文本文件。然后,在 create-role 命令中引用该文件。

1.    使用文本编辑器(如 vi)创建该文本文件:

$ sudo vi assume-role.txt

2.    将以下内容粘贴到文本文件中,然后保存该文件。

{
  "Version": "2012-10-17",
  "Statement": [{
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "autoscaling.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

3.    使用 aws iam create-role 命令从保存到 assume-role.txt 的策略创建 IAM 角色 AS-Lifecycle-Hook-Role

$ aws iam create-role --role-name AS-Lifecycle-Hook-Role --assume-role-policy-document file://assume-role.txt

输出包含角色 ARN。确保保存 IAM 角色ARNSNS 主题

4.    向角色添加权限,以允许 AWS Auto Scaling 在发生生命周期挂钩事件时发送 SNS 通知。以下示例使用 attach-role-policy 命令将托管策略 AutoScalingNotificationAccessRole 附加到 IAM 角色 AS-Lifecycle-Hook-Role

$ aws iam attach-role-policy --role-name AS-Lifecycle-Hook-Role --policy-arn arn:aws:iam::aws:policy/service-role/AutoScalingNotificationAccessRole

此托管策略授予以下权限:

{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "sqs:SendMessage",
        "sqs:GetQueueUrl",
        "sns:Publish"
      ]
    }
  ]
}

重要提示:AWS 托管策略 AutoScalingNotificationAccessRole 允许 AWS Auto Scaling 服务调用所有 SNS 主题和队列。要将 AWS Auto Scaling 限制为仅访问特定 SNS 主题或队列,请使用以下示例策略。

{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Resource": "arn:aws:sns:us-west-2:123456789012:ASNotifications",
       "Action": [
         "sqs:SendMessage",
         "sqs:GetQueueUrl",
         "sns:Publish"
       ]
     }
   ]
}

配置生命周期挂钩

接下来,使用 put-lifecycle-hook 命令配置生命周期挂钩:

aws autoscaling put-lifecycle-hook --lifecycle-hook-name AStroublshoot --auto-scaling-group-name MyASGroup
        --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING
        --notification-target-arn arn:aws:sns:us-west-2:123456789012:ASNotifications
        --role-arn arn:aws:iam::123456789012:role/AS-Lifecycle-Hook-Role 

运行此命令之前,请务必替换您自己的 AWS Auto Scaling 组名称、SNS 目标 ARN 和 IAM 角色 ARN。

此命令:

  • 命名生命周期挂钩 (AStroubleshoot)
  • 标识与生命周期挂钩关联的 AWS Auto Scaling 组 (MyASGroup)
  • 配置实例终止生命周期阶段的挂钩 (EC2_INSTANCE_TERMINATING)
  • 指定 SNS 主题的 ARN (arn:aws:sns:us-west-2:123456789012:ASNotifications)
  • 指定 IAM 角色的 ARN (arn:aws:iam::123456789012:role/AS-Lifecycle-Hook-Role)

测试生命周期挂钩

要测试生命周期挂钩,请选择一个实例,然后使用 terminate-instance-in-auto-scaling group 终止此实例。这可强制 AWS Auto Scaling 终止实例,类似于实例状况不佳时。实例进入 Terminating:Wait(正在终止:等待)状态后,您可以使用 record-lifecycle-action-heartbeat 将实例保持在此状态。或者,使用 complete-lifecycle-action 允许终止完成。

aws autoscaling complete-lifecycle-action --lifecycle-hook-name my-lifecycle-hook
        --auto-scaling-group-name MyASGroup --lifecycle-action-result CONTINUE
        --instance-id i-0e7380909ffaab747

这篇文章对您有帮助吗?


您是否需要账单或技术支持?