【问题标题】:AWS ECS Fargate Tasks caught in restart-loop - How to configure LoadBalancer TargetGroup health checks with Pulumi?AWS ECS Fargate 任务陷入重启循环 - 如何使用 Pulumi 配置负载均衡器目标组健康检查?
【发布时间】:2021-07-28 00:20:16
【问题描述】:

我创建了一个简单的 Pulumi TypeScript 程序示例,它应该将 Spring Boot 应用程序部署到 AWS ECS Fargate 集群中。 Spring Boot 应用在 Cloud Native Buildpacks/Paketo.io 的帮助下进行了容器化/Docker 化,并发布到 GitHub 容器注册表ghcr.io/jonashackt/microservice-api-spring-boot (example project here)。

我已经阅读了一些 Pulumi 教程,并从通常的 pulumi new aws-typescript 开始。我现在有以下index.ts:

import * as awsx from "@pulumi/awsx";

// Create a load balancer to listen for requests and route them to the container.
let loadbalancer = new awsx.lb.ApplicationListener("alb", { port: 8098, protocol: "HTTP" });

// Define Container image published to the GitHub Container Registry
let service = new awsx.ecs.FargateService("microservice-api-spring-boot", {
    taskDefinitionArgs: {
        containers: {
          microservice_api_spring_boot: {
                image: "ghcr.io/jonashackt/microservice-api-spring-boot:latest",
                memory: 768,
                portMappings: [ loadbalancer ],
            },
        },
    },
    desiredCount: 2,
});

// Export the URL so we can easily access it.
export const apiUrl = loadbalancer.endpoint.hostname;

选择dev 堆栈后,正常的pulumi up 会运行并为我提供ApplicationLoadBalancer URL。这里还有一个 asciicast 我准备展示一切顺利:

我现在的问题是 Fargate 服务不断停止和启动。我查看了 CloudWatch 日志,我看到 Spring Boot 应用程序正在启动 - 并且在几秒钟后再次停止。我已经检查了 ApplicationLoadBalancer 的 TargetGroup,我看到 Registered Targets 一次又一次地变为 unhealthy。我该如何解决?

【问题讨论】:

  • 也请注意 - AWS 正在努力更新 ecs 控制台。旧版本显示启动错误/容器失败的原因(无法提取图像等)。新的控制台代码虽然在此评论时没有这个有用的小细节

标签: amazon-web-services spring-boot docker aws-fargate pulumi


【解决方案1】:

默认的 AWS TargetGroup HealthCheckPath 就是 /(请参阅 the docs)。作为标准的 Spring Boot 应用程序,通常会以这样的 HTTP 404 响应:

TargetGroups 内的 ApplicationLoadBalancers 健康检查 Status 转到 unhealthy,从而触发 Fargate 服务的重启。

我们如何解决这个问题?在 Spring Boot 中,您通常会使用 spring-boot-actuator。将其添加到您的pom.xml 应用程序会响应localhost:yourPort/actuator/health:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

所以我们需要配置Pulumi创建的TargetGroup使用健康检查路径/actuator/health而不是/。

Pulumi 文档告诉我们如何Manually Configure Target Groups,但是这些如何准确地集成到 TypeScript 代码中呢?答案隐藏在@pulumi/awsx/lb docs! Pulumi 教程中的示例代码从一行let loadbalancer = new awsx.lb.ApplicationListener("alb", { port: 8098, protocol: "HTTP" }); 中完成了多项操作:

  1. 它创建一个 ApplicationLoadBalancer
  2. 它会创建一个匹配的 TargetGroup
  3. 它创建一个匹配的 ApplicationListener

我们只需要手动创建每个组件,因为这样我们可以配置 TargetGroup 的healthCheck: path 属性:

import * as awsx from "@pulumi/awsx";

// Spring Boot Apps port
const port = 8098;

// Create a ApplicationLoadBalancer to listen for requests and route them to the container.
const alb = new awsx.lb.ApplicationLoadBalancer("fargateAlb");

// Create TargetGroup & Listener manually (see https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/awsx/lb/)
// so that we can configure the TargetGroup HealthCheck as described in (https://www.pulumi.com/docs/guides/crosswalk/aws/elb/#manually-configuring-target-groups)
// otherwise our Spring Boot Containers will be restarted every time, since the TargetGroup HealthChecks Status always
// goes to unhealthy
const albTargetGroup = alb.createTargetGroup("fargateAlbTargetGroup", {
    port: port,
    protocol: "HTTP",
    healthCheck: {
        // Use the default spring-boot-actuator health endpoint
        path: "/actuator/health"
    }
});

const albListener = albTargetGroup.createListener("fargateAlbListener", { port: port, protocol: "HTTP" });

// Define Container image published to the GitHub Container Registry
const service = new awsx.ecs.FargateService("microservice-api-spring-boot", {
    taskDefinitionArgs: {
        containers: {
            microservice_api_spring_boot: {
                image: "ghcr.io/jonashackt/microservice-api-spring-boot:latest",
                memory: 768,
                portMappings: [ albListener ]
            },
        },
    },
    desiredCount: 2,
});

// Export the URL so we can easily access it.
export const apiUrl = albListener.endpoint.hostname;

现在,使用此配置,我们的 Fargate 服务在启动后应该会恢复正常。我们应该能够在 AWS 控制台的 ALB 的 TargetGroup 中看到这一点:

【讨论】:

    猜你喜欢
    • 2019-08-27
    • 2020-09-23
    • 2021-04-20
    • 2013-04-11
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 2020-07-22
    相关资源
    最近更新 更多