首页/Amazon AWS/如何实现对集群任务最小影响的 ECS 容器实例自动化终止方案
Amazon AWS

如何实现对集群任务最小影响的 ECS 容器实例自动化终止方案

问题背景

Amazon ECS 是一种容器管理服务,可以很方便地运行、停止和管理群集上的 Docker 容器。当使用 ECS 运行容器任务时,会将它们放置在 ECS 群集上。Amazon ECS 从指定的映像存储库中,下载指定的容器映像,并在集群中的容器实例上运行这些映像所承载的任务。

我的同事 Chris Barclay 发了一篇很不错的博客文章,介绍了在 Auto Scaling 组缩小 ECS 集群之前,使用容器实例耗尽的方法,自动化地删除正在进行的容器实例。

根据多个实际的客户案例,需要从 Amazon ECS 群集中终止实例的应用场景很多且重要, 例如: EC2 AMI 的升级和更新,执行系统关键升级补丁,系统核心组库的更新,Docker 软件版本的升级和更新,ECS 代理的版本升级和更新,集群大小的变更等等。

解决方案

通常而言,这些应用场景,都有一个共同的目标就是当容器实例的终止时,或从集群中删除容器实例时,不会影响集群中正在进行的任务,也就是说,阻止将新任务安排在处于 DRAINING 状态的容器实例上,如果资源可用(或预先起动新的容器实例),则新任务分配到 ECS 集群中的其他容器实例,待终止的容器实例上正在运行的任务,等其成功迁移到其他容器实例后,终止实例。实战中,亦可手动修改容器实例的状态为 DRAINING。本文中,我们将展示如何实现对集群任务最小影响的 ECS 容器实例自动化终止方案,其中会需要使用Auto Scaling组的生命周期挂钩以及 Amazon Lambda 提供的无服务函数调用,如下图所示:

1-6

Auto Scaling 组支持可调用的生命周期挂钩,例如:Lambda 函数,以允许其在实例启动或终止之前完成,此例为实例终止之前。生命周期挂钩调用的 Lambda 函数完成以下两个任务:

  1. 将 ECS 容器实例状态设置为 DRAINING。
  2. 检查容器实例上是否存在任何正在进行的任务。 如有则会向 SNS 发布消息,再次调用该 Lambda 函数进行检查。

该 Lambda 函数会重复执行第2步,直到容器实例上没有任何正在运行的任务,或者生命周期挂钩心跳超时,以先发生者为准。 之后,控制权返回到 Auto Scaling 生命周期挂钩,终止容器实例。

参考示例

要实现上述自动化容器实例终止方案,可参考开源的 CloudFormation 模板,以及 S3 存储桶中上传 Lambda 部署软件包,设置本文中描述的资源。该模板创建以下资源:

  • VPC 和关联的网络元素(子网,安全组,路由表等)
  • ECS 群集,ECS 服务和示例 ECS 任务定义
  • 具有两个 EC2 实例和包含生命周期终止挂钩的 Auto Scaling 组
  • Lambda 函数
  • SNS 话题
  • 能执行 Lambda 函数的 IAM 角色

鉴于中国区有关 Auto Scaling 组的可信任实体和全球的命名方式有所区别,因此可参考这里的修改方法,对 CloudFormation 模板进行配置和更改。

创建 CloudFormation 堆栈,我们可以通过触发实例终止事件,来了解这是如何工作的:

  • 在 Amazon EC2 控制台中 ,选择 Auto Scaling Groups 并选择由 CloudFormation 创建的 Auto Scaling 组的名称。
  • 选择操作 , 编辑并更新服务,将实例的数量减少1个。

这将触发一个实例的终止过程。选择 Auto Scaling 组实例选项卡:实例状态值应显示生命周期状态:

2-4

此时,生命周期挂钩被激活并向 SNS 发布消息,最终触发 Lambda 函数的响应和执行。之后, Lambda 函数将 ECS 容器实例状态更改为 DRAINING。ECS 服务介入调度,停止实例上的任务并在可用实例上启动该任务。

3-5

任务完成后,Auto Scaling 组活动历史记录确认 EC2 实例已终止。

4-4

 

深入分析

我们来深入分析一下 Lambda 函数内部的工作原理。该函数首先检查,收到的事件中的 LifecycleTransition 值是否为 EC2_INSTANCE_TERMINATING,表示当前已经进入生命周期挂钩的终止状态之前。

 # If the event received is instance terminating...
if 'LifecycleTransition' in message.keys():
    print("message autoscaling {}".format(message['LifecycleTransition']))
if message['LifecycleTransition'].find('autoscaling:EC2_INSTANCE_TERMINATING') > -1:

继续调用函数 “checkContainerInstanceTaskStatus”。该函数根据容器实例的 ID,将容器实例状态设置为 ‘DRAINING’。

# Get lifecycle hook name
lifecycleHookName = message['LifecycleHookName']
print("Setting lifecycle hook name {} ".format(lifecycleHookName))

# Check if there are any tasks running on the instance
tasksRunning = checkContainerInstanceTaskStatus(Ec2InstanceId)

然后,检查实例上是否有任务正在运行。如有任务正在运行,则向 SNS 发布消息以再次触发 Lambda 函数后退出。

# Use Task ARNs to get describe tasks
descTaskResp = ecsClient.describe_tasks(cluster=clusterName, tasks=listTaskResp['taskArns'])
for key in descTaskResp['tasks']:
 print("Task status {}".format(key['lastStatus']))
 print("Container instance ARN {}".format(key['containerInstanceArn']))
 print("Task ARN {}".format(key['taskArn']))

# Check if any tasks are running
if len(descTaskResp['tasks']) > 0:
 print("Tasks are still running..")
 return 1
else:
 print("NO tasks are on this instance {}..".format(Ec2InstanceId))
 return 0

继续执行的 Lambda 函数,发现容器实例上没有运行的任务时,则继续完成生命周期挂钩并终止 EC2 实例。

#Complete lifecycle hook.
try:
 response = asgClient.complete_lifecycle_action(
 LifecycleHookName=lifecycleHookName,
 AutoScalingGroupName=asgGroupName,
 LifecycleActionResult='CONTINUE',
 InstanceId=Ec2InstanceId)
 print("Response = {}".format(response))
 print("Completedlifecycle hook action")
except Exception, e:
 print(str(e)) 

结论

本文讨论了 ECS 容器实例终止的多种应用场景,提供了对集群任务最小影响的 ECS 容器实例自动化终止方案,并通过参考示例展示和深入分析了其工作原理。基于参考示例,可以使用 CloudFormation,Lambda 等服务,实现真正的滚动部署 ,先启动新实例并批量终止实例,同时保证对现有的集群任务带来最小影响。要了解有关容器实例耗尽的更多信息,请参阅 Amazon ECS 开发人员指南 。

SERVICE

相关服务与公开报价

以下为三家云市场官方店铺的在售商品,价格取自平台页面、可核验。 点击直达商品页,由平台完成下单与交付。

按本文主题推荐的云市场在售服务与公开报价
商品图 服务 / 商品 云市场 公开报价 操作
Rapidssl 单域名 通配符SSL证书安装配置服务 Rapidssl 单域名 通配符SSL证书安装配置服务 阿里云 ¥600 去商品页
网站博彩挂马清理 ASP-PHP程序问题 网站被黑挂马清理 数据库恢复 网站博彩挂马清理 ASP-PHP程序问题 网站被黑挂马清理 数据库恢复 阿里云 ¥2000 去商品页
SSL证书申请续费安装 https配置通配符防劫持 多域名ssl证书 SSL证书申请续费安装 https配置通配符防劫持 多域名ssl证书 阿里云 ¥100 去商品页
Drupal建站系统(附高级运维支持) Drupal建站系统(附高级运维支持) 腾讯云 ¥0 / 小时 去商品页
企业建站系统 Wordpress 2024-4-18更新 企业建站系统 Wordpress 2024-4-18更新 腾讯云 ¥0 / 小时 去商品页
网站小程序SSL证书购买配置服务 网站小程序SSL证书购买配置服务 腾讯云 ¥100 / 次 去商品页
企业网站运维技术支持服务(年度订阅) 企业网站运维技术支持服务(年度订阅) 华为云 ¥6000 / 年 去商品页
国密 SM2 证书安装服务 国密 SM2 证书安装服务 华为云 ¥300 / 次 去商品页
BT 宝塔 Linux 面板安装服务 BT 宝塔 Linux 面板安装服务 华为云 ¥100 / 次 去商品页
FREE CHECKUP

先做一次免费服务器体检

我们会在 1 个工作日内给出问题清单与处置建议 —— 做不做代维都没关系。

135 410 16684
工作日 Mon – Fri 10:00 – 22:00 · 紧急故障 7×24 响应
立即拨打
CONTACT

在线留言

有什么可以帮您?

带 * 为必填