如何在docker中保持已安装卷的所有权一致?

Jua*_*hin 7 docker

我试图理解我在 docker 上看到的一些奇怪的行为。我想运行一个容器,它将缓存的数据从主机写入已安装的卷,稍后我可以将其重新用于容器的未来执行,并且也可以从主机读取数据。

在主机上,我看到我的用户具有用户 id 1000

# This is on the host
$ id
uid=1000(juan-munoz) gid=1000(juan-munoz) groups=1000(juan-munoz)...
Run Code Online (Sandbox Code Playgroud)

我正在运行容器,没有为用户提供任何特殊标志,因此它运行为root

# This is on the container
$ id
uid=0(root) gid=0(root) groups=0(root)
Run Code Online (Sandbox Code Playgroud)

此外,已经有一个用户id=1000

# The image is provided by AWS and apparently it includes a user with this ID
$ id -nu 1000
ec2-user
Run Code Online (Sandbox Code Playgroud)

我已经安装了一个目录-v /some/local/directory:/var/mountedid=1000在本地,该目录由我的用户 ( )拥有:

# On the host
ls -ld /some/local/directory
drwx------ 2 juan-munoz juan-munoz 4.0K Jun 21 16:21 /some/local/directory
Run Code Online (Sandbox Code Playgroud)

在容器中,如果我检查目录,我会发现它当前属于root. 这是我不明白的第一部分。

# ls -ld /var/mounted
drwx------ 2 root root 4096 Jun 22 03:36 /var/mounted
Run Code Online (Sandbox Code Playgroud)

为什么root?我会期望mount用户 ID 会受到尊重。

如果我随后尝试将用户更改为1000,则会发生这种情况:

# Inside the container
$ chown -R 1000:1000 /var/mounted
ls -ld /var/mounted
drwx------ 2 ec2-user 1000 4096 Jun 22 03:36 /var/mounted
Run Code Online (Sandbox Code Playgroud)

这对我来说看起来不错,但是当我这样做时,如果我查看发生的情况,host我会看到以下内容:

# On the host
ls -ld /some/local/directory
drwx------ 2     100999     100999 4.0K Jun 21 20:36 /some/local/directory
Run Code Online (Sandbox Code Playgroud)

所以无论是主机还是容器都有一个混乱的所有者。如果我chown 1000:1000在主机上,容器将其视为root,如果我chown 1000:1000在容器上,主机将其视为100999

我在这里做错了什么?

重现步骤

$ mkdir $HOME/testing
$ docker run -it --name=ubuntu-test --entrypoint="/bin/bash" --rm -v $HOME/testing:$HOME/testing ubuntu:latest

# Inside the container
$ cd /home/myusername/testing
$ touch file.txt
root@b98b7a5445e3:/home/juan-munoz/testing# ls -l
total 0
-rw-r--r-- 1 root root 0 Jun 30 23:52 file.txt

# Outside the container
$ ls -l $HOME/testing
total 0
-rw-r--r-- 1 juan-munoz juan-munoz 0 Jun 30 16:52 file.txt
Run Code Online (Sandbox Code Playgroud)

观察到的行为:

  • 在某些计算机中,从容器外部,该文件由本地用户拥有。在其他情况下,它由 root 用户拥有。

预期行为:

  • 跨计算机保持一致

小智 0

我在安装了 Docker Desktop 的 Ubuntu 22.04 下遇到了同样的问题。卸载 Docker Desktop 并重新安装 Docker Engine 后,事情就会按照我希望的方式进行:在主机和容器之间对已安装目录的所有权保持一致。

这是我的用例:我想启动一个 Ubuntu 20.04 容器并将其用作我的应用程序的编译环境。Dockerfile 是:

FROM ubuntu:20.04
ARG USER=docker
ARG UID=1000
ARG GID=1000

# create a new user with same UID & PID but no password
RUN groupadd --gid ${GID} ${USER} && \
    useradd --create-home ${USER} --uid=${UID} --gid=${GID} --groups root && \
    passwd --delete ${USER}
# add user to the sudo group and set sudo group to no passoword
RUN apt update && \
    apt install -y sudo && \
    adduser ${USER} sudo && \
    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# prevent tzdata to ask for configuration
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt -y install tzdata
RUN apt install -y build-essential git cmake

# setup default user when enter the container
USER ${UID}:${GID}
WORKDIR /home/${USER}
Run Code Online (Sandbox Code Playgroud)

构建脚本:

FROM ubuntu:20.04
ARG USER=docker
ARG UID=1000
ARG GID=1000

# create a new user with same UID & PID but no password
RUN groupadd --gid ${GID} ${USER} && \
    useradd --create-home ${USER} --uid=${UID} --gid=${GID} --groups root && \
    passwd --delete ${USER}
# add user to the sudo group and set sudo group to no passoword
RUN apt update && \
    apt install -y sudo && \
    adduser ${USER} sudo && \
    echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# prevent tzdata to ask for configuration
RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt -y install tzdata
RUN apt install -y build-essential git cmake

# setup default user when enter the container
USER ${UID}:${GID}
WORKDIR /home/${USER}
Run Code Online (Sandbox Code Playgroud)

由于我使用它作为编译环境,为了方便起见,挂载了整个主目录:

#!/bin/bash
set -e
UID=$(id -u)
GID=$(id -g)
docker build --build-arg USER="$USER" \
    --build-arg UID="$UID" \
    --build-arg GID="$GID" \
    --tag "ubuntu-env" \
    --file ./Dockerfile \
    --progress=plain \
    .
Run Code Online (Sandbox Code Playgroud)

不知何故,安装了 Docker Desktop 后,安装的主目录的所有者始终是 root 而不是主机用户。卸载后,安装的目录现在获得容器中的预期所有者,即主机用户。