我有一个 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 显示为注册目标而不仅仅是临时端口范围
我认为问题是由于:
health_check_type = "ELB"
这使得 ASG 在实例的端口 80 上使用 ALB 的运行状况检查。但是,由于您使用的是 ECS,因此运行状况检查应仅用于您的容器,而不是实例本身。因此应该是:
health_check_type = "EC2"
在 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
}