使用 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 守护进程,我需要将什么附加到我的 Dockerfile?
为了允许其他用户访问 Docker 您需要:
sudo groupadd docker
sudo usermod -aG docker go
如果您是运行此命令作为go
用户,您需要在执行上述任务后注销并登录。
当 运行 一个 dind
容器,IE docker 在 docker 时,它是从主机将卷挂载 /var/run/docker.sock:/var/run/docker.sock
到 dind 的常见位置-容器。
发生这种情况时,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是从host机器派生/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
这是@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 }')
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-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 您需要:
sudo groupadd docker
sudo usermod -aG docker go
如果您是运行此命令作为go
用户,您需要在执行上述任务后注销并登录。
当 运行 一个 dind
容器,IE docker 在 docker 时,它是从主机将卷挂载 /var/run/docker.sock:/var/run/docker.sock
到 dind 的常见位置-容器。
发生这种情况时,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是从host机器派生/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
这是@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 }')
if [ $DOCKER_GROUP ]
then
addgroup $RUNUSER $DOCKER_GROUP
else
addgroup -S -g ${DOCKER_GID} docker
addgroup $RUNUSER docker
fi
fi
exec runuser -u $RUNUSER -- $@