亚马逊AWS官方博客

利用 Auto Scaling Group 生命周期功能实现有状态应用的管理

1. 场景说明

在很多情况下,尤其是在管理有状态应用的场景中,需要对Auto Scaling Group里的EC2在启动和停止时执行一些特定的操作,从而实现定制化的功能,满足业务上的需求。比如游戏服内部应用大量交叉互联并且交互依赖IP地址,实例恢复后希望保持IP地址不变,还有共享应用配置文件,不需要预先配置实例,以及采用分组分区的模式部署游戏服,希望每台机器部署的应用和承担的角色不一样。 还有很多的客户通过Consul来实现服务的注册和发现,希望在EC2 终止时执行Consul命令来注销实例资源等等。

本文档介绍的解决方案是通过利用Auto Scaling Group生命周期功能,判断外部状态信息,结合AWS Systems Manager登陆实例,执行特定的命令或脚本来实现对有状态应用的管理,满足上述业务上的需求。在本文档介绍的实验里,通过EC2 Auto Scaling 生命周期挂钩, Amazon EventBridge和Systems Manager(SSM) Automation,来实现在ASG里的EC2被terminate之前执行命令,生成一个测试文件并把文件压缩,然后上传到S3上。 客户可以根据自己的场景,来替换执行的命令或脚本,从而实现相关的业务需求。

2. 服务介绍

Amazon EventBridge 是一种无服务器事件总线服务,可以轻松地将应用程序与来自各种来源的数据相连接。您可以设置路由规则来确定发送数据的目的地,以便构建能够实时响应所有数据源的应用程序架构。利用 EventBridge,您可以构建事件驱动的体系结构,这些体系结构是松散耦合的和分布式的。EventBridge 以前的名称为 Amazon CloudWatch Events。现有的 CloudWatch Events 用户可以在新的 EventBridge 控制台和 CloudWatch Events 控制台中访问其现有的默认总线、规则和事件。EventBridge 使用相同的 CloudWatch Events API,因此您使用的所有现有的 CloudWatch Events API 都保持不变。

AWS Systems Manager让您能够查看和控制 AWS 上的基础设施。Systems Manager 可以提供一个统一的用户界面,供您查看多种 AWS 服务的运行数据,并在 AWS 资源上自动执行操作任务。Systems Manager(SSM) Automation简化了EC2实例和 其他 AWS 资源,能够构建自动化工作流以配置和管理实例和AWS 资源,例如重新启动一个或多个EC2 实例或创建EC2 AMI。

Amazon EC2 Auto Scaling 生命周期从 Auto Scaling 组启动实例并将其投入使用时开始,在实例终止时结束。生命周期挂钩能够在Auto Scaling 组启动或终止时执行自定义操作,当 Amazon EC2 Auto Scaling 响应横向扩展事件时,生命周期挂钩将新启动的实例从Pending状态设置为Pending:Wait状态,此时您可以在实例上安装或配置软件等,在完成生命周期操作后,实例将进入Pending:Proceed状态,当实例完全配置后,将会附加到Auto Scaling 组并且进入InService状态。同样在响应缩减事件时,生命周期挂钩将终止的实例从Terminating状态设置为Terminating:Wait状态,此时可以执行连接到实例并下载日志或其他数据等操作,在完成生命周期操作后,实例将进入Terminating:Proceed状态,最终进入Terminated状态。下图阐释了 Amazon EC2 Auto Scaling 生命周期内的实例状态之间的过渡。

3. 整体架构

当EC2 Auto Scaling将实例标记为终止时,生命周期挂钩将实例设置为“Terminating:Wait”状态,同时生成CloudWatch事件,Amazon EventBridge获取事件后, 触发SSM Automation来对被terminate的EC2执行命令,生成一个文件并把文件压缩,然后上传到S3上。整体架构如下:

4.方案实现

1.前提条件 – SSM配置,本方案要求EC2 Auto Scaling Group使用的EC2能够被AWS Systems Manager管理, 因而要求SSM代理被正确安装和配置。

  • 确保EC2 Auto Scaling Group使用的EC2 AMI安装SSM 代理, Amazon Linux和Amazon Linux 2默认情况下已经安装了SSM代理。可以通过ps -ef 命令去检查SSM代理是否运行。
  • 在IAM里创建一个policy, 拥有对目标S3 桶的写入(PutObject)权限
  • 创建一个IAM实例配置文件,拥有”AmazonSSMManagedInstanceCore” policy和上一步骤里创建的S3 写入的policy
  • 安全组允许HTTPS(端口443)出站流量

 

  • 在EC2 console界面里, 创建启动模版, 启动模版里配置上面的AMI, 实例配置文件和安全组。

 

  • 从上面的EC2启动模版里创建一个Auto Scaling Group

验证: 在AWS System Manager界面里, 选择托管实例, 可以成功地看到EC2 Auto Scaling Group里的所有EC2实例。

2. 给EC2 Auto Scaling Group创建一个Terminate的lifecycle Hook, 默认timeout是3600s,可以根据需求调整这个值

3. 在IAM里,创建一个SSM Automation的role

  • 选择创建role, trusted entity 选择AWS System Manager Service

  • 添加AmazonSSMAutomationRole policy,并完成SSM Automation Role的创建

  • 选择上一步创建好的role, 添加一个Inline policy, 附加iam:PassRole,resource选择新创建的SSM Automation的role
  • 最终创建的SSM Automation role包含2个policy,整体配置如下

4.创建SSM Automation 文档

进入AWS System Manager界面, 选择文档,然后选择创建自动化。在编辑器窗口, 粘贴下面的内容。

schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    default: ''
  InstanceId:
    type: String
mainSteps:
  - name: runCommand
    action: 'aws:runCommand'
    isCritical: true
    isEnd: true
    inputs:
      InstanceIds:
        - '{{InstanceId}}'
      DocumentName: AWS-RunShellScript
      Parameters:
        commands:
          - touch /tmp/testforSSMAutomation.txt
          - ec2InstanceId=$(ec2-metadata -i | cut -d " " -f 2)
          - tar -cvf /tmp/data-$ec2InstanceId.tar /tmp/testforSSMAutomation.txt
          - 'aws s3 cp /tmp/data-$ec2InstanceId.tar s3://shiyang-test6'

 

5. 在Amazon EventBridge里创建规则, 服务选择创建的Auto Scaling, Event选择EC2 instance-terminate Lifecycle Action。

6. 继续创建SSM Automation 目标, 选择Input Transformer, 配置如下:

之后选择 “Create a new role for this specific resource”.

到这里整体的方案就配置完了,接下来进入方案验证。

5.方案验证

  • 进入EC2 界面,选择创建的Auto Scaling组, 然后手动调小所需容量,从而引起缩容
  • EC2终止并进入“Terminating:Wait”状态

 

  • 登陆到“Terminating:Wait”状态的EC2, 确认SSM Automation文档里的2条命令被成功执行。
  • 登陆到S3 界面,确认生成的文件已经上传
  • 如果在生命周期挂钩设置的Timeout之前结束,使用complete-lifecycle-action命令或 CompleteLifecycleAction 完成操作, 让EC2 从“Terminating:Wait”状态,进入“Terminating:Proceed”状态,最终被Terminated。
aws autoscaling complete-lifecycle-action --lifecycle-hook-name asgNamexxx --auto-scaling-group-name asgname --lifecycle-action-result CONTINUE --instance-id i-xxx --region xxx

 

6. 方案总结

以上内容介绍了利用Systems Manager(SSM) Automation来实现在EC2被terminate之前执行命令或脚本,完成优雅退出的一个整体解决方案。该方案结合EC2 Auto Scaling 生命周期挂钩,Amazon EventBridge和Systems Manager(SSM) Automation服务,来完成对EC2终止前的相关操作,并把log压缩上传到Amazon S3服务。客户可以根据自己的场景,来替换执行的命令或脚本,从而实现相关的业务需求。

 

本篇作者

朱士洋

AWS技术客户经理,负责企业级客户的架构和成本优化、技术支持等工作,致力于AdTech等行业,曾供职于IBM,拥有15+年的产品设计、开发/测试、技术支持经验