【问题标题】:CannotPullContainerError: context canceled error when starting ECS taskCannotPullContainerError:启动 ECS 任务时出现上下文取消错误
【发布时间】:2020-02-29 11:27:10
【问题描述】:

我正在使用 Fargate 启动 ECS 任务,容器在 PENDING 几分钟后最终处于 STOPPED 状态。状态给出以下错误消息:

CannotPullContainerError: context canceled

我正在使用 PrivateLink 允许 ECS 主机与 ECR 注册表对话,而无需通过公共 Internet,这就是它的配置方式(无服务器语法增强 CloudFormation):

      Properties:
        PrivateDnsEnabled: true
        ServiceName: com.amazonaws.ap-southeast-2.ecr.dkr
        SubnetIds:
          - { Ref: frontendSubnet1 }
          - { Ref: frontendSubnet2 }
        VpcEndpointType: Interface
        VpcId: { Ref: frontendVpc }

关于导致错误的原因有什么想法吗?

【问题讨论】:

标签: amazon-web-services aws-ecr


【解决方案1】:

您是否还添加了 S3 端点? 这是我的模板的工作 sn-p,我能够通过 aws 支持解决问题:

  EcrDkrEndpoint:
Type: 'AWS::EC2::VPCEndpoint'
Properties:
  PrivateDnsEnabled: true
  SecurityGroupIds: [!Ref 'FargateContainerSecurityGroup']
  ServiceName: !Sub 'com.amazonaws.${AWS::Region}.ecr.dkr'
  SubnetIds: [!Ref 'PrivateSubnetOne', !Ref 'PrivateSubnetTwo']
  VpcEndpointType: Interface
  VpcId: !Ref 'VPC'

对于 S3,您需要知道路由表是必需的 - 通常您希望使用与 Internet 网关相同的路由表,其中包含路由 0.0.0.0/0

  S3Endpoint:
Type: 'AWS::EC2::VPCEndpoint'
Properties:
  ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
  VpcEndpointType: Gateway
  VpcId: !Ref 'VPC'
  RouteTableIds: [!Ref 'PrivateRouteTable'] 

如果没有 cloudwatch 端点,您将再次失败,这也是必要的:

  CloudWatchEndpoint:
Type: 'AWS::EC2::VPCEndpoint'
Properties:
  PrivateDnsEnabled: true
  SecurityGroupIds: [!Ref 'FargateContainerSecurityGroup']
  ServiceName: !Sub 'com.amazonaws.${AWS::Region}.logs'
  SubnetIds: [!Ref 'PrivateSubnetOne', !Ref 'PrivateSubnetTwo']
  VpcEndpointType: Interface
  VpcId: !Ref 'VPC'

编辑:私有路由表:

  PrivateRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachement
Properties:
  RouteTableId: !Ref 'PublicRouteTable'
  DestinationCidrBlock: '0.0.0.0/0'
  GatewayId: !Ref 'InternetGateway'

【讨论】:

  • 我也为 S3 添加了一个 VPCEndpoint,但我没有为 CloudWatch 添加一个 - 如果没有 CloudWatch VPCEndpoint,您会遇到什么错误?我与我的内部 AWS 团队进行了交谈,他们认为我所拥有的应该可行,因此我们决定采取不同的方法(为容器提供公共 IP 地址并将它们放入安全组中)。
  • 您的 S3 VPCEndpoint 是否包含参数“RouteTableIds”这是必要的,即使文档说它是可选的。添加路由表后,错误“CannotPullContainerError:上下文已取消”为我解决了。我在没有 CloudWatch 端点的情况下收到此错误:“DockerTimeoutError:无法转换为启动;等待 3 分钟后超时”支持人员告诉我,以下错误也可能出现:“CannotStartContainerError:来自守护程序的错误响应:无法初始化日志记录驱动程序”
  • 不,我没有 - 我信任 AWS 文档(因为有太多文档可以质疑它)。私有路由表中需要什么?
  • 我也信任文档,并且真的很惊讶,因为支持人员告诉我该参数是必要的。 (我希望他们会在文档中添加提示。)私有路由表只需要到您的互联网网关的默认路由,我将 cloudformation sn-p 添加到我的原始答案中。
  • 我在一个完全隔离的 VPC(只有 S3 和 ECR 的内部 VPC 端点)上收到了类似的错误。由于我们没有互联网网关,因此上述内容没有帮助。在我们的例子中,它与任务的安全组有关。它被配置为仅允许访问私有 VPC 子网,因此无法对存储 docker 层的 S3 存储桶进行出站访问。在咨询 AWS 支持后,他们建议我们添加一条规则,允许 https/tcp-443 到 0.0.0.0/0 出口。这解决了问题。
【解决方案2】:

我发现我不仅需要 s3 的 vpc 端点、aws 日志和两个 ecr 端点,如@graphik_ 的答案中所述,而且我还需要确保端点上的安全组允许从安全性入口访问 HTTPS Farscape 容器上的组。

Farscape 容器上的安全组需要通过 HTTPS 对 vpce 端点安全组以及 pl-7ba54012 IP 组(即 s3)进行出口访问。

这和路由表中到 pl-7ba54012 的路由似乎是全貌。

vpce 上也有策略,我将其保留为默认的“所有访问权限”,但您可以将其强化为仅允许从运行 Fargate 容器的角色进行访问。

【讨论】:

    猜你喜欢
    • 2020-02-11
    • 2020-02-29
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多