繁体   English   中英

使用 docker-dind 时如何授予非 root 用户访问 docker 的权限?

[英]How do i give a non root user access to docker when using docker-dind?

我正在尝试使用 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 守护进程,我需要将 append 连接到我的 Dockerfile 吗?

当在dind中运行一个dind容器,IE dind ,它通常将容器挂载/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

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

docker:x:993:go

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

我创建了一个docker-entrypoint.sh ,它将确定 GID 并重用该组(如果它已经存在)。 主要是在 Docker 的 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 -- $@

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

sudo groupadd docker
sudo usermod -aG docker go

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM