为何我的Docker镜像在AWS ECS(Fargate)中作为任务运行时报错退出
故障原因分析与解决方案
你日志中输出的signal SIGTERM明确说明进程是被外部系统主动终止,而非应用内部代码崩溃,终止信号的来源是AWS ECS/Fargate控制平面,常见触发原因和对应解决方案如下:
负载均衡健康检查失败(最高概率)
如果你的ECS服务关联了应用负载均衡(ALB),会出现以下触发场景:
ALB配置的健康检查规则连续多次检测失败后,会判定任务不健康,通知ECS终止该任务,同时发送SIGTERM信号给容器进程
排查方向:- 确认ALB健康检查的端口是否和容器暴露的
8080一致,健康检查路径是否是应用能正常返回200状态码的路径 - 确认ECS任务关联的安全组已放开ALB安全组到8080端口的入站规则
- 确认ECS服务配置了足够长的
healthCheckGracePeriodSeconds(健康检查宽限期),大于应用的启动耗时,避免应用还没启动完成就被判定为不健康
- 确认ALB健康检查的端口是否和容器暴露的
生产环境配置/网络/权限问题
你本地运行的镜像使用
NODE_ENV=local参数构建,而部署到ECS的生产镜像使用NODE_ENV=production参数构建,两者运行逻辑存在差异:
排查方向:- 确认生产模式下应用需要访问的上下游服务(数据库、缓存、AWS云服务等)的网络连通性:如果ECS任务部署在私有子网,需要确认是否配置了NAT网关或私有端点来访问外部服务、AWS公共服务
- 确认ECS任务角色的权限满足应用生产环境的资源访问要求,比如是否有S3、DynamoDB等依赖服务的访问权限
- 可以临时把ECS任务定义的启动命令改为
sleep 3600,任务启动后用ECS Exec进入容器内部手动执行npm start,查看完整运行日志,定位是否有未打印到CloudWatch的隐藏报错
资源超限触发强制终止
你当前配置的Fargate任务规格为
256CPU/512MB内存,如果生产环境下应用存在内存泄漏、CPU占用过高的情况,Fargate会强制终止超限的进程:
排查方向:- 到CloudWatch Metrics查看对应ECS服务的CPU、内存使用率指标,确认是否存在使用率持续上涨直到达到阈值的情况
- 可以临时把任务规格调高到
512CPU/1024MB内存测试,确认是否还会出现自动终止的问题
进程信号传递问题
你当前使用
npm start作为容器启动入口,npm进程作为PID1进程默认不会转发系统信号给子Node进程,当ECS发送SIGTERM信号要求进程停止时,Node进程收不到信号,超过终止等待时间后会被强制杀死,也会触发对应报错:
解决方案:
把Dockerfile的ENTRYPOINT配置改为直接启动Node进程,同时删掉ECS任务定义中重复配置的entryPoint字段(Dockerfile中已经声明过启动命令,不需要重复配置)ENTRYPOINT ["node", "./bin/www"]
内容的提问来源于stack exchange,提问作者Jez D
相关产品推荐
相关产品推荐

