如何为 Docker 主机上的卷挂载点指定 userid 和 groupid

Naj*_*aju 7 permissions containers file-permissions docker docker-volume

我对这个问题感到沮丧有一段时间了,因为这里已经多次询问这个问题,例如在如何处理 Docker 中的持久存储(例如数据库)什么是管理 Docker 共享卷的权限的(最佳)方法?,但答案根本没有解决问题。

第一个“答案”说只使用named volumes而不是传统的bind mounts. 这解决不了任何问题,因为当命名卷安装在主机上时,例如在默认位置/var/lib/docker/volumes/<volume name>/_data,那么该安装点将具有容器内安装点的uid/ 。gid

在 docker 命名卷之前给出的另一个“答案”是使用纯数据容器。这展示了同样的问题。

这对我来说是一个巨大的问题,因为我有很多嵌入式机器,我想在其中运行 docker 主机,并且用户在每台机器上可能有不同的uid/ 。gid因此,我无法在 Dockerfile 中对持久卷的挂载点硬编码uid/来实现匹配。gidid

这是问题的一个示例:假设我的用户foo位于主机上,具有uid 1001gid 1001,并且将文件写入容器内的卷的用户具有uid 1002。当我运行容器时,docker将chown 1002:1002在主机上安装点目录,并用它写入文件uid,我什至无法用我的用户读取/写入文件foo

视觉上(主机上的所有这些操作):

$ docker volume create --driver local --opt type=volume --opt device=/home/<my_host_user>/logs --opt o=bind logs
logs
$ docker volume inspect logs
[
    {
        "CreatedAt": "2020-08-26T16:26:08+01:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/logs/_data",
        "Name": "logs",
        "Options": {
            "device": "/home/<myhostuser>/logs",
            "o": "bind",
            "type": "volume"
        },
        "Scope": "local"
    }
]
Run Code Online (Sandbox Code Playgroud)
$ pwd
/home/foo
$ mkdir logs && ls -ld logs
drwxr-xr-x 2 foo foo 4096 Aug 26 17:24 logs
Run Code Online (Sandbox Code Playgroud)

然后运行容器:

$ docker run --rm --name <cont_name> -it --net="host" --mount src=logs,target=/home/<container_user>/logs <my docker image>
Run Code Online (Sandbox Code Playgroud)

现在是挂载点:

$ ls -ld logs
drwxr-xr-x 2 1002 1002 4096 Aug 26 17:30 logs
$ ls -l logs/
total 4
-rw-r----- 1 1002 1002    0 Aug 26 17:30 log
-rw-r----- 1 1002 1002 2967 Aug 26 17:27 log.1
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,写入该卷的日志有一个uid/ gid,它与主机上存在的内容不对应,并且如果没有 root/sudo 就无法访问它。

那么,有没有什么方法可以让 docker 将容器中的uid/映射到主机上的/ ,或者更简单地使用指定的/作为主机挂载点?giduidgiduidgid

Tom*_*Tom 2

我的环境:

  1. 乌班图22.04
  2. Docker 版本 20.10.17,内部版本 100c701

创建具有适当权限的挂载点路径。

# docker file 
RUN mkdir --parents '$volumeDir' ; chown --recursive '$userName':'$userGroup' '$volumeDir'
Run Code Online (Sandbox Code Playgroud)

接下来,创建容器并挂载卷。

# terminal
docker run --name=containerName --interactive  
--user=$userName:$userGroup --mount='source=volumeName,target==$volumeDir,readonly=false'  
imageName /bin/bash
Run Code Online (Sandbox Code Playgroud)

您将获得适当的许可


归档时间:

查看次数:

6042 次

最近记录:

3 年,7 月 前