【问题标题】:fargate failing on docker pull in private subnetfargate 在私有子网中的 docker pull 上失败
【发布时间】:2020-04-05 00:36:02
【问题描述】:

我在部署 Fargate 集群时遇到问题,它在 docker pull 映像上失败并出现错误“CannotPullContainerError”。我正在使用 cloudformation 创建堆栈,这不是可选的,它创建了完整的堆栈,但是在尝试基于上述错误启动任务时失败。

我附上了可能会突出问题的 cloudformation 堆栈文件,并且我再次检查了子网是否有到 nat 的路由(如下)。我还通过 ssh 连接到同一子网中的一个实例,该实例能够进行外部路由。我想知道我是否没有正确放置所需的部分,即服务+负载均衡器在私有子网中,还是我不应该将内部 lb 放在同一个子网中???

此子网是当前具有该位置的子网,但文件中的所有 3 个子网都具有相同的 nat 设置。

子网可路由 (subnet-34b92250) * 0.0.0.0/0 -> nat-05a00385366da527a

提前欢呼。

yaml cloudformaition 脚本:

AWSTemplateFormatVersion: 2010-09-09
Description: Cloudformation stack for the new GRPC endpoints within existing vpc/subnets and using fargate
Parameters:
  StackName:
    Type: String
    Default: cf-core-ci-grpc
    Description: The name of the parent Fargate networking stack that you created. Necessary
  vpcId:
    Type: String
    Default: vpc-0d499a68
    Description: The name of the parent Fargate networking stack that you created. Necessary
Resources:
  CoreGrcpInstanceSecurityGroupOpenWeb:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupName: sgg-core-ci-grpc-ingress
      GroupDescription: Allow http to client host
      VpcId: !Ref vpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
  LoadBalancer:
    Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer'
    DependsOn:
      - CoreGrcpInstanceSecurityGroupOpenWeb
    Properties:
      Name: lb-core-ci-int-grpc
      Scheme: internal
      Subnets:
      # # pub
      #   - subnet-f13995a8
      #   - subnet-f13995a8
      #   - subnet-f13995a8
      # pri
        - subnet-34b92250
        - subnet-82d85af4
        - subnet-ca379b93
      LoadBalancerAttributes:
        - Key: idle_timeout.timeout_seconds
          Value: '50'
      SecurityGroups:
        - !Ref CoreGrcpInstanceSecurityGroupOpenWeb
  TargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    DependsOn:
      - LoadBalancer
    Properties:
      Name: tg-core-ci-grpc
      Port: 3000
      TargetType: ip
      Protocol: HTTP
      HealthCheckIntervalSeconds: 30
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 10
      HealthyThresholdCount: 4
      Matcher:
        HttpCode: '200'
      TargetGroupAttributes:
        - Key: deregistration_delay.timeout_seconds
          Value: '20'
      UnhealthyThresholdCount: 3
      VpcId: !Ref vpcId
  LoadBalancerListener:
    Type: 'AWS::ElasticLoadBalancingV2::Listener'
    DependsOn:
      - TargetGroup
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: HTTP
  EcsCluster:
    Type: 'AWS::ECS::Cluster'
    DependsOn:
      - LoadBalancerListener
    Properties:
      ClusterName: ecs-core-ci-grpc
  EcsTaskRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                # - ecs.amazonaws.com
                - ecs-tasks.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: iam-policy-ecs-task-core-ci-grpc
          PolicyDocument:
            Statement:
              - Effect: Allow
                Action:
                  - 'ecr:**'
                Resource: '*'
  CoreGrcpTaskDefinition:
    Type: 'AWS::ECS::TaskDefinition'
    DependsOn:
      - EcsCluster
      - EcsTaskRole
    Properties:
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn: !Ref EcsTaskRole
      Cpu: '1024'
      Memory: '2048'
      ContainerDefinitions:
        - Name: container-core-ci-grpc
          Image: 'nginx:latest'
          Cpu: '256'
          Memory: '1024'
          PortMappings:
            - ContainerPort: '80'
              HostPort: '80'
          Essential: 'true'
  EcsService:
    Type: 'AWS::ECS::Service'
    DependsOn:
      - CoreGrcpTaskDefinition
    Properties:
      Cluster: !Ref EcsCluster
      LaunchType: FARGATE
      DesiredCount: '1'
      DeploymentConfiguration:
        MaximumPercent: 150
        MinimumHealthyPercent: 0
      LoadBalancers:
        - ContainerName: container-core-ci-grpc
          ContainerPort: '80'
          TargetGroupArn: !Ref TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: DISABLED
          SecurityGroups:
            - !Ref CoreGrcpInstanceSecurityGroupOpenWeb
          Subnets:
            - subnet-34b92250
            - subnet-82d85af4
            - subnet-ca379b93
      TaskDefinition: !Ref CoreGrcpTaskDefinition

【问题讨论】:

  • 我还注意到我没有启用 dockerhub creds,所以这可能与它有关吗?

标签: amazon-cloudformation aws-fargate


【解决方案1】:

不幸的是,AWS Fargate 仅支持托管在 ECR 中的映像或 Docker Hub 中的公共存储库,不支持托管在 Docker Hub 中的私有存储库。
更多信息 - https://forums.aws.amazon.com/thread.jspa?threadID=268415

即使我们在几个月前使用 AWS Fargate 时也遇到过同样的问题。你现在只有两个选择:

  1. 将您的图像迁移到 Amazon ECR。

  2. 将 AWS Batch 与自定义 AMI 结合使用,其中自定义 AMI 是使用 ECS 配置中的 Docker Hub 凭证构建的(我们现在正在使用)。

编辑: 正如Christopher Thomas 在评论中提到的,ECS fargate 现在支持从 DockerHub 私有存储库中提取图像。有关如何设置的更多信息,请访问here

【讨论】:

  • 嘿,raj,我在想你不能在 fargate 中使用 ami,或者你是说你已经切换回 ecs 而不是 fargate。
  • 您说得对,我们不能将自定义 AMI 与 AWS Fargate 一起使用。我们实际上切换到 AWS Batch(一种不同的 AWS 服务),其中 EC2 服务器由 AWS 管理,并可选择使用自定义 AMI。欲了解更多信息:docs.aws.amazon.com/batch/latest/userguide/what-is-batch.html
  • AWS Batch 有 3 个组件:Batch environment(您可以在其中定义机器规格)、job queueJob Definition(就像 ECS 任务定义一样)。我们调用一个 lambda 来向 AWS Batch 提交一个作业,这反过来又在 ECS 集群中启动一个 AWS 托管的 EC2 服务器,docker 镜像开始运行。当相应的任务完成时,EC2 将被终止。如果您仍想使用 Fargate,则应将 docker hub 映像迁移到 AWS ECR(与设置新的 AWS Batch 相比,这将花费更少的精力)。
  • 我最初确实收到了来自 aws 支持的评论,建议我可以使用私有存储库。但是,在浪费我的时间之后,他们实际上撤回了该声明并说它不适用于 fargate
  • 如果有人在 2020 年读到这篇文章,只是一个更新。这个问题现在已经修复,你可以使用私有 docker 存储库了。
【解决方案2】:

请在您的 ECR 注册表中定义此策略并将 IAM 角色附加到您的任务中。

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "new statement",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::99999999999:role/ecsEventsRole"
            },
            "Action": [
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage",
                "ecr:InitiateLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:CompleteLayerUpload"
            ]
        }
    ]
}

【讨论】:

  • 这对于 dockerhub 镜像是否有效?在此示例中,我正在拉取 nginx 存储库,但一旦我开始工作,我将想要拉取我们的私有 dockerhub 映像。
  • 我在该脚本中也有一个策略,它似乎涵盖了这些路径“ecr:**”,除非这是不同的上下文
猜你喜欢
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2021-10-23
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多