我正在尝试在基于 Ubuntu 20.04 的 Docker 容器中运行 Docker 构建。在 Docker 构建发生之前,容器需要以非 root 用户身份运行以进行构建过程。
以下是我的 Dockerfile 的一些片段,用于展示我在做什么:
FROM amd64/ubuntu:20.04
# Install required packages
RUN apt-get update && apt-get install -y software-properties-common
build-essential \
libssl-dev \
openssl \
libsqlite3-dev \
libtool \
wget \
autoconf \
automake \
git \
make \
pkg-config \
cmake \
doxygen \
graphviz \
docker.io
# Add user for CI purposes
RUN useradd -ms /bin/bash ciuser
RUN passwd -d ciuser
# Set docker group membership
RUN usermod -aG docker ciuser
# Run bash as the non-root user
CMD ["su", "-", "ciuser", "/bin/bash"]
当我运行容器并尝试运行 docker 命令时,出现错误:
$ docker run -ti --privileged=true -v /var/run/docker.sock:/var/run/docker.sock ci_container_staging
ciuser@0bb768506106:~$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied
如果我删除运行为 ciuser
它工作正常:
$ docker run -ti --privileged=true -v /var/run/docker.sock:/var/run/docker.sock /ci_container_staging
root@d71654581cec:/# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d71654581cec ci_container_staging "/bin/bash" 3 seconds ago Up 2 seconds vigilant_lalande
root@d71654581cec:/#
通过 Dockerfile 设置 Docker 然后将用户设置为运行身份,我哪里出错了?
答案 0 :(得分:1)
amd64/ubuntu:20.04
有一个 docker
组,组 ID 为 103。很可能本地机器的 docker 组的 gid 不是 103(检查 getent group docker
)。因此,即使 ciuser
是 docker
组的一部分,id 是不同的,因此用户没有被授予访问 docker 套接字的权限。
一个简单的解决方法是更改容器中 docker
组的 gid 以匹配您的主机:
RUN groupmod -g <HOST_DOCKER_GROUP_ID> docker
有很多其他方法可以解决将 uid/gid 映射到 docker 容器的问题,但这应该可以为您提供足够的信息以继续前进。
示例/更多信息:
# gid on docker socket is 998
root@c349e1d13b76:/# ls -al /var/run/docker.sock
srw-rw---- 1 root 998 0 Apr 12 14:54 /var/run/docker.sock
# But gid of docker group is 103
root@c349e1d13b76:/# getent group docker
docker:x:103:ciuser
# root can `docker ps`
root@c349e1d13b76:/# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c349e1d13b76 nonroot:latest "/bin/bash" About a minute ago Up About a minute kind_satoshi
# but fails for ciuser
root@c349e1d13b76:/# runuser -l ciuser -c 'docker ps'
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json: dial unix /var/run/docker.sock: connect: permission denied
# change docker gid in the container to match the one on the socket/localhost
# 998 is the docker gid on my machine, yours may (will) be different.
root@c349e1d13b76:/# groupmod -g 998 docker
# run `docker ps` again as ciuser, works.
root@c349e1d13b76:/# runuser -l ciuser -c 'docker ps'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c349e1d13b76 nonroot:latest "/bin/bash" About a minute ago Up About a minute kind_satoshi
答案 1 :(得分:0)
Docker 启动容器时的部分元数据是它应该以哪个用户身份运行;您通常不会使用 su
或 sudo
。
USER ciuser
CMD ["/bin/bash"] # or the actual thing the container should do
这很重要,因为您可以在容器启动时使用 docker run -u
选项覆盖用户;或者你可以docker run --group-add
额外的组。这些通常应该是数字组 ID,并且它们不需要存在于容器的 /etc/passwd
或 /etc/group
文件中。
如果主机的 Docker 套接字是模式 0660 并且由 docker
组拥有,您可以look up the corresponding group ID 并指定容器进程具有该组 ID:
docker run \
--group-add $(getent group docker | cut -d: -f3) \
-v /var/run/docker.sock:/var/run/docker.sock \
--rm \
ci_container_staging \
docker ps
(容器并不特别需要是 --privileged
,但没有什么可以阻止它启动额外的特权容器。)