为什么我的 Fargate 任务卡在待定状态?

why are my Fargate tasks stuck on pending?

我正在使用 Terraform 设置一个包含三个 apache 服务器任务的小型 Fargate 集群。任务挂起,然后集群停止它们并创建新的挂起任务,然后循环继续。

AWS docs 说可能是因为:

  • The Docker daemon is unresponsive

文档说要设置 CloudWatch 以查看 CPU 使用情况并在需要时增加容器大小。我已将 CPU/memory 都提高到 1024/2048,但这并没有解决问题。

  • The Docker image is large

不太可能?图片不过是httpd:2.4

  • The ECS container agent lost connectivity with the Amazon ECS service in the middle of a task launch

文档为容器实例中的 运行 提供了一些命令。为此,我似乎必须 set up AWS Systems Manager or SSH in directly。如果我的 Terraform 配置没有发现任何问题,我会选择这条路线。

  • The ECS container agent takes a long time to stop an existing task

不太可能,因为我正在启动一个全新的 ECS 集群


下面是我的 Terraform 文件的 ECS 和 IAM 部分。为什么我的 Fargate 任务会卡在待处理状态?

#
# ECS
#
resource "aws_ecs_cluster" "main" {
  name = "main-ecs-cluster"
}

resource "aws_ecs_task_definition" "app" {
  family                   = "app"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = 256
  memory                   = 512
  execution_role_arn       = aws_iam_role.task_execution.arn
  task_role_arn            = aws_iam_role.task_execution.arn
  container_definitions = <<DEFINITION
  [
    {
      "image": "httpd:2.4",
      "cpu": 256,
      "memory": 512,
      "name": "app",
      "networkMode": "awsvpc",
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80,
          "protocol": "tcp"
        }
      ]
    }
  ]
  DEFINITION
}

resource "aws_ecs_service" "main" {
  name            = "tf-ecs-service"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = 2
  launch_type     = "FARGATE"

  network_configuration {
    security_groups = [aws_security_group.main.id]
    subnets         = [
      aws_subnet.public1.id,
      aws_subnet.public2.id,
    ]
  }
}

#
# IAM
#
resource "aws_iam_role" "task_execution" {
  name               = "my-first-service-task-execution-role"
  assume_role_policy = data.aws_iam_policy_document.task_execution.json
}

data "aws_iam_policy_document" "task_execution" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy_attachment" "task_execution" {
  role       = aws_iam_role.task_execution.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

根据评论中的讨论,确定问题是由 Fargate 任务无法访问互联网引起的。

这是因为任务 运行 在 私有子网 中,而任务使用来自 docker 中心的 httpd 图像。从中心拉取图像需要互联网访问。

可能的解决方案是使用 NAT gateway/instance、使用 public 子网中的任务或在 ECR 中使用自定义图像..

Public 子网 / public IP 出于许多安全原因可能不是正确的解决方案。

考虑将您的任务放在私有子网中。

  1. 如果您配置通过 NAT 连接到互联网,您将能够拉取图像 pulling image from ECR using routing through NAT gateway

或者您可以使用更好的解决方案:

  1. 您的 ECS FARGATE 可以从 ECR 中提取图像,即使您放置在 PRIVATE 子网中而无需连接到互联网。 请检查 AWS PrivateLink for ECR 图:pulling image from ECS using PrivateLink - VPC endpoints