提问人:user2315104 提问时间:2/3/2019 最后编辑:MLavoieuser2315104 更新时间:9/22/2023 访问量:96328
AWS ECS 错误:目标组中的任务 ELB 运行状况检查失败
AWS ECS error: Task failed ELB health checks in Target group
问:
我正在使用云形成模板来构建基础设施(ECS fargate 集群)。 模板已成功执行,堆栈已成功创建。但是,任务失败,出现以下错误:
Task failed ELB health checks in (target-group arn:aws:elasticloadbalancing:eu-central-1:890543041640:targetgroup/prc-service-devTargetGroup/97e3566c8b307abf)
我不明白在哪里寻找这个来解决问题。 由于它是 fargate 集群,我不明白如何登录容器并执行一些运行状况检查查询以进一步调试。
有人可以帮我进一步指导并帮助我吗?
由于此错误,我甚至无法访问我的 Web 应用程序。如果流量不正常,则不会路由流量。ALB
我做了什么
经过一番谷歌搜索,我找到了这个帖子: https://aws.amazon.com/premiumsupport/knowledge-center/troubleshoot-unhealthy-checks-ecs/
但是,我想,这与 fargate 中的 EC2 兼容性有关。但就我而言,EC2 不存在。
如果您愿意,我也可以粘贴整个模板。
请帮忙
答:
此问题已解决。 这是以下几点的问题:
- Docker 容器端口与主机端口的映射不正确
- ALB 运行状况检查间隔时间非常短。因此,ALB 立即放弃了,没有等待 docker 容器启动并正常运行。
进行这些更改后,它工作正常
评论
我遇到了完全相同的问题。我能够通过以下方式解决这个问题:
- 导航到 EC2 服务
- ,然后在侧面板中选择目标组
- 为负载均衡器选择目标组
- 选择“运行状况检查”选项卡
- 确保您的 EC2 实例的运行状况检查与目标组中的运行状况检查相同。这将告知您的 ELB 在执行运行状况检查时将其流量路由到此终端节点。就我而言,我的运行状况检查路径是/health。
我收到此错误消息是因为 ECS 服务和负载均衡器目标组之间的安全组仅允许 HTTP 和 HTTPS 流量。
显然,运行状况检查发生在其他端口和/或协议上,因为更新安全组以允许所有端口上的所有流量(如 https://docs.aws.amazon.com/AmazonECS/latest/userguide/create-application-load-balancer.html 中建议的那样)使运行状况检查起作用。
评论
如上所述,检查 ECS 集群周围的安全组。如果使用 Terraform,请使用如下所示的内容允许进入所有 docker 临时端口:
resource "aws_security_group" "ecs_sg" {
name = "ecs_security_group"
vpc_id = "${data.aws_vpc.vpc.id}"
}
resource "aws_security_group_rule" "ingress_docker_ports" {
type = "ingress"
from_port = 32768
to_port = 61000
protocol = "-1"
cidr_blocks = ["${data.aws_vpc.vpc.cidr_block}"]
security_group_id = "${aws_security_group.ecs_sg.id}"
}
评论
此问题有很多不同的原因,而不仅仅是开放端口:
- ecsServiceRole IAM 角色的 IAM 权限不正确
- 容器实例安全组 Elastic Load Balancing 负载
- 未为所有可用区弹性负载配置平衡器
- 平衡负载均衡器运行状况检查配置错误
- 无法更新服务 servicename:任务定义中更改了负载均衡器容器名称或端口
因此,AWS创建了自己的网站,以解决此错误的可能性:
编辑:就我而言,我的应用程序的运行状况检查代码不同。默认值为 200,但您也可以添加一个范围,例如 200-499。
可能对某人有帮助。我们的目标组运行状况检查路径设置为 ,对于我们的服务来说,它指向 Swagger 并且运行良好。更新为使用 Springfox 而不是手动生成 swagger.json 后,现在执行 302 重定向到 ,这导致运行状况检查失败。由于这是针对 Spring Boot 服务的,因此我们只需将目标组中的运行状况检查路径指向(OOTB Spring 状态页面)。/
/
/swagger-ui.html
/health
让我分享我的经验。
就我而言,一切都是正确的,除了服务器侦听的主机之外,这使得服务器无法从外部世界访问,并且健康检查不起作用。在某些库中,它应该是空的。localhost
0.0.0.0
就我而言,ECS Fargate 将 docker 容器功能编排为服务,而不是 Web 应用程序或 API。该服务是不侦听任何端口(例如:Schedule corn/ActiveMQ message consumer ...等)。
换句话说,它是一个客户端,而不是一个服务器节点。所以我只听localhost进行健康检查......
我在目标组中添加了运行状况检查路径 -
在 index.ts 中的代码下面 -
import express from 'express';
const app = express();
const port = process.env.PORT || 8080;
//Health Check
app.get('/__health', (_, res) => res.send({ ok: 'yes' }));
app.listen(port, () => {
logger.info(`Health Check: Listening at http://localhost:${port}`);
});
解决方案在响应“iravinandan”时部分正确,但在nodejs路由器的最后一部分,只需简单地添加即可。或者,您可以单击页面末尾的“高级”选项卡设置您的个人状态。status(200)
app.get('/__health', (request, response) => response.status(200).end(""));
更多信息请见:请在此处输入链接描述
问候
我的案例是在 FARGATE 模式下运行的 React 应用程序。
第一个问题是 Docker 镜像是在 NodeJS 上构建的,它使用以下命令“服务”它:
CMD npm run start # react-scripts start
除此之外,这根本不是一个好的做法,它需要大量资源(4GB和2vCPU是不够的),因此,检查失败了。(本文提到这是一个可能的原因)
为了解决前面的问题,我们将镜像修改为多阶段构建,构建阶段使用 NodeJS 提供内容,NGINX 提供内容。在本地运行良好,但我们尚未意识到 NGINX 的默认端口为 80,并且您不能在具有 awsvpc 网络模式的 FARGATE 上使用不同的主机和容器端口。
为了解决这个问题,我启动了一个具有正确安全组的 EC2 实例,以在负载均衡器无法执行运行状况检查的同一端口上与 FARGATE 目标连接。我能够对其他目标执行 curl 的命令,但是对于这个不健康的目标(不断被回收),我收到了即时的 Connection 拒绝响应。这不是超时,它告诉我目标无法管理该请求,因为它没有侦听该端口。然后我意识到我的容器需要端口 80 上的流量,并且我的应用程序配置为在 3xxx 端口上工作。
这里的解决方案是修改 NGINX 的默认配置以侦听我们想要的端口,重新构建映像并重新启动服务。
就我而言,我的 ECS Fargate 服务不需要负载均衡器,因此我删除了“负载均衡器”和“安全组”,然后它就可以工作了。
我在作为 fargate 运行的 ACS 上部署 java springboot 应用程序时遇到了同样的问题。我必须解决 3 个问题才能解决问题,如果这可以帮助其他人的话。
容器在端口 8080 上运行(因为 tomcat),因此 ELB、目标组和两个安全组(一个使用 ELB,一个使用 ECS)必须在其入站规则中允许 8080。此外,还必须修改任务设置,以将容器更改为映射到 8080。
目标组运行状况检查部分的端口(高级设置)必须显式更改为 8080,而不是默认的 80。
我不得不在应用程序中创建一个虚拟的运行状况检查路径,因为在“/”处ping应用程序的根目录会导致 302 错误代码。
希望这会有所帮助。
我在使用 AWS Fargate 时也遇到了同样的问题。
以下是一些可以尝试的解决方案:
- 首先检查“附加”的“服务”的安全组,该组具有“出站”和“入站”规则。
- 如果您使用的是 Loadbalancer 并指向目标组,则必须在安全组上启用 docker 容器端口,并附加仅来自 ALB 安全组的入站流量 3)还要检查我们分配给目标组的运行状况检查端点是否有任何依赖项,它应该只返回 200 个状态回复/我们在目标组中指定的内容
就我而言,这是一个安全组规则,仅允许来自某个 IP 的连接,这阻止了来自 LB 的运行状况检查。我将 VPC 的 cidr 作为另一条规则添加到安全组中,然后它起作用了。
我浏览了 aws 提供的博客,我的修复是在 LB w.r.t 中错误地配置了 ping 路径。
https://docs.aws.amazon.com/AmazonECS/latest/userguide/troubleshoot-service-load-balancers.html
https://aws.amazon.com/premiumsupport/knowledge-center/ecs-fargate-health-check-failures/
ECS的一些可能解决方案
- 验证安全组入站端口是否允许 ECS 实例流量。
- 验证容器网络和端口映射。
- 验证目标组运行状况检查终结点。它应该是正确的,并给出 200 状态。
评论
如果您使用 cloudformation 使用管道创建,我建议在您的模板中添加 2 个参数。例:
[第一步] 类型:AWS::ECS::Service 性能: HealthCheckGracePeriodSeconds:60
[第二步] 目标组: 类型:AWS::ElasticLoadBalancing::TargetGroup 性能: 港口:!引用 ListenerContainerPort 协议:TCP VpcId:!参考VPCID 目标类型:ip HealthCheckTimeoutSeconds:40 HealthCheckIntervalSeconds:100
当部署成功完成并且任务停止错误时。
评论