对于上下文:
docker --version
Docker version 20.10.7, build 20.10.7-0ubuntu5~20.04.2
测试 1:音量为/myvolume
这是我的 Dockerfile
FROM alpine:latest
USER 1000:1000
VOLUME /myvolume
以及构建+运行命令:
docker build -t myimage .
docker run --rm -it myimage
然后,进入容器后:
/ $ whoami
whoami: unknown uid 1000
/ $ ls -ld /myvolume/
drwxr-xr-x 2 root root 4096 Mar 8 09:22 /myvolume/
/ $ touch /myvolume/test
touch: /myvolume/test: Permission denied
到目前为止,UID 为 1000 的用户无法写入也就不足为奇了/myvolume
。
测试 2:音量为/tmp
我的 Dockerfile
FROM alpine:latest
USER 1000:1000
VOLUME /tmp
(相同的构建 + 运行命令),并在容器中:
/ $ whoami
whoami: unknown uid 1000
/ $ ls -ld /tmp
drwxrwxrwt 2 root root 4096 Nov 24 09:20 /tmp
/ $ touch /tmp/test
/ $ ls -l /tmp
total 0
-rw-r--r-- 1 1000 1000 0 Mar 8 09:23 test
现在该卷已经变为/tmp
,UID 为 1000 的用户可以对其进行写入。
我知道/tmp
在 GNU/Linux 中通常是全世界可写的,但在这里,这看起来很“神奇”(只有当哈利波特在身边时才可以),我想知道:
a)我不清楚 Docker 和卷的工作原理(请参阅相应的文档/教程)
b) 这是由于我的设置而导致的巧合/缺少某些明确的东西并停止依赖默认值
c)这是一个未记录的功能,可能随时更改,恕不另行通知
d) 这是我找不到相关文档的功能,但我可以放心地相信,当卷附加到时/tmp
,它始终是全球可写的
答案1
摘自 Docker 文档https://docs.docker.com/engine/reference/builder/#volume:
docker run 命令使用基础映像中指定位置存在的任何数据初始化新创建的卷。
看起来,不仅文件和目录被复制到指定位置,而且这些文件的权限和该位置的权限。
考虑以下Dockerfile:
FROM alpine:latest
RUN rm -rf /tmp
USER 1000:1000
VOLUME /tmp
如果您尝试在容器内执行以下命令:
~ $ touch /tmp/test
您将遇到以下错误:
touch: /tmp/test: Permission denied
答案2
那个“魔法”就是所谓的(并且有据可查的)“粘性位“。