为什么我的 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 出于许多安全原因可能不是正确的解决方案。
考虑将您的任务放在私有子网中。
- 如果您配置通过 NAT 连接到互联网,您将能够拉取图像
pulling image from ECR using routing through NAT gateway
或者您可以使用更好的解决方案:
- 您的 ECS FARGATE 可以从 ECR 中提取图像,即使您放置在 PRIVATE 子网中而无需连接到互联网。
请检查 AWS PrivateLink for ECR
图:pulling image from ECS using PrivateLink - VPC endpoints
我正在使用 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 出于许多安全原因可能不是正确的解决方案。
考虑将您的任务放在私有子网中。
- 如果您配置通过 NAT 连接到互联网,您将能够拉取图像 pulling image from ECR using routing through NAT gateway
或者您可以使用更好的解决方案:
- 您的 ECS FARGATE 可以从 ECR 中提取图像,即使您放置在 PRIVATE 子网中而无需连接到互联网。 请检查 AWS PrivateLink for ECR 图:pulling image from ECS using PrivateLink - VPC endpoints