Elastic BeanStalk MultiContainer docker 失败

Elastic BeanStalk MultiContainer docker fails

我想在 elastic beanstalk 中部署一个多容器应用程序。我收到以下错误。

Error 1: The EC2 instances failed to communicate with AWS Elastic Beanstalk, either because of configuration problems with the VPC or a failed EC2 instance. Check your VPC configuration and try launching the environment again.

我已经设置了仅包含 public 子网和允许所有入站和出站流量的安全组的 VPC。我知道生产级部署不鼓励这样做,但我降低了查找错误原因的复杂性。

因此,负载均衡器和 EC2 实例位于与互联网网关相连的同一 public 子网内。他们都共享同一个安全组,允许所有流量。

在上述错误之前,我还得到另一个错误说明

Error 2: No ecs task definition (or empty definition file) found in environment

话虽如此,我已将 Dockerrun.aws.json 文件与 beantalk 用于部署的源包内的 .ebextensions 文件夹 捆绑在一起。 在所有这些错误之后,深入研究两个问题:

  1. 我无法理解为什么当我打包包含 containerDefinitions 的 dockerrun.aws.json 文件时出现 No ecs task 错误
  2. 由于没有ecs任务运行,所以实例中没有任何东西运行。这就是 beantalk 和 ELB 无法与实例通信的原因吗? (假设我的public子网和所有流量安全组都没有问题)

问题出在 VPC 上。即使我只有一个 public 子网的简单 VPC,beanstalk 也无法与实例通信,因此无法在实例中部署 ECS 任务定义和 docker 容器。

通过创建两个子网,即 public 和私有子网,并在 public 子网中拥有一个 NAT 实例,它成为私有子网中实例的路由器。使上述设置对我有效,我可以将 ECS 任务定义成功部署到私有子网中的 EC2 实例。

我发现这个问题是因为我遇到了同样的错误。以下是对我在 Beanstalk 上实际部署多容器应用程序有用的步骤:

为了克服 这个特殊的 错误,我使用了 eb CLI 工具。出于某种原因,使用 eb deploy 而不是压缩和上传我自己解决了这个问题。它实际上没有用,但它给了我一个新的错误。

所以,我更改了我的 Dockerrun.aws.json,一种需要更多文档的文件格式,直到我不再收到关于 that.

的错误

然后,我得到了一个更好的错误!

ERROR: [Instance: i-0*********0bb37cf] Command failed on instance. 
Return code: 1 Output: (TRUNCATED)..._api_call
raise ClientError(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when 
calling the GetObject operation: Access Denied
Failed to download authentication credentials [config file name] from [bucket name].
Hook /opt/elasticbeanstalk/hooks/appdeploy/enact/02update-
credentials.sh failed. For more detail, check /var/log/eb-activity.log 
using console or EB CLI.

根据this part of the docs解决这个问题的方法是

  1. 在 IAM 控制台中打开 Roles 页面。

  2. 选择 aws-elasticbeanstalk-ec2-role。

  3. 在“权限”选项卡上的“托管策略”下,选择“附加策略”。

  4. Select 您的应用程序使用的附加服务的托管策略。例如,AmazonS3FullAccessAmazonDynamoDBFullAccess。 (对于我们的问题,S3 一个)

  5. 选择附加策略。

这部分真的很令人兴奋,因为我又遇到了另一个错误:Authentication credentials are not in JSON format as expected. Please generate the credentials using 'docker login'.(请记住,我试着按照 the instructions 如何做到这一点,但是,哦,好吧).原来这是我的问题,我存储在 S3 上的 DockerHub 身份验证文件中的 JSON 格式错误。我将文件重命名为 dockercfg.json 以进行语法检查,似乎 Beanstalk/ECS 可以将 .json 作为名称的一部分,因为这次......有一个不同的错误:CannotPullContainerError: Error: image [DockerHub organization]/[repo name]:latest not found)。嗯,也许有错字?让我们检查一下:

$ docker run -it [DockerHub organization]/[repo name]:latest
Unable to find image '[DockerHub organization]/[repo name]:latest' locally
latest: Pulling from [DockerHub organization]/[repo name]

好的,回购就在那里。所以...我的身份验证不好?是的,事实证明我遵循了 DockerHub 身份验证文档中的一个示例,该示例是您 不应该 做的。您的 dockercfg.json 应该看起来像

{
  "https://index.docker.io/v1/": {
    "auth": "ZWpMQ=Vyd5zOmFsluMTkycN0ZGYmbn=WV2FtaGF2",
    "email": "your@email.com"
  }
}

还有一些错误(卷 sourcePath 必须是绝对路径!这就是 invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed 消息的意思),但它最终部署了。对不起小说;希望对某人有所帮助。