即使在浏览了大量材料和 SO 答案之后,我仍然不清楚 docker uid/用户的使用或实现。
我理解以下几点:
- 映像的实例称为容器。
- uid/gid 由底层内核维护,而不是由容器维护。
- 内核理解 uid/gid 数字而不是用户名/组名,名称是别名,仅供人类阅读。
- 所有容器都是由 docker 守护程序维护的进程,在主机中将作为进程可见 (ps -ef)
- root (id = 0) 是容器中的默认用户,可以通过 Dockerfile 中的 USER 指令或在 docker run 中传递 -u 标志来更改
综上所述,当我的 Dockerfile 中有以下命令时,我假设将使用递增的 uid 创建一个新用户 (my-user
)。
RUN addgroup my-group && adduser -D my-user -G my-group
如果我多次运行同一映像(即多个容器)会发生什么情况?是否会为所有流程分配相同的
uid
?如果我在另一个映像中添加相同的上述命令并将该映像作为容器运行,会发生什么情况? - 我会得到新的
uid
或与以前的相同的uid
吗?容器中与主机相关的
uid
增量如何发生。
任何指针都会有所帮助。
如果没有用户命名空间重新映射,只有两件事很重要:
- 数字用户 ID 是什么;以及
/etc/passwd
文件中的内容。
请记住,每个容器和主机都有单独的文件系统,因此每个容器和主机都可以具有单独的/etc/passwd
文件。
如果我多次运行同一映像(即多个容器)会发生什么情况?是否会将相同的 uid 分配给所有进程?
是的,因为每个容器都会从映像中获取同一/etc/passwd
文件的副本。
如果我在另一个映像中添加相同的上述命令并将该映像作为容器运行,会发生什么情况? - 我会得到新的 uid 还是与以前的 uid 相同的 uid?
这取决于adduser
实际做什么;它可以是相同的,也可能是不同的。
uid 增量在容器中与主机的关系如何发生。
他们是完全独立的。
另请记住,您可以docker push
/docker pull
构建的映像以在不同的主机上运行它。 这将带来映像的/etc/passwd
文件,但主机环境可能完全不同。 相应地,尝试在 Dockerfile 中匹配某些特定主机的 uid 映射不是最佳做法,因为如果您尝试在其他任何地方运行相同的映像,则会出错。
当您尝试在RUN
语句中添加用户时,它不会在主机上创建用户。如果在启动容器时未在 Dockerfile 中使用USER
语句或-u
标志指定用户(假设父 Dockerfile 也不包含 USER 语句),则主机上的容器进程将简单地以用户身份运行(如果您以 root 身份启动 docker 守护程序root
则主机上的容器进程将简单地以用户身份运行。
因此,如果您使用RUN addgroup my-group && adduser -D my-user -G my-group
创建用户,它将简单地在容器中创建一个用户,即该用户是容器的本地用户。因此,您运行的该映像的每个实例(容器)都将具有容器内用户的相同 uid。注意:主机上将不存在该用户。
如果要以其他用户(存在于主机上)身份在主机上运行容器进程,则有 3 个选项:
- 在 Dockerfile 中添加
USER
语句 - 运行容器时使用
-u
标志 - 您可以使用 docker 的用户命名空间功能
我强烈建议通过阅读此文档来了解用户命名空间和映射:使用用户命名空间隔离容器