如何在 Elastic Beanstalk 应用程序中的 Docker 容器之间共享卷?

Posted

技术标签:

【中文标题】如何在 Elastic Beanstalk 应用程序中的 Docker 容器之间共享卷?【英文标题】:How do you share volumes between Docker containers in an Elastic Beanstalk application? 【发布时间】:2015-09-25 12:20:00 【问题描述】:

我正在尝试在多容器 AWS EC2 实例中运行的两个 Docker 容器之间共享数据。

通常,我会在运行容器时将卷指定为命令标志,即:docker run -p 80:80 -p 443:443 --link Widget:Widget --volumes-from Widget --name nginx1 -d nginx1 将卷从 Widget 共享到 Nginx1。

但是,由于 Elastic Beanstalk 要求您在 dockerrun.aws.json 文件中指定 Docker 配置,然后在内部处理您的 docker 容器的运行,因此我无法弄清楚如何在容器之间共享数据卷。

请注意,我并没有尝试将数据从 EC2 实例共享到 Docker 容器中——这部分似乎工作正常;相反,我想直接从一个 Docker 容器共享数据到另一个容器。我知道 docker 容器卷在 "/var/lib/docker/volumes/fac362...80535" 等处与主机共享,但由于此位置不是静态的,我不知道如何在 dockerrun.aws.json 文件中引用它。

有没有人找到解决方案或变通方法?

有关dockerrun.aws.json 的更多信息以及 EB 在此处寻找的配置:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_docker_v2config.html

谢谢!

【问题讨论】:

我也有同样的问题。希望使用此功能在 rails 容器和 nginx 容器之间共享已编译的资产。 【参考方案1】:

来自the AWS docs 我发现了这个:

您可以在一个容器上定义一个或多个卷,然后使用 不同容器定义中的 volumesFrom 参数(在 相同的任务)将 sourceContainer 中的所有卷安装在 它们最初定义的挂载点。

volumesFrom 参数适用于任务中定义的卷 定义,以及使用 Dockerfile 内置到映像中的那些。

【讨论】:

Kyle,可以进行链接,但挂载后文件夹为空。 ECS服务似乎删除了VOLUME文件夹中的所有数据:( 嗯,是的,我觉得我们可能尝试过 volumesFrom 却没有成功。 我已经单独使用了这种“类型”的安装和 docker 引擎,它就像一个魅力。也许我们在 AWS 论坛上运气不错?或者这可能是预期的行为。 Kyle,我在 AWS 论坛上发布了一个问题。 forums.aws.amazon.com/thread.jspa?messageID=677566#677566 请注意,您不需要“containerDefinitions”旁边的“volumes”部分。文档中的示例实际上会清除数据容器中的卷。只需指定 volumesFrom 就足够了。【参考方案2】:

要完成你想要的,你需要正确使用volumesFrom参数。您需要确保使用VOLUME 命令公开该卷,以便容器共享其内部数据。

这是一个示例 Dockerfile,我用它捆绑了一些静态文件以通过网络服务器提供服务:

FROM tianon/true
COPY build/ /opt/static
VOLUME ["/opt/static"]

现在Dockerrun.aws.json的相关部分:


    "name": "staticfiles",
    "image": "mystaticcontainer",
    "essential": false,
    "memory": "16"
,

    "name": "webserver,
    ...
    "volumesFrom" : [
        
            "sourceContainer": "staticfiles"
        
    ]

请注意,您不需要在 Dockerrun.aws.json 文件的根目录中添加任何 volumes 条目,因为该卷仅在两个容器之间共享,而不会持久保存在主机上。您也不需要容器定义中包含要共享的卷的任何特定的mountPoints 键,因为带有volumesFrom 的容器会自动从引用的容器中获取所有卷。在此示例中,staticfiles 容器中 /opt/static 中的所有文件也可用于同一位置的 webserver 容器。

【讨论】:

这是否意味着静态文件容器应该始终启动并运行?【参考方案3】:

您需要在 Dockerrun.aws.json 文件中指定 dockerVolumeConfiguration。这就是我们如何做到这一点的。这基本上被推送到 ECS。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-volumes.html

这是我的 .json 文件的 sn-p

 "volumes": [
    
      "name": "shared-data",
      "dockerVolumeConfiguration": 
          "scope": "shared",
          "driver": "local",
          "autoprovision": false
      
     
  ],

  "containerDefinitions": [
    
      "name": "api",
      "image": "account.dkr.ecr.us-west-2.amazonaws.com/api:latest",
      "essential": true,
      "memory": 128,
      "portMappings": [
        
          "hostPort": 5000,
          "containerPort": 3050
        
      ],
      "mountPoints": [
        
          "sourceVolume": "shared-data",
          "containerPath": "/var/area_data"
        
      ]
    ,

【讨论】:

以上是关于如何在 Elastic Beanstalk 应用程序中的 Docker 容器之间共享卷?的主要内容,如果未能解决你的问题,请参考以下文章

创建应用程序源包AWS Elastic Beanstalk

如何在 elastic-beanstalk 中应用 ruby​​ 版本补丁

如何设置 Dockerized 应用程序与 Elastic Beanstalk 的持续集成?

如何在 AWS 中为 Elastic Beanstalk 设置应用程序负载均衡器

如何使用 Spring Boot 应用程序登录 Amazon Elastic Beanstalk

如何确保所有实例在 Elastic Beanstalk 应用程序中运行相同的版本?