添加AWS CDK生命周期挂钩后EC2实例每小时异常终止求助
问题原因分析
你的问题核心在于INSTANCE_LAUNCHING生命周期挂钩的默认行为:
- AWS ASG的生命周期挂钩默认超时时间为3600秒(1小时),默认的
default_result是ABANDON。 - 当实例进入INSTANCE_LAUNCHING挂钩状态后,如果在超时时间内没有收到
CompleteLifecycleAction的继续信号,ASG会执行默认的ABANDON操作,将实例标记为启动失败并终止;随后因为实际容量低于期望容量,触发扩容启动新实例,形成每小时一次的循环。
解决方案
针对这个问题,有两种处理方式:
方式1:直接设置超时后继续实例启动流程
如果你不需要在实例启动时执行额外自定义操作,仅需通知,可修改挂钩配置,将default_result设为CONTINUE,这样即使超时,ASG也会完成实例启动流程,不会终止实例。
修正后的CDK代码:
topic = sns.Topic(my_stack, "fleet_changes") topic_hook = autoscaling_hooktargets.TopicHook(topic) asg.add_lifecycle_hook( 'instance-terminating-hook', lifecycle_transition=autoscaling.LifecycleTransition.INSTANCE_TERMINATING, lifecycle_hook_name="instance-terminating", notification_target=topic_hook, notification_metadata="INFO: An instance has been terminated" ) asg.add_lifecycle_hook( 'instance-launching-hook', lifecycle_transition=autoscaling.LifecycleTransition.INSTANCE_LAUNCHING, lifecycle_hook_name="instance-launching", notification_target=topic_hook, notification_metadata="INFO: A new instance has been launched", # 设置超时后继续启动流程 default_result=autoscaling.DefaultResult.CONTINUE, # 可选:调整超时时间,比如设置为10分钟 heartbeat_timeout=600 )
方式2:添加自定义处理逻辑并主动发送继续信号
如果需要在实例启动时执行自定义操作(比如初始化配置),需在通知处理流程中,调用AWS SDK的CompleteLifecycleAction接口,在超时前告知ASG继续实例启动流程。例如:
- 订阅SNS主题的Lambda函数,收到启动通知后执行自定义逻辑,然后调用
autoscaling_client.complete_lifecycle_action()方法,传入对应的Lifecycle Hook名称、ASG名称、实例ID和ActionResult='CONTINUE'。
验证步骤
修改配置后,等待一小时观察实例状态,确认不再出现自动终止和扩容的循环,同时检查ALB日志是否还有“启动失败被移出服务”的记录。
内容的提问来源于stack exchange,提问作者user1319182
相关产品推荐
相关产品推荐

