【问题标题】:How to give non-root user in Docker container access to a volume mounted on the host如何让 Docker 容器中的非 root 用户访问安装在主机上的卷
【发布时间】:2017-01-16 18:38:23
【问题描述】:

我以非 root 用户身份在 Docker 容器中运行我的应用程序。我这样做是因为它是最佳实践之一。但是,在运行容器时,我将主机卷安装到它 -v /some/folder:/some/folder 。我这样做是因为我在 docker 容器中运行的应用程序需要将文件写入挂载的主机文件夹。但由于我以非 root 用户身份运行我的应用程序,它没有写入该文件夹的权限

问题

是否可以让 docker 容器中的非 root 用户访问托管卷?

如果不是,我唯一的选择是在 docker 容器中以 root 身份运行该进程吗?

【问题讨论】:

    标签: security docker


    【解决方案1】:

    这里没有神奇的解决方案:docker 内部的权限管理与没有 docker 的权限相同。您需要运行相应的chownchmod 命令来更改目录的权限。

    一种解决方案是让您的容器以 root 身份运行并使用 ENTRYPOINT 脚本进行适当的权限更改,然后将您的 CMD 作为非特权用户。例如,将以下内容放入entrypoint.sh

    #!/bin/sh
    
    chown -R appuser:appgroup /path/to/volume
    exec runuser -u appuser "$@"
    

    这假设您有可用的runuser 命令。您可以改用sudo 来完成几乎相同的事情。

    通过在 Dockerfile 中包含 ENTRYPOINT 指令来使用上述脚本:

    FROM baseimage
    
    COPY entrypoint.sh /entrypoint.sh
    ENTRYPOINT ["/bin/sh", "entrypoint.sh"]
    CMD ["/usr/bin/myapp"]
    

    这将启动容器:

    /bin/sh entrypoint.sh /usr/bin/myapp
    

    入口点脚本将进行所需的权限更改,然后将/usr/bin/myapp 运行为appuser

    【讨论】:

    • 我认为这可行。为了使这个更通用,有没有办法在运行容器时将/path/to/volume 替换为-v 命令的参数?例如,如果容器使用-v /some/path:/some/path 运行,则entrypoint.sh 中的chown 命令变为chown -R appeaser:appuser /some/path。而不是在 entrypoint.sh 中硬编码卷名
    • 容器内无法检查可用的卷路径,但您可以传入环境变量 (docker run -v /some/path:/some/path -e MYVOLUME=/some/path ...),然后在 ENTRYPOINT 脚本中使用 $MYVOLUME
    • @larsks “让你的容器以 root 身份运行”违背了非 root 容器的目的。
    • @13013SwagR 我不同意。我认为以root 启动您的容器,然后在ENTRYPOINT 脚本中切换到非root 用户可以完全 获得相同级别的安全性。无论哪种情况,您的服务都没有以root 用户身份运行。
    • @larsks - 我必须(礼貌地)不同意你的不同意见。我不是这里的专家,但是快速谷歌出现了(pythonspeed.com/articles/root-capabilities-docker-security 了解详细信息),它解释了为什么以 root 身份启动然后在容器内降级不会提供与您相同级别的安全性'd 通过 Dockerfile 中的 USER 关键字指定非 root 用户。
    【解决方案2】:

    如果主机环境没有appuserappgroup 会抛出错误,所以最好使用用户ID 而不是用户名:

    在您的容器中,运行

    appuser$ id
    

    这将显示:

    uid=1000(appuser) gid=1000(appuser) groups=1000(appuser)

    从主机环境,运行:

    mkdir -p /some/folder
    chown -R 1000:1000 /some/folder
    docker run -v /some/folder:/some/folder [your_container]
    

    在您的容器内,检查

    ls -lh
    

    查看用户和组名,如果不是root,那么应该可以。

    【讨论】:

    • 如果没有安装appuser,有什么办法吗?
    • @bananabrann appuser 不是工具,而是一些用户名,如admin 等,由容器的USER admin 指令决定。
    • 哦,我是笨蛋——我没有区分它是应用程序“用户”而不是新词“应用程序用户”
    【解决方案3】:

    在使用从自定义 Dockerfile 构建的镜像的特定情况下,您可以执行以下操作(使用 debian 镜像的示例命令):

        FROM baseimage
        ...
        RUN useradd --create-home appuser
        USER appuser
        RUN mkdir /home/appuser/my_volume
        ...
    

    然后使用挂载卷

    -v /some/folder:/home/appuser/my_volume
    

    现在appuser 拥有对位于其主目录中的卷的写入权限。如果必须将卷挂载到其主目录之外,您可以创建它并在 Dockerfile 中分配appuser 写入权限作为额外步骤。

    【讨论】:

      猜你喜欢
      • 2020-02-20
      • 2014-10-08
      • 2018-01-13
      • 2019-12-18
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多