是否可以在Amazon elasticbeanstalk上启动特权docker容器?

时间:2015-11-24 19:38:33

标签: amazon-web-services amazon-ec2 docker

根据此处的任务定义文档,我尝试了多种不同的方法在我的任务定义中包含特权标志:http://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_security

我还在亚马逊上发现了论坛帖子:https://forums.aws.amazon.com/thread.jspa?threadID=180014&tstart=0&messageID=687696#687696亚马逊员工“ChrisB @ AWS”说“ECS现在支持特权模式。”

我已使用任务定义中的上述特权键/ val在ECS上成功启动了特权容器,并且可以在ec2主机上使用docker命令进行确认。但是,相同的任务定义节在弹性beanstalk多容器解决方案堆栈主机上并不成功。

我在亚马逊论坛上看到一篇专门关于paintbeanstalk支持的文章:https://forums.aws.amazon.com/thread.jspa?messageID=687694&#687694其中亚马逊员工“DhanviK @ AWS”说:“EB还没有干净地支持Docker执行的特权模式。我们将继续发布我们的docker容器的下一个版本作为反馈。“

我也看到了github上4月4日的一些旧讨论:https://github.com/awslabs/eb-docker-virtual-hosting/issues/1他们说ECS不支持它。但很明显,根据我上面的实验,它已经实现了。

那是什么给出的?如果EB multi-conatiner解决方案堆栈简单地包装了ECS服务,那么当从elasticbeanstalk传递时,为什么ecs代理不能接受我的特权标志? elasticbeanstalk是否只是在获得ecs代理之前删除了标志?如果这样那就是怪人。任何人都可以对此有所了解吗?

更新:我发现这个问题与单容器elasticbeanstalk解决方案堆栈有关。这不是我正在使用的。我正在使用多容器解决方案堆栈。 How can I run a Docker container in AWS Elastic Beanstalk with non-default run parameters?

2 个答案:

答案 0 :(得分:8)

事实证明,Elastic Beanstalk只是从任务定义中删除了特权标志。您可以通过将它包含在您在应用程序包中上传到EB的Dockerrun.aws.json文件中进行确认,然后转到aws中的ECS控制面板并查看EB为您的容器群创建的任务定义。特权标志现在将设置为false。这实际上是怪人。

为了解决这个问题,我不得不花费很多时间来组织一个等待部署来启动所有容器的ebextension,然后循环遍历Dockerrun.aws.json并提取任何应该享有特权的容器定义然后一个docker检查这些容器的正在运行的非特权版本,然后使用docker inspect中现有的运行配置停止并重新运行它们,但将特权标志设置回true。 ebextension的文件在这里提供:https://gist.github.com/therealjessesanford/5a012218889831926169

注意:您不能在Dockerrun.aws.json文件的同一容器定义节中使用essential:true和privileged:true。这两个参数与这个黑客互相排斥。

我还会在这里为googlers添加内容:

<强> .ebextensions / 0001_restart_privileged_containers.config

container_commands:
  01-move-restart-hook:
    command: cp -f .ebextensions/files/00_restart_containers_with_privileges.sh /opt/elasticbeanstalk/hooks/appdeploy/post/00_restart_containers_with_privileges.sh && chmod 755 /opt/elasticbeanstalk/hooks/appdeploy/post/00_restart_containers_with_privileges.sh
  02-move-stop-hook:
    command: cp -f .ebextensions/files/02stop_privileged_containers.sh /opt/elasticbeanstalk/hooks/appdeploy/pre/02stop_privileged_containers.sh && chmod 755 /opt/elasticbeanstalk/hooks/appdeploy/pre/02stop_privileged_containers.sh

<强> .ebextensions /文件/ 00_restart_containers_with_privileges.sh

#!/bin/bash

set -ex

. /opt/elasticbeanstalk/hooks/common.sh

EB_CONFIG_APP_STAGING=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
export DOCKERRUN_AWS_JSON=$EB_CONFIG_APP_STAGING/Dockerrun.aws.json

while read -r container_short_name; do
  CURRENT_CONTAINER_ID=$(docker ps --no-trunc -q --filter=name=.$container_short_name)
  CONTAINER_LONG_NAME=$(docker inspect --format='{{.Name}}' $CURRENT_CONTAINER_ID)
  CURRENT_CONFIG=$(docker inspect --format='{{json .Config}}' $CURRENT_CONTAINER_ID)
  NEW_HOST_CONFIG=$(docker inspect --format='"HostConfig":{{json .HostConfig}}' $CURRENT_CONTAINER_ID | sed 's/\"Privileged\":false/\"Privileged\":true/I')
  echo "Stopping unprivileged $CONTAINER_LONG_NAME"
  docker stop $CURRENT_CONTAINER_ID
  docker rm $CURRENT_CONTAINER_ID
  NEW_CONTAINER_ID=$(curl --unix-socket /var/run/docker.sock -X POST -H "Content-Type: application/json" http:/containers/create?name=$CONTAINER_LONG_NAME -d "${CURRENT_CONFIG%?},$NEW_HOST_CONFIG}" | jq -r '.Id')
  echo "Starting privileged $CONTAINER_LONG_NAME"
  docker start $NEW_CONTAINER_ID
  sed -i "s/$CURRENT_CONTAINER_ID/$NEW_CONTAINER_ID/g" /var/lib/ecs/data/ecs_agent_data.json
done <<< "$(jq -r '.containerDefinitions[] | select(.privileged == true) | .name' $DOCKERRUN_AWS_JSON)"

<强> .ebextensions /文件/ 02stop_priviliged_containers.sh

#!/bin/bash

set -ex

. /opt/elasticbeanstalk/hooks/common.sh

EB_CONFIG_APP_CURRENT=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
export DOCKERRUN_AWS_JSON=$EB_CONFIG_APP_CURRENT/Dockerrun.aws.json

while read -r container_short_name; do
  CURRENT_CONTAINER_ID=$(docker ps -q --filter=name=.$container_short_name)
  if [[ ! -z $CURRENT_CONTAINER_ID && "FOOBAR$CURRENT_CONTAINER_ID" != "FOOBAR" ]]; then
    CONTAINER_LONG_NAME=$(docker inspect --format='{{.Name}}' $CURRENT_CONTAINER_ID)
    echo "Stopping unprivileged $CONTAINER_LONG_NAME"
    docker stop $CURRENT_CONTAINER_ID || true
    docker rm $CURRENT_CONTAINER_ID || true
  fi
done <<< "$(jq -r '.containerDefinitions[] | select(.privileged == true) | .name' $DOCKERRUN_AWS_JSON)"

<强> ./ Dockerrun.aws.json

{
  "AWSEBDockerrunVersion": 2,
  "containerDefinitions": [
    {
      "name": "happy_container_name",
      "image": "tutum.co/happy/happy_container",
      "memory": 128,
      "essential": false,
      "privileged": true
    }
  ]
}

答案 1 :(得分:4)

刚刚想出如何解决这个问题,现在Elastic Beanstalk supports running a privileged containers,您需要将"privileged": "true"添加到Dockerrun.aws.json,如以下示例所示(请查看{{1} }}):

container-1