我使用Docker已经有一段时间了,在处理持久数据时不断发现同样的问题。
我创建Dockerfile并公开一个卷或使用——volumes-from在容器中挂载一个主机文件夹。
主机上的共享卷需要申请哪些权限?
我可以想到两个选择:
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.
还有其他选择吗?
你们是如何处理这个问题的?
In my specific case, I was trying to build my node package with the node docker image so that I wouldn't have to install npm on the deployment server. It worked well until, outside out the container and on the host machine, I tried to move a file into the node_modules directory that the node docker image had created, to which I was denied permissions because it was owned by root. I realized that I could work around this by copying the directory out of the container onto the host machine. Via docker docs...
的UID:GID创建复制到本地计算机的文件
调用docker cp命令的用户。
这是我用来更改docker容器中创建的目录的所有权的bash代码。
NODE_IMAGE=node_builder
docker run -v $(pwd)/build:/build -w="/build" --name $NODE_IMAGE node:6-slim npm i --production
# node_modules is owned by root, so we need to copy it out
docker cp $NODE_IMAGE:/build/node_modules build/lambda
# you might have issues trying to remove the directory "node_modules" within the shared volume "build", because it is owned by root, so remove the image and its volumes
docker rm -vf $NODE_IMAGE || true
如果需要,您可以使用第二个docker容器删除该目录。
docker run -v $(pwd)/build:/build -w="/build" --name $RMR_IMAGE node:6-slim rm -r node_modules
要在docker主机和docker容器之间共享文件夹,请尝试以下命令
$(pwd):$(pwd)-i -t ubuntu
-v标志将当前工作目录挂载到容器中。当绑定挂载卷的主机目录不存在时,Docker会自动在主机上为你创建这个目录,
然而,这里有两个问题:
如果您不是root用户,则无法对挂载的卷进行写操作,因为共享文件将由主机中的其他用户拥有。
你不应该以root用户在容器中运行进程,但即使你以硬编码用户运行,它仍然不会与你笔记本电脑上的用户匹配。
解决方案:
容器:
创建一个用户testuser,默认用户id从1000开始,
主持人:
创建一个名为“testgroup”的组,组id为1000,并将目录更改为新组(testgroup . testgroup . testgroup)
在大多数情况下,这可能不是最好的方法,但它还没有被提及,所以也许它会帮助到某些人。
绑定挂载主机卷
主机文件夹FOOBAR挂载在容器/卷/FOOBAR中
修改容器的启动脚本,以找到感兴趣的卷的GID
$ TARGET_GID=$(stat -c "%g" /volume/FOOBAR)
确保您的用户属于一个具有此GID的组(您可能必须创建一个新组)。对于本例,我将假装我的软件在容器内以nobody用户运行,因此我希望确保没有人属于组id等于TARGET_GID的组
EXISTS=$(cat /etc/group | grep $TARGET_GID | wc -l)
# Create new group using target GID and add nobody user
if [ $EXISTS == "0" ]; then
groupadd -g $TARGET_GID tempgroup
usermod -a -G tempgroup nobody
else
# GID exists, find group name and add
GROUP=$(getent group $TARGET_GID | cut -d: -f1)
usermod -a -G $GROUP nobody
fi
我喜欢这样做是因为我可以轻松地修改主机卷上的组权限,并且知道这些更新的权限适用于docker容器内部。这种情况无需对我的主机文件夹/文件进行任何权限或所有权修改,这让我很高兴。
我不喜欢这种方法,因为它假定将自己添加到容器内的任意组(碰巧使用您想要的GID)中没有危险。它不能与Dockerfile中的USER子句一起使用(除非该用户具有根权限)。此外,它是一种黑客工作;-)
如果你想要硬核,你显然可以在许多方面扩展它——例如,搜索任何子文件上的所有组,多个卷,等等。