我正在尝试创建 ECS 任务并能够访问和提取 ECR,但出现错误。我该如何解决这个问题?
原始错误:
Cannotpullcontainererror: pull image manifest has been retried 1 time(s): failed to resolve ref {accId}.dkr.ecr.us-east-1.amazonaws.com/test-container:latest: {accId}.dkr.ecr.us-east-1.amazonaws.com/test-container:latest: not found
AWSTemplateFormatVersion:'2010-09-09' 描述:'ECS 服务、集群和 ECR'
Resources:
# ECR repository
EcrRepository:
Type: 'AWS::ECR::Repository'
Properties:
RepositoryName: 'test-container'
# ECS cluster
EcsCluster:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: 'test'
# IAM role for ECS task
EcsTaskRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Principal:
Service:
- 'ecs-tasks.amazonaws.com'
Action:
- 'sts:AssumeRole'
Path: '/'
Policies:
- PolicyName: 'test_task_policy'
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: 'Allow'
Action:
- 'ecr:*'
Resource: '*'
- Effect: 'Allow'
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
- Effect: 'Allow'
Action:
- 'lambda:InvokeFunction'
- 'lambda:GetFunction'
Resource: '*'
- Effect: 'Allow'
Action:
- 'ec2:CreateNetworkInterface'
- 'ec2:DescribeNetworkInterfaces'
- 'ec2:DeleteNetworkInterface'
Resource: '*'
# ECS task definition
EcsTaskDefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
Family: 'test'
Memory: 512
Cpu: 256
ContainerDefinitions:
- Name: 'test_container'
Image: !Join [ "", [ !Ref "AWS::AccountId", ".dkr.ecr.", !Ref "AWS::Region", ".amazonaws.com/", !Ref EcrRepository, "" ] ]
PortMappings:
- ContainerPort: 80
Environment:
- Name: 'ENV_VAR_1'
Value: 'value1'
Essential: true
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Join [ '', [ '/ecs/', !Ref AWS::StackName ] ]
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
awslogs-create-group: true
TaskRoleArn: !GetAtt EcsTaskRole.Arn
ExecutionRoleArn: !GetAtt TestExecutionRole.Arn
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
# ECS service
EcsService:
Type: 'AWS::ECS::Service'
Properties:
ServiceName: 'test_svc'
Cluster: !Ref EcsCluster
DesiredCount: 1
TaskDefinition: !Ref EcsTaskDefinition
LaunchType: 'FARGATE'
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !Ref TestSG
Subnets:
- !Ref TestSubnet
TestExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: TestExecutionRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'sts:AssumeRole'
Principal:
Service:
- 'ecs-tasks.amazonaws.com'
Policies:
- PolicyName: EcsTaskExecutionPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'ec2:*'
- 'ecs:*'
- 'logs:*'
- 'ecr:*'
Resource: '*'
# Network
TestVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
TestSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref TestVPC
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true
TestSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for my ECS task
VpcId: !Ref TestVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
RouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref TestVPC
InternetGateway:
Type: "AWS::EC2::InternetGateway"
VPCGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref TestVPC
InternetGatewayId: !Ref InternetGateway
InternetRoute:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
RouteTableId: !Ref RouteTable
SubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref TestSubnet
答案1
上次我遇到这样的错误是因为 ECS 没有到 ECR 的路由。这可以是互联网路由或 ECR VPC 端点。如果容器位于私有子网中,您可以使用 NAT 网关(昂贵)或 VPC 端点(较便宜)。
从记忆中看,事情似乎是这样运作的:ECS 启动您的任务以及图像的 URL,容器必须获取图像来引导自身。容器位于您的 VPC/子网上,这就是为什么它需要一条通往 ECR 的路由。
答案2
您的问题在于:
TestSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for my ECS task
VpcId: !Ref TestVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
您的 ECS 任务的安全组应允许出站流量到 ECR。最简单的方法是允许所有流量到 0.0.0./0(流量通过互联网)。您也可以使用 VPC 端点到 ECR,但仍需要在安全组中添加出站规则(文档:https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html)