Как заставить мою задачу ECS извлекать мой образ ECR

Я пытаюсь создать задачу 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

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) .

В прошлый раз подобная ошибка произошла из-за того, что у ECS не было маршрута к ECR. Это может быть интернет-маршрут или конечная точка ECR VPC. Если контейнер находится в частной подсети, вы можете использовать шлюз NAT (дорого) или конечную точку VPC (менее дорого).

Судя по памяти, все работает следующим образом: ECS запускает вашу задачу вместе с URL-адресом изображения, а контейнер должен получить изображение для начальной загрузки. Контейнер находится в вашем VPC/подсети, поэтому ему нужен маршрут к ECR.

Другие вопросы по тегам