管理Docker共享卷权限的(最佳)方法是什么? [英] What is the (best) way to manage permissions for Docker shared volumes?

查看:97
本文介绍了管理Docker共享卷权限的(最佳)方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经和Docker玩了一段时间了,在处理持久性数据时一直寻找相同的问题。



我创建了 Dockerfile 公开卷或使用-volumes-from 在容器中安装主机文件夹



我应该对主机上的共享卷应用哪些权限?



我可以想到两个选择:




  • 到目前为止,我已经给大家读过/写访问权限,因此我可以从Docker容器中写入文件夹。


  • 将用户从主机映射到容器中,这样我就可以分配更精细的权限。不确定是否可行,但尚未找到很多相关信息。到目前为止,我所能做的就是以某些用户身份运行容器: docker run -i -t -user = myuser postgres ,但是该用户的UID与我的主机 myuser ,因此权限不起作用。另外,我不确定映射用户是否会带来一些安全风险。




还有其他选择吗?



你们如何处理这个问题?

解决方案

UPDATE 2016-03-02 :自Docker 1.9.0起,Docker具有命名卷 替换仅数据容器。下面的答案以及我链接的博客文章,在如何考虑docker内部的数据的意义上仍然有价值,但请考虑使用命名卷而不是数据容器来实现以下所述的模式。 / p>




我相信解决此问题的规范方法是使用仅数据容器。通过这种方法,所有对卷数据的访问都是通过使用 -volumes-from 数据容器的容器进行的,因此主机uid / gid无关紧要。



例如,文档中给出的一个用例正在备份数据量。为此,使用另一个容器通过 tar 进行备份,并且它也按顺序使用 -volumes-from 安装卷。因此,我认为grok的关键点是:与其考虑如何通过适当的权限访问主机上的数据,不如考虑如何通过另一个容器来执行所需的任何操作(备份,浏览等)。 。容器本身需要使用一致的uid / gids,但是它们不需要映射到主机上的任何内容,从而保持可移植性。



对我来说这是相对较新的同样,但是如果您有特定的用例,请随时发表评论,我将尝试扩展答案。



更新:对于在注释中给定的用例中,您可能有一个图像 some / graphite 来运行石墨,以及一个图像 some / graphitedata 作为数据容器。因此,忽略端口等,图像 some / graphitedata Dockerfile 类似于:

  FROM debian:jessie 
#首先添加我们的用户和组,以确保其ID得到一致分配,而不管后来添加的其他dep为何$ b RUN groupadd -r石墨\
&& useradd -r -g石墨石墨
RUN mkdir -p / data / graphite \
&& chown -R石墨:石墨/数据/石墨
体积/数据/石墨
用户石墨
CMD [ echo,石墨的数据容器]

构建并创建数据容器:

  docker build -t some / graphitedata Dockerfile 
docker run --name石墨数据some / graphitedata

some / graphite Dockerfile也应该获得相同的uid / gids,因此可能看起来像这样:

  FROM debian:jessie 
#首先添加我们的用户和组,以确保其ID得到一致分配,而不管后来添加的其他deps是什么。
RUN groupadd -r石墨b
&& useradd -r -g石墨石墨
#...石墨安装...
体积/ data / graphite
用户石墨
CMD [ / bin / graphite]

运行如下:

  docker run --volumes-from = graphitedata一些/石墨

好的,现在,我们为石墨容器和关联的仅数据容器提供了正确的用户/组(请注意,您可以将 some / graphite 容器重新用于数据容器同样,在运行时覆盖entrypoing / cmd,但将它们作为单独的图像IMO会更清晰。)



现在,假设您要编辑数据中的内容夹。因此,与其将卷绑定到主机上并在其上进行编辑,不如创建一个新容器来完成该工作。我们称之为 some / graphitetools 。让我们还创建适当的用户/组,就像 some / graphite 图片一样。

  FROM debian:jessie 
#首先添加我们的用户和组,以确保其ID得到一致分配,而不管以后是否添加了其他部门
RUN groupadd -r石墨\
& ;& useradd -r -g石墨石墨
VOLUME / data / graphite
用户石墨
CMD [ / bin / bash]

您可以通过从 some / graphite some / graphitedata继承来进行此DRY code>而不是创建新映像,而只是重用现有映像之一(必要时覆盖入口点/ cmd)。



现在,您只需运行:

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

然后是 vi /data/graphite/whatever.txt 。之所以如此行之有效,是因为所有容器的石墨用户都具有相同的uid / gid。



因为您从未安装过 / data / graphite 从主机,您不在乎主机uid / gid如何映射到 graphite graphitetools中定义的uid / gid 容器。这些容器现在可以部署到任何主机,并且它们将继续正常运行。



关于这一点的简洁之处是 graphitetools 可能具有各种有用的实用程序和脚本,您现在也可以以可移植的方式进行部署。



UPDATE 2 :写下此答案后,我决定撰写有关以下内容的更完整的博客文章这种方法。希望对您有所帮助。



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


I've been playing around with Docker for a while and keep on finding the same issue when dealing with persistent data.

I create my Dockerfile and expose a volume or use --volumes-from to mount a host folder inside my container.

What permissions should I apply to the shared volume on the host?

I can think of two options:

  • So far I've given everyone read/write access, so I can write to the folder from the Docker container.

  • Map the users from host into the container, so I can assign more granular permissions. Not sure this is possible though and haven't found much about it. So far, all I can do is run the container as some user: docker run -i -t -user="myuser" postgres, but this user has a different UID than my host myuser, so permissions do not work. Also, I'm unsure if mapping the users will pose some security risks.

Are there other alternatives?

How are you guys/gals dealing with this issue?

解决方案

UPDATE 2016-03-02: As of Docker 1.9.0, Docker has named volumes which replace data-only containers. The answer below, as well as my linked blog post, still has value in the sense of how to think about data inside docker but consider using named volumes to implement the pattern described below rather than data containers.


I believe the canonical way to solve this is by using data-only containers. With this approach, all access to the volume data is via containers that use -volumes-from the data container, so the host uid/gid doesn't matter.

For example, one use case given in the documentation is backing up a data volume. To do this another container is used to do the backup via tar, and it too uses -volumes-from in order to mount the volume. So I think the key point to grok is: rather than thinking about how to get access to the data on the host with the proper permissions, think about how to do whatever you need -- backups, browsing, etc. -- via another container. The containers themselves need to use consistent uid/gids, but they don't need to map to anything on the host, thereby remaining portable.

This is relatively new for me as well but if you have a particular use case feel free to comment and I'll try to expand on the answer.

UPDATE: For the given use case in the comments, you might have an image some/graphite to run graphite, and an image some/graphitedata as the data container. So, ignoring ports and such, the Dockerfile of image some/graphitedata is something like:

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"]

Build and create the data container:

docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata

The some/graphite Dockerfile should also get the same uid/gids, therefore it might look something like this:

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"]

And it would be run as follows:

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

Ok, now that gives us our graphite container and associated data-only container with the correct user/group (note you could re-use the some/graphite container for the data container as well, overriding the entrypoing/cmd when running it, but having them as separate images IMO is clearer).

Now, lets say you want to edit something in the data folder. So rather than bind mounting the volume to the host and editing it there, create a new container to do that job. Lets call it some/graphitetools. Lets also create the appropriate user/group, just like the some/graphite image.

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"]

You could make this DRY by inheriting from some/graphite or some/graphitedata in the Dockerfile, or instead of creating a new image just re-use one of the existing ones (overriding entrypoint/cmd as necessary).

Now, you simply run:

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

and then vi /data/graphite/whatever.txt. This works perfectly because all the containers have the same graphite user with matching uid/gid.

Since you never mount /data/graphite from the host, you don't care how the host uid/gid maps to the uid/gid defined inside the graphite and graphitetools containers. Those containers can now be deployed to any host, and they will continue to work perfectly.

The neat thing about this is that graphitetools could have all sorts of useful utilities and scripts, that you can now also deploy in a portable manner.

UPDATE 2: After writing this answer, I decided to write a more complete blog post about this approach. I hope it helps.

UPDATE 3: I corrected this answer and added more specifics. It previously contained some incorrect assumptions about ownership and perms -- the ownership is usually assigned at volume creation time i.e. in the data container, because that is when the volume is created. See this blog. This is not a requirement though -- you can just use the data container as a "reference/handle" and set the ownership/perms in another container via chown in an entrypoint, which ends with gosu to run the command as the correct user. If anyone is interested in this approach, please comment and I can provide links to a sample using this approach.

这篇关于管理Docker共享卷权限的(最佳)方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆