Skip to content

AWS ECS Fargate ResourceInitializationError 错误解决指南

问题描述

在使用 AWS ECS Fargate 平台版本 1.4.0 运行私有仓库时,可能会遇到以下错误:

ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to get registry auth from asm: service call has been retried 1 time(s): asm fetching secret from the service for <secretname>: RequestError: ...

即使已正确配置 ecsTaskExecutionRole 并包含所有必需的策略,此错误仍可能发生。

错误根源

从 Fargate 平台版本 1.4.0 开始,AWS 对网络模型进行了重大更改:

网络模型变更

在版本 1.3.0 及以下,每个 Fargate 任务有两个网络接口:

  • 一个用于应用程序流量、日志和容器镜像层拉取
  • 另一个用于 Fargate 平台获取 ECR 认证凭证和密钥

从版本 1.4.0 开始,Fargate 改为使用单个网络接口,所有流量(包括平台流量)都通过同一任务网络接口,并保持在您的 VPC 内。

这意味着您现在需要确保 VPC 中有网络路径允许任务与 ECR 和 AWS Secrets Manager 通信。

解决方案

方案一:使用公有子网和公共 IP

最简单的解决方案是将任务启动到具有公共 IP 地址的公有子网中:

  1. 在创建或更新 ECS 服务时,选择公有子网
  2. 设置 "Auto-assign public IP" 为 "ENABLED"
  3. 确保安全组允许出站 HTTPS 流量(端口 443)

安全提醒

此方法会将您的任务暴露到公共互联网,请根据安全要求谨慎使用。

方案二:使用私有子网和 NAT 网关

如果需要在私有子网中运行任务:

  1. 创建 NAT 网关并放置在公有子网中
  2. 配置私有子网的路由表,将出站流量指向 NAT 网关
  3. 确保安全组允许出站 HTTPS 流量

方案三:使用 VPC 端点(推荐用于私有网络)

对于完全私有的 VPC 环境(无 NAT 网关),必须配置 VPC 接口端点:

bash
# ECR API 端点
com.amazonaws.<region>.ecr.api

# ECR DKR 端点  
com.amazonaws.<region>.ecr.dkr

# S3 网关端点(网关类型)
com.amazonaws.<region>.s3

# CloudWatch Logs 端点
com.amazonaws.<region>.logs

# Secrets Manager 端点(可选,如使用密钥)
com.amazonaws.<region>.secretsmanager

# KMS 端点(可选,如使用加密)
com.amazonaws.<region>.kms
json
{
  "Type": "HTTPS",
  "Protocol": "TCP", 
  "Port": 443,
  "Source": "<ECS 服务的安全组>"
}

安全组配置指南

正确配置安全组至关重要:

  1. 为 VPC 端点创建专用的安全组(如 vpc-endpoint-sg
  2. 添加入站规则:允许来自 ECS 任务安全组的 HTTPS(端口 443)流量
  3. 确保 ECS 任务安全组有适当的出站规则

常见错误

不要将 ECS 服务安全组直接附加到 VPC 端点,这不会允许入站流量到达端点。

IAM 权限配置

确保 ECS 任务执行角色具有以下权限:

json
{
  "Effect": "Allow",
  "Action": [
    "ecr:GetAuthorizationToken",
    "ecr:BatchGetImage", 
    "ecr:GetDownloadUrlForLayer",
    "logs:CreateLogStream",
    "logs:PutLogEvents",
    "secretsmanager:GetSecretValue"
  ],
  "Resource": "*"
}
json
{
  "Effect": "Allow",
  "Principal": {
    "Service": "ecs-tasks.amazonaws.com"
  },
  "Action": "sts:AssumeRole"
}

Terraform 配置示例

以下是创建具有必要 VPC 端点的完整 VPC 的 Terraform 配置:

hcl
variable "name" {
  description = "项目名称,例如 my-project"
  type        = string
}

variable "environment" {
  description = "环境,例如 prod"
  type        = string
}

variable "aws_region" {
  description = "AWS 区域,例如 us-east-1"
  type        = string
}

data "aws_availability_zones" "available" {}

locals {
  num_availability_zones = 3
  availability_zones = slice(data.aws_availability_zones.available.names, 0, local.num_availability_zones)
  public_cidrs = [for n in range(1, local.num_availability_zones + 1): "10.0.${n}.0/24"]
  private_cidrs = [for n in range(local.num_availability_zones + 1, local.num_availability_zones * 2 + 1): "10.0.${n}.0/24"]
}

resource "aws_vpc" "this" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "${var.name}-${var.environment}"
  }
}

resource "aws_subnet" "private" {
  count             = local.num_availability_zones
  availability_zone = element(local.availability_zones, count.index)
  cidr_block        = element(local.private_cidrs, count.index)
  vpc_id            = aws_vpc.this.id

  tags = {
    Name = "${var.name}-${var.environment}-private-${count.index + 1}"
  }
}

# 其余资源:公有子网、互联网网关、路由表等...

resource "aws_vpc_endpoint" "ecr_dkr" {
  private_dns_enabled = true
  service_name        = "com.amazonaws.${var.aws_region}.ecr.dkr"
  vpc_endpoint_type   = "Interface"
  vpc_id              = aws_vpc.this.id

  security_group_ids = [aws_security_group.this.id]
  subnet_ids = aws_subnet.private[*].id

  tags = {
    Name = "${var.name}-${var.environment}-privatelink-ecr-dkr"
  }
}

# 类似地创建其他端点:ecr_api、cloudwatch、s3_gateway 等...

故障排除工具

AWS 提供了系统管理器(SSM)运行手册来帮助诊断此问题:

  1. 访问 AWS Systems Manager 控制台
  2. 在侧边栏中选择 "Automation" → "Execute automation"
  3. 搜索并执行 AWSSupport-TroubleshootECSTaskFailedToStart 运行手册
  4. 提供必要的参数(集群名称、子网 ID、安全组 ID 等)

该工具将自动检查并报告根本原因,如缺失的 VPC 端点、安全组配置错误或 IAM 权限问题。

其他常见问题

  1. 密钥格式错误:确保 Secrets Manager ARN 末尾包含 ::

    json
    "valueFrom": "arn:aws:secretsmanager:<region>:<account>:secret:<name>:<key>::"
  2. 密钥值为空:确认 Secrets Manager 中的密钥已设置实际值

  3. DNS 解析问题:如果使用自定义 DNS,确保能正确解析 VPC 端点地址

  4. 区域不匹配:确保所有资源(ECR、Secrets Manager、端点)都在同一区域

总结

Fargate 平台版本 1.4.0 的网络模型变更要求用户显式配置网络路径来访问 AWS 服务。通过正确设置 VPC 端点、安全组和 IAM 权限,可以解决 ResourceInitializationError 错误并确保任务成功启动。

最佳实践推荐

对于生产环境,建议使用 VPC 端点方案,它提供了更好的安全控制和网络隔离,同时避免了 NAT 网关的成本。

参考资料