【问题标题】:docker container process running as non-root user cannot write to docker volume以非 root 用户身份运行的 docker 容器进程无法写入 docker 卷
【发布时间】:2020-12-28 02:17:36
【问题描述】:

TLDR

  • 每个人都建议容器内的进程永远不要以 root 身份运行
  • kubernetes 除外)似乎没有一个好的 devops/configuration-as-code 方法可以在 docker 卷上设置正确的所有者/权限,因此(非 root)用户无法写入音量

当以non-root 用户身份运行容器进程并且我想写入(cloudstor、aws-ebs)docker 卷时,有什么好的做法。


说来话长

在 docker 容器中(和外部)以 root 身份运行进程被认为是不好的做法(参见例如ref1ref2、...)。这可能会带来安全隐患。

但是当我们开始使用 docker 卷并且非 root 用户尝试写入卷时,麻烦就开始了。我找不到一个干净的解决方案,可以在云基础设施上运行,而无需人工干预。我发现的可行解决方案似乎在某些方面都存在不足(安全性、可维护性……)。

附带说明,我们正在使用cloudstordocker-swarm 上部署aws-ebs 卷。我们希望有一天能迁移到 Kubernetes,但我们还没有 Kubernetes,所以我们尝试为我们的设置找到一种替代解决方案。

考虑的解决方案/变通方法

1。在 docker 镜像中预先创建卷

按照here 的建议,如果docker-compose 创建了一个卷,则会传播图像内目录的权限。

缺点:

  • 如果该卷之前存在,或者如果它是磁盘上的一个文件夹,这将不起作用
  • 如果使用 cloudstor 配置卷,这可能也不起作用,因为它不会是 docker-compose 配置卷(未测试)

2。使用volumes-provisioner

hasnat 创建了一个volumes-provisioner 图像,它可以在真正的容器启动之前设置正确的文件夹权限。

缺点:

  • 需要在 docker 堆栈中添加额外的服务。此服务几乎立即终止(设置权限后)。
  • 真正的容器需要depends_onvolumes_provisioner。重新部署相同的堆栈时(配置更改后),执行顺序无法保证
  • ebs 卷只能挂载在单个 docker 容器上,这会导致很多部署问题

3。使用docker run 更正文件权限

一旦真正的容器在挂载卷的情况下运行(但仍然有错误的权限),我们调用

docker run --rm -u root -v ${MOUNT}:${TARGET} { real_image } chown -R user:group ${TARGET}

缺点:

  • ebs 卷只能安装在一个容器中,因此会产生冲突
  • 该命令只能在 docker-stack 部署后运行(否则该卷尚未配置),因此在真正的容器启动和正确的权限之间会有延迟。这意味着在启动时,真正的容器会发现具有错误权限的卷,因此这只有在服务不断检查权限是否已被更正时才会起作用。

4。启动容器时更改所有权

这意味着:

  • root 用户身份启动进程(否则我们无权更改目录所有者/权限)
  • 更改所有权/权限
  • 切换到non-root用户

缺点:

  • 容器进程以 root 身份运行时仍有(次要?)时间段(安全隐患?)
  • 需要破解官方图像的入口点、覆盖用户、...才能正常工作

5。只需以 root 身份运行

这是最简单的解决方案,但安全性呢?并且每个人都建议这样做?

6。使用 Kubernetes

正如here 建议的那样,使用 kubernetes 我们可以为卷分配组 ID。这似乎在kubernetes documentation for pods 中得到证实。

缺点:

  • (遗憾地)我们还没有使用kubernetes
  • (未测试。)

7。在文件系统上创建具有正确权限的文件夹

确保文件系统上存在具有正确所有者/权限的目录。

缺点

  • 这不是云存储...如果容器切换到另一个节点怎么办?或者如果服务器崩溃? (这就是我们使用cloudstor 的原因,它甚至可以让我们切换可用区)
  • 似乎不是很“配置即代码”

【问题讨论】:

  • 在 k8s 中以 root 身份运行服务是 not recommended。对于docker-compose 环境,我们在不启动服务(docker-compose up --no-start)的情况下创建所有内容,然后设置权限(docker run --rm -it --volumes-from ... --entrypoint chown alpine:3 -R 1000:1000 /data),然后启动服务。对于 k8s,afaik 的常见做法是使用initContainers
  • 你不能将 docker 用户添加到有权访问卷的用户组吗?
  • @clogwog 在容器内运行进程的用户对于每个容器都不同,并且与 docker 用户不同

标签: docker docker-compose file-permissions docker-swarm cloud-storage


【解决方案1】:

我投票支持解决方案 4,以 root 身份更改权限然后以非 root 身份启动您的应用程序没有安全问题。如果您的应用程序中存在安全漏洞,那么无论在启动之前发生了什么,该应用程序都不会以 root 身份运行。您可以在入口点中使用的脚本中执行此操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多