【问题标题】:How can I run a Docker container in AWS Elastic Beanstalk with non-default run parameters?如何使用非默认运行参数在 AWS Elastic Beanstalk 中运行 Docker 容器?
【发布时间】:2015-03-31 18:57:25
【问题描述】:

我有一个 Docker 容器,它在我的本地开发机器上运行良好。我想将其移至 AWS Elastic Beanstalk,但我遇到了一些麻烦。

我正在尝试使用s3fsS3 存储桶安装到我的容器中。我有 Dockerfile:

FROM tomcat:7.0
MAINTAINER me@example.com

RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential libfuse-dev libcurl4-openssl-dev libxml++2.6-dev libssl-dev mime-support automake libtool wget tar 

# Add the java source
ADD . /path/to/tomcat/webapps/
ADD run_docker.sh /root/run_docker.sh
WORKDIR $CATALINA_HOME

EXPOSE 8080

CMD ["/root/run_docker.sh"]

然后我安装s3fs,挂载S3 存储桶,并在创建映像后运行Tomcat 服务器,方法是运行run_docker.sh

#!/bin/bash
#run_docker.sh

wget https://github.com/s3fs-fuse/s3fs-fuse/archive/master.zip -O /usr/src/master.zip;
cd /usr/src/;
unzip /usr/src/master.zip;
cd /usr/src/s3fs-fuse-master;
autoreconf --install;
CPPFLAGS=-I/usr/include/libxml2/ /usr/src/s3fs-fuse-master/configure;
make;
make install;
cd $CATALINA_HOME;

mkdir /opt/s3-files;
s3fs my-bucket /opt/s3-files;
catalina.sh run

当我使用命令构建和运行这个 Docker 容器时:

docker run --cap-add mknod --cap-add sys_admin --device=/dev/fuse -p 80:8080 -d username/mycontainer:latest

效果很好。然而,当我删除 --cap-add mknod --cap-add sys_admin --device=/dev/fuse 时,s3fs 无法挂载我的 S3 存储桶。

现在,我想在 AWS Elastic Beanstalk 上运行它,当我部署容器(并运行 run_docker.sh)时,所有步骤都可以正常执行,除了run_docker.sh中的步骤s3fs my-bucket /opt/s3-files无法挂载bucket。

这大概是因为无论 Elastic Beanstalk 为运行 Docker 容器做什么,它都不会添加任何额外的标志,例如 --cap-add mknod --cap-add sys_admin --device=/dev/fuse

我的Dockerrun.aws.json 文件如下所示:

{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "tomcat:7.0"
  },
  "Ports": [
    {
      "ContainerPort": "8080"
    }
  ]
}

是否可以向 AWS EB Docker 部署添加额外的 docker run 标志? 另一种选择是找到另一种安装S3 存储桶的方法,但我怀疑无论如何我都会遇到类似的权限错误。有没有人看到任何方法来做到这一点???

更新:

对于尝试使用以下@Egor 答案的人,当EB 配置设置为使用v1.4.0 running Docker 1.6.0 时,它可以工作。超过 v1.4.0 版本的任何内容都会失败。所以要让它工作,像平常一样构建你的环境(这应该会给你一个失败的构建),然后用 v1.4.0 running Docker 1.6.0 配置重建它。应该这样做!

【问题讨论】:

  • 如何使用“1.4.0 running Docker 1.6.0”配置重建环境? EB 控制台似乎没有提供此选项,文档也没有。

标签: linux amazon-web-services amazon-s3 docker amazon-elastic-beanstalk


【解决方案1】:

添加文件.ebextensions/01-commands.config

container_commands:
    00001-docker-privileged: command: 'sed -i "s/docker run -d/docker run --privileged -d/" /opt/elasticbeanstalk/hooks/appdeploy/pre/04run.sh'

我也在用 s3fs

【讨论】:

  • 有趣。 04run.sh 这里是什么?这是否特定于您的环境/设置?还是 docker run 步骤只是 EB 所做的第四步?
  • 这 - 不幸 - 不适合我。我看到04run.sh 已修改并包含--privileged 标志,但日志状态为:fuse: failed to open /dev/fuse: Operation not permitted。有什么想法吗?
  • 小更新。我 ssh 进入 EB 上的主机实例,停止 Docker 容器,将其删除,然后使用 --privileged 标志重新运行它;那行得通。所以看起来sed 命令在04run.sh 运行之前没有被执行。
  • 我遇到了与@Brett 相同的问题,我得到了不允许的操作。有没有这方面的新信息?
【解决方案2】:

如果您使用的是最新版本的 aws docker stack(例如 docker 1.7.1),则需要稍微修改上述答案。试试这个:

commands:
    00001_add_privileged:
        cwd: /tmp
        command: 'sed -i "s/docker run -d/docker run --privileged -d/" /opt/elasticbeanstalk/hooks/appdeploy/enact/00run.sh'

注意运行脚本位置&&名称的变化

【讨论】:

  • 我一直想知道如何做到这一点,太棒了。就我而言,我试图将 args 传递给公共 docker 镜像仓库,所以我使用了 command: 'sed -i "s/\$EB_CONFIG_DOCKER_IMAGE_STAGING/\$EB_CONFIG_DOCKER_IMAGE_STAGING -gzip -enable-url-source/" /opt/elasticbeanstalk/hooks/appdeploy/enact/00run.sh'
  • 太棒了。很高兴它可以提供帮助。
【解决方案3】:

您现在可以使用任务定义添加功能。以下是文档: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

这就是您要添加到任务定义中的具体内容:

"linuxParameters": {
    "capabilities": {
      "add": [
        "SYS_PTRACE"
      ]
    }
  },

【讨论】:

    【解决方案4】:

    感谢 elijahchancey 的回答,这很有帮助。我想补充一点小评论:

    Elasticbeanstalk 现在正在使用 ECS 任务来部署和管理应用程序集群。 Multicontainer Docker Configuration docs 中有一个非常重要的段落(我最初错过了)。

    以下示例显示了常用参数的子集。更多可选参数可用。有关任务定义格式的更多信息和任务定义参数的完整列表,请参阅 Amazon ECS 开发人员指南中的 Amazon ECS Task Definitions

    所以该文档不是完整的参考,但它只是显示典型条目,您应该在其他地方找到更多。这会产生相当大的影响,因为现在(2018 年)您可以指定更多选项,并且不再需要破解 ebextensions。您唯一需要做的就是在您的多泊坞窗Dockerrun.aws.jsoncontainerDefinitions 中使用任务参数。

    这在单个 docker 容器中没有提到,但可以尝试验证...

    带有额外上限的多 docker Dockerrun.aws.json 示例:

    {
      "AWSEBDockerrunVersion": 2,
      "containerDefinitions": [
        {
          "name": "service1",
          "image": "myapp/service1:latest",
          "essential": true,
          "memoryReservation": 128,
          "portMappings": [
            {
              "hostPort": 8080,
              "containerPort": 8080
            }
          ],
          "linuxParameters": {
            "capabilities": {
              "add": [
                "SYS_PTRACE"
              ]
            }
          }
        }
      ]
    }
    

    【讨论】:

      猜你喜欢
      • 2014-09-17
      • 2015-06-29
      • 2020-05-08
      • 2021-11-25
      • 2015-07-12
      • 2017-07-26
      • 2015-06-05
      • 2016-11-28
      • 2018-05-04
      相关资源
      最近更新 更多