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

Posted

技术标签:

【中文标题】是否可以在 Amazon elasticbeanstalk 上启动特权 docker 容器?【英文标题】:Is it possible to launch privileged docker containers on Amazon elasticbeanstalk? 【发布时间】:2016-02-27 09:45:27 【问题描述】:

根据此处的任务定义文档,我尝试了许多不同的方法来在我的任务定义中包含特权标志: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 多容器解决方案堆栈主机上,相同的任务定义节并未证明是成功的。

我在亚马逊论坛上看到了一篇关于弹性beanstalk 支持的~年前帖子:https://forums.aws.amazon.com/thread.jspa?messageID=687694&#687694 其中亚马逊员工“DhanviK@AWS”说:“EB 还没有完全支持 docker 执行的特权模式。我们”在我们继续发布 docker 容器的下一个版本时,我们会将这一点作为反馈考虑在内。”

我还在这里看到了去年 4 月在 github 上的一些旧讨论:https://github.com/awslabs/eb-docker-virtual-hosting/issues/1,他们说 ECS 不支持它。但显然,根据我上面的实验,它已经在这一点上实现了。

那是什么?如果 EB 多容器解决方案堆栈只是包装了 ECS 服务,为什么我的特权标志在从 elasticbeanstalk 传递时不能被 ecs 代理接受? elasticbeanstalk 是否只是在标志到达 ecs 代理之前删除标志?如果是这样,那就太古怪了。任何人都可以对此有所了解吗?

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

【问题讨论】:

【参考方案1】:

事实证明,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。这两个参数与此 hack 是互斥的。

我还将在此处为 Google 员工内嵌它们:

.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/files/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/files/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
    
  ]

【讨论】:

我不知道如何将我们更简单的 Dockerrun 转换为新的 v2 格式:"AWSEBDockerrunVersion":"1","Ports":["ContainerPort":80," ContainerPort":444,"HostPort":444,"ContainerPort":222,"HostPort":222],"Volumes":["HostDirectory":"/mnt/efs/files","ContainerDirectory": "/files"] 但由于没有任何与 Amazon Linux v2 的挂钩,所以它没有实际意义【参考方案2】:

刚刚知道如何解决这个问题,现在Elastic Beanstalk supports running a privileged containers,您只需将"privileged": "true" 添加到您的Dockerrun.aws.json,如下示例(请查看container-1):


  "AWSEBDockerrunVersion": 2,
  "containerDefinitions": [
    "name": "container-0",
    "image": "ubuntu",
    "memory": "512"
  , 
    "name": "container-1",
    "image": "ubuntu",
    "memory": "512",
    "privileged": "true"
  ]

【讨论】:

以上是关于是否可以在 Amazon elasticbeanstalk 上启动特权 docker 容器?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 Amazon Cognito 组来设置对 AW 资源(例如 Amazon DynamoDB 和 Amazon S3)的权限?

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

是否可以从 Amazon Aurora 迁移回 Amazon RDS 中的原生 MySQL?

是否有任何模仿 amazon.com 菜单布局的 jquery 插件

是否可以使用iOS SDK更改Amazon Cognito中的用户名?

是否可以将Amazon-Quicksight与salesforce集成[关闭]