在私有子网内的集群中运行 ECS 任务仍处于配置状态

Posted

技术标签:

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

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

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

我们已经在 *** 中阅读了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 支持。 【参考方案1】:

终于!!解开谜团!

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

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

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

【讨论】:

以上是关于在私有子网内的集群中运行 ECS 任务仍处于配置状态的主要内容,如果未能解决你的问题,请参考以下文章

ECS 代理无法成功从 ECR 拉取镜像

如何查看 ECS Fargate 容器内的日志?

自动扩展 ECS 集群到/从零个实例

用于微服务的私有子网 ecs 连接上负载均衡器的 AWS API 网关

AWS服务建设之路-Docker集群

在ECS上使用来自pulumi的私人码头登记处的图像