我试图理解我在 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/mounted
。id=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)
观察到的行为:
预期行为:
小智 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 而不是主机用户。卸载后,安装的目录现在获得容器中的预期所有者,即主机用户。
归档时间: |
|
查看次数: |
1178 次 |
最近记录: |