【问题标题】:Running ECS task in a cluster within a private subnet remains in provisioning status在私有子网内的集群中运行 ECS 任务仍处于配置状态
【发布时间】:2020-12-16 16:35:01
【问题描述】:

我们要构建一个具备以下特点的ECS集群:

  1. 它必须在 VPC 中运行,然后,我们需要 awsvpc 模式
  2. 它必须使用 GPU 实例,所以我们不能使用 Fargate
  3. 它必须动态配置实例,因此,我们需要容量提供程序
  4. 它将运行将通过 AWS ECS API 直接触发的任务(批处理作业)。因此,我们不需要服务,只需要任务定义。
  5. 这些任务必须能够访问 S3(互联网),因此根据 AWS 文档,实例必须放置在私有子网 (a reference to docs) 内。

我们已经在 stackoverflow 中阅读了this post,其中说我们需要使用路由表设置私有子网,该路由表指向在公共子网中配置的 NAT 网关,并且该公共子网应该指向互联网网关。我们已经有了这个配置。我们还在路由表中配置了一个 S3 vpc 端点。

下面,你可以在 terraform 中看到集群的一些相关配置(为简单起见,我只放了相关部分):


# Launch template
resource "aws_launch_template" "train-launch-template" {
  name_prefix   = "{var.project_name}-launch-template-${var.env}"
  image_id      = "ami-01f62a207c1d180d2"
  instance_type = "m5.large"
  key_name="XXXXXX"
  iam_instance_profile {
    name = aws_iam_instance_profile.ecs-instance-profile.name
  }
  user_data = base64encode(data.template_file.user_data.rendered)

  network_interfaces {
    associate_public_ip_address = false
    security_groups = [aws_security_group.ecs_service.id]
  }
}


# Task definition
resource "aws_ecs_task_definition" "task" {
  family                   = "${var.project_name}-${var.env}-train-task"
  execution_role_arn       = data.aws_iam_role.ecs_task_execution_role.arn
  task_role_arn            = aws_iam_role.ecs_train_task_role.arn
  requires_compatibilities = ["EC2"]
  cpu                      = var.ecs_cpu
  network_mode             = "awsvpc"
  memory                   = var.ecs_memory
  container_definitions    = data.template_file.app_definition.rendered

  tags = {
    Stage   = var.env_tag
    Project = var.project_name_tag
  }
}


# Cluster
resource "aws_ecs_cluster" "cluster" {
  name = "${var.project_name}-${var.env}-train-ecs-cluster"
  capacity_providers = [aws_ecs_capacity_provider.train-capacity-provider.name]
  default_capacity_provider_strategy {
    capacity_provider = aws_ecs_capacity_provider.train-capacity-provider.name
  }
  tags = {
    Project = var.project_name_tag
    Stage   = var.env_tag
  }
}

我们还配置了实例所需的所有角色以及访问所需资源(S3、ECR、ECS)的任务。

AMI 对应一个 ECS 优化实例(目前在 eu-west-1 中发布的最后一个版本)。

在启动模板中,由于this link 中的解释,我们已经删除了实例的公共 IP

我们已经进化到这种配置来尝试使其工作,但我们一次又一次地面临同样的问题:当任务被触发时,容量提供者会启动一个实例,但该任务从未放入容器中实例并无限期保持在 PROVISIONING 状态。

使用相同的配置但将实例放置在公共子网中,任务被放置到容器实例中,但正如 the first link 中警告的那样,该任务无法访问互联网。

我们需要一些启示或线索。提前谢谢你。

更新:根据要求,我添加了有关自动缩放的其余部分

resource "aws_autoscaling_group" "train-autoscaling" {
  availability_zones = ["eu-west-1b"]
  desired_capacity   = 0
  max_size           = 10
  min_size           = 0
  protect_from_scale_in = true
  

  launch_template {
    id      = aws_launch_template.train-launch-template.id
    version = "$Latest"
  }

  tags = [
    {
      key = "Project",
      value = var.project_name_tag
      propagate_at_launch = true
    },
    {
      key = "Stage",
      value = var.env_tag
      propagate_at_launch = true
    }
  ]
}

resource "aws_ecs_capacity_provider" "train-capacity-provider" {
  name = "${var.project_name}-${var.env}-train-capacity-provider"

  auto_scaling_group_provider {
    auto_scaling_group_arn         = aws_autoscaling_group.train-autoscaling.arn
    managed_termination_protection = "ENABLED"

    managed_scaling {
      status                    = "ENABLED"
      target_capacity           = 100
      maximum_scaling_step_size = 1
      minimum_scaling_step_size = 1
    }
  }
}

data "template_file" "user_data" {
  template = "${file("${path.module}/user_data.sh")}"

  vars = {
    cluster_name = "${var.project_name}-${var.env}-train-ecs-cluster"
  }
}

更新 2(AWS 控制台信息):

容器实例运行

详细容器实例:

待处理任务:

待处理任务详情:

更新 3:

30 分钟后任务停止,这是显示的消息(任务无法启动):

更新 4:

来自容器实例的日志。 ecs-agent.log

level=info time=2020-08-28T11:09:21Z msg="Loading configuration" module=agent.go
level=info time=2020-08-28T11:09:21Z msg="Amazon ECS agent Version: 1.44.1, Commit: 1f05fbf0" module=agent.go
level=info time=2020-08-28T11:09:21Z msg="Image excluded from cleanup: amazon/amazon-ecs-pause:0.1.0" module=docker_image_manager.go
level=info time=2020-08-28T11:09:21Z msg="Image excluded from cleanup: amazon/amazon-ecs-pause:0.1.0" module=docker_image_manager.go
level=info time=2020-08-28T11:09:21Z msg="Image excluded from cleanup: amazon/amazon-ecs-agent:latest" module=docker_image_manager.go
level=info time=2020-08-28T11:09:21Z msg="Creating root ecs cgroup: /ecs" module=init_linux.go
level=info time=2020-08-28T11:09:21Z msg="Creating cgroup /ecs" module=cgroup_controller_linux.go
level=info time=2020-08-28T11:09:21Z msg="Event stream ContainerChange start listening..." module=eventstream.go
level=info time=2020-08-28T11:09:21Z msg="Loading state!" module=state_manager.go
level=info time=2020-08-28T11:09:23Z msg="Registering Instance with ECS" module=agent.go
level=info time=2020-08-28T11:09:23Z msg="Remaining mem: 7680" module=client.go
level=info time=2020-08-28T11:09:23Z msg="Registered container instance with cluster!" module=client.go
level=info time=2020-08-28T11:09:23Z msg="Registration completed successfully. I am running as 'arn:aws:ecs:eu-west-1:XXXXXXXXXXXXXXXX:container-instance/foqum-read-dev-train-ecs-cluster/95559f936f8d44de9373595009fcd588' in cluster 'foqum-read-dev-train-ecs-cluster'" module=agent.go
level=info time=2020-08-28T11:09:23Z msg="Beginning Polling for updates" module=agent.go
level=info time=2020-08-28T11:09:23Z msg="Initializing stats engine" module=engine.go
level=info time=2020-08-28T11:09:23Z msg="Event stream DeregisterContainerInstance start listening..." module=eventstream.go
level=info time=2020-08-28T11:09:23Z msg="Establishing a Websocket connection to https://ecs-t-X.eu-west-1.amazonaws.com/ws?agentHash=1f05fbf0&agentVersion=1.44.1&cluster=XXXXXXXXX-cluster&containerInstance=arn%3Aaws%3Aecs%3Aeu-west-1%3AXXXXXXXX%3Acontainer-instance%2FXXXXXXXX-cluster%2F95559fXXXXXXde9373595009fcd588&dockerVersion=19.03.6-ce" module=client.go
level=info time=2020-08-28T11:09:23Z msg="NO_PROXY set:XXX.254.169.XXXX,XXXX.254.XXX.2,/var/run/docker.sock" module=client.go
level=info time=2020-08-28T11:09:23Z msg="Establishing a Websocket connection to https://ecs-a-X.eu-west-1.amazonaws.com/ws?agentHash=1f05fbf0&agentVersion=1.44.1&clusterArn=XXXXX-ecs-cluster&containerInstanceArn=arn%3Aaws%3Aecs%3Aeu-west-1%XXXXXX%3Acontainer-instance%2FXXXXX-ecs-cluster%2F9XXXXX6f8d44de9373595009fcd588&dockerVersion=DockerVersion%3A+19.03.6-ce&sendCredentials=true&seqNum=1" module=client.go
level=info time=2020-08-28T11:09:23Z msg="Connected to TCS endpoint" module=handler.go
level=info time=2020-08-28T11:09:23Z msg="Connected to ACS endpoint" module=acs_handler.go
level=info time=2020-08-28T11:20:04Z msg="TCS Websocket connection closed for a valid reason" module=handler.go
level=info time=2020-08-28T11:20:04Z msg="Establishing a Websocket connection to https://ecs-t-X.eu-west-1.amazonaws.com/ws?agentHash=1f05fbf0&agentVersion=1.44.1&cluster=XXXXXXXecs-cluster&containerInstance=arn%3Aaws%3Aecs%3Aeu-west-1%3AXXXXXX3Acontainer-instance%2FZZZXXXXX-ecs-cluster%2F95XXX936f8d44de9373595009fcd588&dockerVersion=19.03.6-ce" module=client.go
level=info time=2020-08-28T11:20:04Z msg="Connected to TCS endpoint" module=handler.go

ecs-init.log

2020-08-28T11:09:19Z [INFO] pre-start
2020-08-28T11:09:20Z [INFO] start
2020-08-28T11:09:20Z [INFO] No existing agent container to remove.
2020-08-28T11:09:20Z [INFO] Starting Amazon Elastic Container Service Agent

【问题讨论】:

  • 你在用启动模板做什么?您似乎缺少一个自动缩放组资源。
  • @jordanm 我已经在信息中添加了自动缩放的部分
  • ECS UI 是否显示集群有成员?在待处理任务页面上,如果您展开容器详细信息,是否会显示任何错误?您检查过集群实例上的 ECS 日志吗?
  • @jordanm 我添加了控制台中显示的容器实例和任务信息的屏幕截图。关于集群实例中的ECS日志,恕我无知,但是在哪里可以看到这些日志呢?我必须通过 ssh 访问实例吗?
  • 是的,您必须通过 SSH 访问日志。我与 ECS 合作过很多次,您所展示的任何内容都不是错误的。我建议联系 AWS 支持。

标签: amazon-web-services amazon-s3 terraform amazon-ecs


【解决方案1】:

终于!!解开谜团!

问题不在集群配置中。通过 ECS API 调用 run_task 时,您需要指定任务应该运行到的子网。

我们的代码在此字段中设置了其中一个公共子网的值。因此,当我们将容器实例更改为与该公共子网对应的可用区时,任务就被放置了。

从代码更改此调用,任务被正确放置并且可以访问互联网。

【讨论】:

    猜你喜欢
    • 2019-08-29
    • 1970-01-01
    • 2021-09-04
    • 2016-06-06
    • 2019-11-08
    • 2021-10-31
    • 1970-01-01
    • 2022-08-23
    • 1970-01-01
    相关资源
    最近更新 更多