【问题标题】:Running non-root Docker within Ubuntu Docker container在 Ubuntu Docker 容器中运行非 root Docker
【发布时间】:2021-04-19 16:12:47
【问题描述】:

我正在尝试在基于 Ubuntu 20.04 的 Docker 容器中运行 Docker 构建。在 Docker 构建发生之前,容器需要作为构建过程的非 root 用户运行。

这是我的 Dockerfile 的一些 sn-ps 以显示我在做什么:

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 然后将用户设置为运行方式,我哪里出错了?

【问题讨论】:

    标签: linux docker ubuntu


    【解决方案1】:

    amd64/ubuntu:20.04 有一个docker 组,组 id 为 103。很可能本地机器的 docker 组的 gid 不是 103(检查getent group docker)。因此,即使 ciuserdocker 组的一部分,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
    

    【讨论】:

    • 谢谢。这正是我所缺少的,我没有考虑容器和主机之间的组 ID(在这种情况下为 WSL2)。
    【解决方案2】:

    在启动容器时,Docker 元数据的一部分是它应该以哪个用户身份运行;你一般不会使用susudo

    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,尽管没有什么能阻止它启动额外的特权容器。)

    【讨论】:

      猜你喜欢
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 1970-01-01
      • 2022-10-04
      • 2015-03-05
      • 1970-01-01
      相关资源
      最近更新 更多