如何通过Lambda函数检测EC2 Spot实例中断通知
解决EC2 Spot实例中断通知的外部检测方案
首先明确:EC2 Spot实例的中断通知元数据只能从实例内部访问,外部服务(比如Lambda)没法直接查询到,所以得换思路,下面是几种生产环境常用的实践方案:
方案1:用AWS EventBridge原生事件(最简便)
AWS会在Spot实例被中断前2分钟,主动发送EC2 Spot Instance Interruption Warning事件到EventBridge,完全不需要在实例内做任何检测逻辑,直接用这个事件触发Lambda扩容按需实例:
- 打开EventBridge控制台,新建规则,事件源选「AWS事件或EventBridge合作伙伴事件」
- 事件模式配置:选择「EC2」服务,事件类型选「EC2 Spot Instance Interruption Warning」
- 目标选择你的Lambda函数,Lambda可以从事件 payload 里拿到即将中断的实例ID,然后调用Auto Scaling API(
update_auto_scaling_group)调整按需ASG的期望容量,补上即将丢失的算力。 - 这个方案是AWS官方推荐的,可靠性最高,不需要维护实例内的检测脚本。
方案2:实例内主动推送中断通知到外部
如果因为某些原因没法用EventBridge,可以在Spot实例内部定时检测元数据,发现中断通知后主动触发Lambda:
- 在实例内写个简单的脚本,定时调用元数据接口:
如果返回非空的JSON(比如curl -s http://169.254.169.254/latest/meta-data/spot/instance-action{"action": "terminate", "time": "2024-05-20T12:00:00Z"}),就说明即将被中断,此时调用Lambda的API或者发送消息到SQS/SNS,触发扩容逻辑。 - 可以用cron定时任务、systemd服务或者CloudWatch Agent来定期执行这个脚本。
方案3:CloudWatch告警辅助(备选)
如果以上两种都不适用,可以监控Spot实例的状态变化,比如当实例状态变为terminating:instance-terminated-by-spot-instance-termination时触发告警,但这种方式的通知时间会比前两种晚,不如提前2分钟的中断通知及时,只适合作为兜底方案。
总结:优先用方案1,完全原生集成,零维护成本;如果有特殊需求再考虑方案2,方案3作为备选。
内容的提问来源于stack exchange,提问作者Alexandre_Bon
相关产品推荐
相关产品推荐

