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

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

问题描述



我创建了我的 Dockerfile 公开卷或使用 - 卷 - 从在我的容器内安装一个主机文件夹



我的问题是,应该在主机上共享卷上应该有哪些权限?我可以想到2个选项:




  • 到目前为止,我一直在做的,让大家读/写访问,所以我可以从docker容器写入文件夹


  • 将用户从主机映射到容器中,因此我可以分配更精细的权限。不知道这是可能的,虽然没有发现太多。到目前为止,我可以做的只是运行容器,一些用户: docker运行-i -t -user =myuserpostgres ,但是该用户的UID不同于我的主机 myuser ,所以权限不起作用。另外,我不确定映射用户是否会带来一些安全隐患。




你们如何处理这个问题?

解决方案

更新2016-03-02 :从Docker 1.9.0开始,Docker的命名卷 替换仅数据的容器。下面的答案以及我链接的博客文章仍然有价值在于如何考虑docker中的数据,但是考虑使用命名卷来实现下面描述的模式,而不是数据容器。 / p>




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



例如,文档中给出的一个用例是备份数据卷。要做到这一点,另一个容器用于通过 tar 进行备份,并且它也使用 -volumes-从按顺序装载音量。所以我认为grok的关键是:而不是考虑如何通过适当的权限访问主机上的数据,想想如何做任何你需要的 - 备份,浏览等 - 通过另一个容器。容器本身需要使用一致的uid / gids,但是它们不需要映射到主机上的任何东西,从而保持便携式。



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



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

  FROM debian:jessie 
#首先添加我们的用户和组,以确保他们的ID得到一致的分配,无论稍后添加的其他deps
RUN groupadd -r graphite \
&& useradd -r -g石墨石墨
RUN mkdir -p / data / graphite \
&& cho石墨:石墨/数据/石墨
VOLUME / data / graphite
USER石墨
CMD [echo,石墨数据容器]

构建并创建数据容器:

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

一些/石墨 Dockerfile也应该得到相同的uid / gids,因此它可能看起来像这样:

  FROM debian:jessie 
#先添加我们的用户和组,以确保他们的ID一致地被分配,而不管以后添加的其他deps
RUN groupadd -r graphite \
&&& useradd -r -g石墨石墨
#...石墨安装...
VOLUME / data / graphite
USER石墨
CMD [/ bin / graphite]

它的运行方式如下:

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

好的,现在给我们我们的石墨容器和相关的只有数据的容器带有正确的用户/组(注意你可以重新使用数据容器的 some / graphite 容器以及在运行它时覆盖entrypoing / cmd,但是将它们作为单独的图像IMO更清楚)。



现在,让我们说你想在数据中编辑某个东西夹。因此,不要将卷加载到主机并在其中进行编辑,而是创建一个新的容器来执行该作业。让我们称它为 some / graphitetools 。也可以创建相应的用户/组,就像一些/石墨图像。

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

你可以通过继承 some / graphite some / graphitedata 在Docker文件中,或者不是创建一个新的图像只是重新使用其中一个现有的(必要时覆盖entrypoint / cmd)。



现在,您只需运行:

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

然后 vi /data/graphite/whatever.txt 。这完全是因为所有容器都具有与uid / gid匹配的相同的石墨用户。



由于您从未挂载 / data / graphite 从主机,你不在乎主机uid / gid如何映射到石墨石墨工具之间定义的uid / gid 容器。这些容器现在可以部署到任何主机,并且它们将继续工作得很好。



这个整洁的事情是 graphitetools 可以有各种有用的实用程序和脚本,您现在还可以以便携式方式部署。



更新2 :撰写此答案后,我决定撰写更完整的博文这种方法。我希望它有帮助。



更新3 :我更正了这个答案,并添加了更多细节。它以前包含关于所有权和perms的一些不正确的假设 - 所有权通常在卷创建时分配,即在数据容器中分配,因为这是创建卷时。请参阅此博客。这不是一个要求 - 你可以使用数据容器作为引用/句柄,并通过在entrypoint中的chown将所有权/ perms设置为另一个容器,以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

My question is, what permissions should I apply to the shared volume on the host? I can think of 2 options:

  • What I've been doing so far, give 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.

Any other alternatives?

How are you guys 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天全站免登陆