Как мне дать некорневому пользователю доступ к докеру при использовании docker-dind?

Я пытаюсь запустить агент Go CD с помощью docker-dind для автоматической сборки некоторых из моих образов docker.

У меня проблемы с получением пользователя go иметь доступ к демону 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 пользователь может получить доступ к информации о докере, но 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

Что мне нужно добавить в мой Dockerfile, чтобы go пользователь для доступа к демону Docker?

3 ответа

Решение

Когда работает dind контейнер, IE докер в докере, это его общее место для монтирования тома /var/run/docker.sock:/var/run/docker.sock от хозяина в динд-контейнер.

Когда это происходит, PID принадлежит не только пользователю root, но и числовому идентификатору группы с хоста.

Запуск следующего внутри контейнера должен показать вам 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.

Поскольку почти невозможно гарантировать, что у нас будет общий идентификатор группы при первом построении образа, идентификатор группы должен быть назначен во время выполнения, используя вашу docker-entrypoint.sh файл.

Моя личная цель - заставить этого пользователя во время выполнения 'go' для go-агента GO CD, но можно заменить этот подход на jenkins или любого другого пользователя во время выполнения.

Поскольку оба агента dind & go основаны на 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

Если вы выполните exec в контейнере и разместите файл / etc / group, вы должны увидеть следующее:

docker:x:993:go

Это слегка измененная версия ответа @Jack.

я создал docker-entrypoint.shкоторый определит GID и повторно использует группу, если она уже существует. В первую очередь на машинах Docker для Windows сокет Docker использует root. Это потребует runuserв качестве suбудет работать только в том случае, если оболочка пользователя не установлена, для которой в моем случае установлено значение 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 Пользователь, вам необходимо выйти и войти после выполнения вышеуказанной задачи.

Другие вопросы по тегам