当前位置: 首页 > 知识库问答 >
问题:

管理Docker共享卷权限的(最佳)方法是什么?

封永嘉
2023-03-14

我使用Docker已经有一段时间了,并且在处理持久数据时不断发现相同的问题。

我创建DockerFile并公开卷,或者使用--Volumes-From在容器中装入主机文件夹。

我应该对主机上的共享卷应用什么权限?

我能想到两个选择:

>

  • 到目前为止,我已经为每个人提供了读/写访问权限,因此我可以从Docker容器写入文件夹。

    将用户从主机映射到容器中,这样我就可以分配更多的粒度权限。不确定这是可能的,但还没有找到很多关于它。到目前为止,我所能做的只是以某个用户的身份运行容器:docker run-i-t-user=“MyUser”postgres,但是这个用户的UID与我的主机MyUser不同,所以权限不起作用。此外,我不确定映射用户是否会带来一些安全风险。

    还有其他选择吗?

    你们是怎么处理这个问题的?

  • 共有1个答案

    郎永福
    2023-03-14

    更新2016-03-02:从Docker 1.9.0开始,Docker已经命名了卷,取代了仅数据容器。下面的答案,以及我链接的博客文章,在如何思考docker内部的数据的意义上仍然有价值,但是考虑使用命名卷来实现下面描述的模式,而不是数据容器。

    我相信解决这一问题的规范方法是使用仅有数据的容器。使用这种方法,对卷数据的所有访问都是通过使用-volumes-from数据容器的容器进行的,因此主机UID/GID并不重要。

    例如,文档中给出的一个用例是备份数据卷。为此,将使用另一个容器通过tar执行备份,它还使用-volumes-from来装入卷。因此,我认为关键在于:与其考虑如何以适当的权限访问主机上的数据,不如考虑如何通过另一个容器来完成所需的操作--备份、浏览等。容器本身需要使用一致的UID/GID,但它们不需要映射到主机上的任何东西,从而保持可移植性。

    这对我来说也是比较新的,但如果您有一个特定的用例,请随意评论,我会尝试扩展答案。

    更新:对于注释中的给定用例,您可能有一个imagesome/graphite来运行graphite,并有一个imagesome/graphiteData作为数据容器。因此,忽略端口等,imageSome/GraphiteDataDockerFile类似于:

    FROM debian:jessie
    # add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
    RUN groupadd -r graphite \
      && useradd -r -g graphite graphite
    RUN mkdir -p /data/graphite \
      && chown -R graphite:graphite /data/graphite
    VOLUME /data/graphite
    USER graphite
    CMD ["echo", "Data container for graphite"]
    

    生成并创建数据容器:

    docker build -t some/graphitedata Dockerfile
    docker run --name graphitedata some/graphitedata
    
    FROM debian:jessie
    # add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
    RUN groupadd -r graphite \
      && useradd -r -g graphite graphite
    # ... graphite installation ...
    VOLUME /data/graphite
    USER graphite
    CMD ["/bin/graphite"]
    

    其运行方式如下:

    docker run --volumes-from=graphitedata some/graphite
    

    好了,现在我们可以使用正确的用户/组使用石墨容器和关联的仅数据容器(注意,您也可以为数据容器重用some/graphite容器,在运行时重写entrypoing/cmd,但将它们作为单独的映像IMO更清晰)。

    现在,假设您想要编辑数据文件夹中的内容。因此,与其将卷挂载绑定到主机并在那里编辑它,不如创建一个新的容器来完成这项工作。让我们称之为some/graphiteTools。我们还可以创建适当的用户/组,就像some/graphite图像一样。

    FROM debian:jessie
    # add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
    RUN groupadd -r graphite \
      && useradd -r -g graphite graphite
    VOLUME /data/graphite
    USER graphite
    CMD ["/bin/bash"]
    

    您可以通过继承Dockerfile中的some/graphitesome/graphiteData来解决这个问题,或者不创建新的映像,而是重用现有的映像之一(根据需要重写entrypoint/cmd)。

    现在,您只需运行:

    docker run -ti --rm --volumes-from=graphitedata some/graphitetools
    

    然后vi/data/graphite/whatever.txt。这可以很好地工作,因为所有容器都具有相同的graphite用户,并且具有匹配的UID/GID。

    因为您从不从主机装入/data/graphite,所以您不关心主机UID/GID如何映射到graphitegraphiteTools容器中定义的UID/GID。那些容器现在可以部署到任何主机上,它们将继续完美地工作。

    简单的一点是,graphiteTools可以包含各种有用的实用程序和脚本,您现在也可以以可移植的方式部署这些实用程序和脚本。

    更新2:写完这个答案后,我决定写一篇关于这个方法的更完整的博文。希望有帮助。

    更新3:我修正了这个答案,并添加了更多的细节。它以前包含了一些关于所有权和perms的错误假设--所有权通常在卷创建时分配,即在数据容器中分配,因为那是创建卷的时候。看这个博客。但这不是一个要求--您只需将数据容器用作“引用/句柄”,并通过入口点中的chown在另一个容器中设置所有权/perms,入口点以gosu结尾,以正确的用户身份运行命令。如果有人对这种方法感兴趣,请发表评论,我可以提供使用这种方法的示例链接。

     类似资料:
    • 问题内容: 我已经和Docker玩了一段时间,在处理持久性数据时继续寻找相同的问题。 我创建我的文件并公开一个卷,或使用它[在容器中安装主机文件夹]。 我应该对主机上的共享卷应用什么权限? 我可以想到两种选择: 到目前为止,我已经授予所有人读取/写入访问权限,因此我可以从Docker容器写入该文件夹。 将用户从主机映射到容器,以便我可以分配更多的细化权限。不确定这是否可能,但尚未找到很多相关信息。

    • 我在使用Docker容器时遇到了一个有点烦人的问题(我使用的是Ubuntu,所以没有像VMWare或b2d这样的虚拟化)。我已经构建了我的映像,并且有一个正在运行的容器,其中有一个来自主机的共享(装入)目录和一个来自主机的共享(装入)文件。以下是命令的全文: 注意:许多用于编辑文件的工具,包括vi和sed--in-place可能会导致inode更改。从Docker V1.1.0开始,这将产生一个错

    • 问题内容: 我经常遇到以下情况,其中我需要提供许多不同类型的权限。我主要在SQL Server 2000中使用ASP.NET/VB.NET。 设想 我想提供一个可以在不同参数上工作的动态权限系统。假设我想授予部门或特定人员访问应用程序的权限。并假装我们拥有不断增长的应用程序。 过去,我选择了我知道的以下两种方法之一。 将单个许可权表与特殊列一起使用,这些特殊列用于确定如何应用参数。此示例中的特殊列

    • 问题内容: 当您有多个都使用同一组JAR库的项目时,在每个项目中一遍又一遍地包含相同的JAR太麻烦了。如果我正在从事20个不同的项目,那么我宁愿没有20个完全相同的JAR文件。使所有这些项目(以及新项目)引用同一组JAR的最佳方法是什么? 我有一些想法,但每个想法都有一些缺点: 将所有JAR放在一个文件夹中,并使每个项目都在该文件夹中显示。 使用Eclipse创建一个“用户库”,并使每个项目都引用

    • 问题内容: 我有一个活动,这是整个应用程序中使用的主要活动,它具有许多变量。我还有另外两个活动,我希望能够使用第一个活动中的数据。现在我知道我可以做这样的事情: 但是我想共享很多变量,有些可能很大,所以我不想像上面那样创建它们的副本。 有没有一种方法可以直接获取和更改变量而无需使用get和set方法?我记得在Google开发者网站上读过一篇文章,建议不要在Android上使用此功能。 问题答案:

    • 问题内容: 我必须在 同一台 服务器上(客户端要求)设置“ dockerized”环境(集成,质量保证和生产)。每种环境的组成如下: Rabbitmq 芹菜 花 基于python 3的应用程序,称为“ A”(每个环境的特定分支) 在它们之上,jenkins将处理基于CI的部署。 在每个环境中使用一组容器听起来是最好的方法。 但是现在我需要流程经理来运行和监督所有这些: 3个兔子容器, 3个芹菜/花