【问题标题】:How do i give a non root user access to docker when using docker-dind?使用 docker-dind 时如何让非 root 用户访问 docker?
【发布时间】:2022-03-04 11:09:50
【问题描述】:

我正在尝试使用 docker-dind 运行 Go CD 代理来自动构建我的一些 docker 映像。

我无法让用户 go 访问 docker 守护程序。

当我尝试访问 docker 信息时,我得到以下信息:

[go] Task: /bin/sh ./builder.shtook: 2.820s
[START]
[USER]  go
[TAG]  manual

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.32/containers/fish/angular-cli/json: dial unix /var/run/docker.sock: connect: permission denied
Sending build context to Docker daemon  3.072kB

Step 1/8 : FROM node:8-alpine
 ---> 4db2697ce114
Step 2/8 : MAINTAINER jack@fish.com
 ---> Using cache
 ---> 22f46bf6b4c1
Step 3/8 : VOLUME /usr/local/share/.cache/yarn/v1
 ---> Using cache
 ---> 86b979e7a2b4
Step 4/8 : RUN apk add --no-cache --update build-base python
 ---> Using cache
 ---> 4a08b0a1fc9d
Step 5/8 : RUN yarn global add @angular/cli@1.5.3
 ---> Using cache
 ---> 6fe4530181a5
Step 6/8 : EXPOSE 4200
 ---> Using cache
 ---> 480edc47696e
Step 7/8 : COPY ./docker-entrypoint.sh /
 ---> Using cache
 ---> 329f9eaa5c76
Step 8/8 : ENTRYPOINT /docker-entrypoint.sh
 ---> Using cache
 ---> cb1180ff8e9f
Successfully built cb1180ff8e9f
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.32/containers/fish/angular-cli/json: dial unix /var/run/docker.sock: connect: permission denied

我的root用户可以正常访问docker信息,但go用户失败。

$ cat /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
....
adm:x:4:root,adm,daemon
wheel:x:10:root
xfs:x:33:xfs
ping:x:999:
nogroup:x:65533:
nobody:x:65534:
dockremap:x:101:dockremap,go
go:x:1000:go

我的docker.sock权限如下:

$ ls -alh /var/run/docker.sock
srw-rw----    1 root     993            0 Apr 20  2017 /var/run/docker.sock

为了允许go 用户访问 docker 守护程序,我需要将什么附加到我的 Dockerfile 中?

【问题讨论】:

    标签: docker go-cd docker-in-docker


    【解决方案1】:

    当运行dind 容器时,即在 docker 中的 IE docker,它的常见位置是将主机上的 /var/run/docker.sock:/var/run/docker.sock 卷挂载到 dind-container 中。

    发生这种情况时,PID 不仅由 root 拥有,而且由来自主机的数字组 id 拥有。

    在容器内运行以下命令应该会显示主机 GID:

    $ ls -alh /var/run/docker.sock
    srw-rw----    1 root     993            0 Apr 20  2017 /var/run/docker.sock
    

    上述进程归组993所有,993派生自主机/etc/group -> docker角色。

    由于在第一次构建映像时几乎不可能确保我们有一个共同的组 ID,因此应该在运行时使用您的 docker-entrypoint.sh 文件分配组 ID。

    我的个人目标是让这个“go”运行时用户成为 GO CD go-agent,但可以用这种方法代替 jenkins 或任何其他运行时用户。

    由于 dind 和 go-agent 都基于 alpine linux,以下将适用于 alpine-linux:

    #setup docker group based on hosts mount gid
    echo "Adding hosts GID to docker system group"
    # this only works if the docker group does not already exist
    DOCKER_SOCKET=/var/run/docker.sock
    DOCKER_GROUP=docker
    BUILD_USER=go
    
    if [ -S ${DOCKER_SOCKET} ]; then
        DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
    
        #addgroup is distribution specific
    
        addgroup -S -g ${DOCKER_GID} ${DOCKER_GROUP}
        addgroup  ${BUILD_USER} ${DOCKER_GROUP}
    fi
    

    如果你执行到容器中,并 cat 你的 /etc/group 文件,你应该会看到以下内容:

    docker:x:993:go
    

    【讨论】:

    • 如果容器以非 root 用户身份运行,这是否可行,因为入口点随后以非 root 权限运行?
    【解决方案2】:

    这是@Jack 答案的略微修改版本。

    我创建了一个docker-entrypoint.sh,它将确定 GID 并重用该组(如果该组已存在)。主要在 Docker for Windows 机器上,Docker 套接字使用root。这将需要runuser,因为su 仅在用户的shell 未设置为nologin(在我的情况下设置为nologin)时才有效

    #!/bin/sh
    set -e
    DOCKER_SOCKET=/var/run/docker.sock
    RUNUSER=jobberuser
    
    if [ -S ${DOCKER_SOCKET} ]; then
        DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
        DOCKER_GROUP=$(getent group ${DOCKER_GID} | awk -F ":" '{ print $1 }')
        if [ $DOCKER_GROUP ]
        then
            addgroup $RUNUSER $DOCKER_GROUP
        else
            addgroup -S -g ${DOCKER_GID} docker
            addgroup $RUNUSER docker
        fi
    fi
    exec runuser -u $RUNUSER -- $@
    

    【讨论】:

      【解决方案3】:

      为了允许其他用户访问 Docker,您需要:

      sudo groupadd docker
      sudo usermod -aG docker go
      

      如果您以go 用户身份运行此命令,则执行上述任务后需要注销并登录。

      【讨论】:

      • 不完全 - 看起来 docker.sock 文件仍归“主机”组 993 所有。如何让组 ID 匹配?
      猜你喜欢
      • 2018-07-06
      • 2017-07-03
      • 2017-01-16
      • 2020-07-01
      • 2021-12-24
      • 2019-04-22
      • 2018-01-13
      • 1970-01-01
      • 2023-03-03
      相关资源
      最近更新 更多