amazon-web-services - 在 Beanstalk 部署或 ECS 任务不使用时计划停止/启动 EC2 实例?
问题描述
我有一个包含 Python 代码和第三方二进制可执行文件的 Docker 映像。只有出站网络请求。图像必须每小时运行一次,每次执行持续约 3 分钟。
我可以:
- 使用 EC2 实例并通过 cron 计划每小时执行一次
- 创建 CloudWatch 事件/规则以每小时运行一次 ECS 任务定义
- 设置 Elastic Beanstalk 环境并安排映像的每小时部署
在所有这些场景中,EC2 实例都在 24/7 运行,并且我需要为长时间不使用付费。
如何在完成我的 docker 映像后完成每小时安排现有 EC2 实例的启动和所述实例的停止?
解决方案
这是我能想到的一种方法。它非常高级,省略了一些细节,但从概念上讲它可以正常工作。您还需要考虑使用的身份和访问管理 (IAM) 角色:
- 触发 Step Function 的 CloudWatch 事件规则
- 用于触发 Lambda 函数的 AWS Step Function
- 用于启动 EC2 实例的 AWS Lambda 函数
EC2 实例轮询 Step Functions 服务以获取活动任务
- 使用 cron 表达式创建 CloudWatch 事件规则以安排定期任务
- CloudWatch 事件规则的目标是 AWS Step Function
- AWS Step Function 状态机首先触发一个 AWS Lambda 函数,该函数启动 EC2 实例
- Step Functions 状态机中的下一步调用一个 Activity Task,表示需要执行的 Docker 容器
- EC2 实例上运行了一个脚本,该脚本轮询 Activity Task 的工作
- EC2 实例执行 Docker 容器,等待它完成,并向 Step Functions Activity Task 发送完成消息
- EC2 实例上运行的脚本自行关闭
- AWS Step Function 结束
请记住,一个可能更好的选择是每小时启动一个新的 EC2 实例,而不是简单地启动和停止同一个实例。尽管通过启动现有实例与启动新实例相比,您可能会获得更好的启动性能,但您还必须花时间像宠物一样维护 EC2 实例:修复出现的问题,或定期修补操作系统。在当今世界,基础设施应该是一次性的,这是一种普遍接受的做法。毕竟,您已经将应用程序打包到 Docker 容器中,因此您很可能对容器实际在哪个主机上执行没有过于具体的期望。
另一种选择是使用 AWS Fargate,它旨在运行 Docker 容器,而无需担心启动和管理容器基础设施。