使用动态端口映射时,目标组在端口 80 上不断出现运行状况检查失败并启动新实例

问题描述 投票:0回答:2

我有一个 ECS 集群和一个应用程序负载均衡器。我已按照 aws 文档为 Amazon ECS 设置动态端口映射。

问题是我的实例的端口 80 在我的目标组中注册为目标,但总是失败(这是因为容器在临时端口范围 32768 - 65535 处公开:

因此,我不断启动新的 EC2 实例并终止现有实例的 Autoscaling 组

下面是我的 Tarraform 配置文件,用于创建 ALB、侦听器和 target_group:

resource "aws_alb" "default" {
  name               = "${var.app_name}-${var.app_environment}-alb"
  load_balancer_type = "application"
  internal           = true
  subnets         = var.loadbalancer_subnets
  security_groups = [aws_security_group.load_balancer_security_group.id]
}

resource "aws_lb_listener" "default" {
  load_balancer_arn = aws_alb.default.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.default.arn
  }
}

resource "aws_lb_target_group" "default" {
  name_prefix = "rushmo"
  port        = 80
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "instance"

  health_check {
    healthy_threshold   = "2"
    unhealthy_threshold = "5"
    interval            = "300"
    port                = "traffic-port"
    path                = "/"
    protocol            = "HTTP"
    matcher             = "200,301,302"
  }

}

resource "aws_autoscaling_group" "default" {
  name             = "${var.app_name}-${var.app_environment}-ASG"
  desired_capacity = 1
  health_check_type         = "ELB"
  health_check_grace_period = 600 # 10 min
  launch_configuration      = aws_launch_configuration.default.name
  max_size                  = 1
  min_size                  = 1

  target_group_arns    = [aws_lb_target_group.default.arn]
  termination_policies = ["OldestInstance"]

  vpc_zone_identifier = var.application_subnets
  protect_from_scale_in = true
}

注意:如果我从目标组中手动取消注册端口 80 上的目标,则不断终止和启动新实例的问题就解决了,但我不明白我做错了什么以及为什么此端口 80 显示为注册目标而不仅仅是临时端口范围

amazon-web-services amazon-ec2 terraform amazon-ecs amazon-elb
2个回答
3
投票

我认为问题是由于:

health_check_type         = "ELB"

这使得 ASG 在实例的端口 80 上使用 ALB 的运行状况检查。但是,由于您使用的是 ECS,因此运行状况检查应仅用于您的容器,而不是实例本身。因此应该是:

health_check_type         = "EC2"

0
投票

在 ECS 中,目标组的创建本质上充当 ECS 代理在从生成的容器回填动态端口映射信息时使用的模板。您仍然可以指定真实的服务端口和运行状况检查 URL,但它们不会立即激活...

...除非您碰巧将该 TG 附加到 ASG。如果这样做,您将在 ALB 的运行状况检查和 ASG 的实例替换算法之间建立关联。这就是使用服务端口创建虚拟目标的原因(它不可能工作)...

...如果您使用“ELB”而不是“EC2”ASG 运行状况检查,那么您将不断重新启动。

因此:在 ASG 中指定“EC2”而不是“ELB”运行状况检查,并且不要在其中设置 target_group_arns 属性。这允许 ECS 使用目标组来确定容器运行状况,而通用系统运行状况(RAM、CPU 等)指导 ASG 进行实例更换。

resource "aws_autoscaling_group" "default" {
  name                      = "${var.app_name}-${var.app_environment}-ASG"
  vpc_zone_identifier       = var.application_subnets
  #target_group_arns        = [DO NOT USE]
  health_check_type         = "EC2"
  health_check_grace_period = 600 # 10 min
  desired_capacity          = 1
  max_size                  = 1
  min_size                  = 1
  launch_configuration      = aws_launch_configuration.default.name
  termination_policies      = ["OldestInstance"]
  protect_from_scale_in     = true
}
© www.soinside.com 2019 - 2024. All rights reserved.