Как смонтировать докер-сокет как том в докер-контейнере с правильной группой

Я хочу запустить экземпляр Jenkins в контейнере Docker.

Я хочу, чтобы сама Дженкинс могла раскручивать док-контейнеры в качестве рабов для запуска тестов.

Кажется, лучший способ сделать это - использовать

docker run -v /var/run.docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image

источник

Dockerfile Я использую это

FROM jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt

USER root
RUN apt-get update && apt-get install -y docker.io
RUN usermod -aG docker jenkins
USER jenkins

Если я запускаю сеанс bash в моем работающем контейнере и запускаю docker info на моем изображении я получаю

$ docker info
FATA[0000] Get http:///var/run/docker.sock/v1.18/info: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS?

И если я запускаю сессию Bash от имени пользователя root

docker exec -u 0 -ti cocky_mccarthy bash
root@5dbd0efad2b0:/# docker info
Containers: 42
Images: 50
...

Так что я думаю, docker группа, к которой я добавляю пользователя Jenkins - это группа для внутреннего докера, поэтому сокет не читается без sudo, Это своего рода проблема, поскольку плагин док-станции Jenkins и т. Д. Не настроены для использования sudo,

Как я могу смонтировать сокет, чтобы его можно было использовать из образа без sudo ?

2 ответа

Немного поздно, но это может помочь другим пользователям, которые борются с той же проблемой:

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

Чтобы решить эту проблему, используйте tcp вместо сокета unix, используя опцию -H при запуске механизма Docker. Вы должны быть очень осторожны с этим, поскольку это позволяет любому, кто имеет доступ к этому порту, получить root-доступ к вашей системе.

Более безопасный способ исправить это - убедиться, что docker группа внутри контейнера заканчивается тем же идентификатором группы, что и docker группа вне контейнера. Вы можете сделать это, используя аргументы сборки для вашего docker build:

Dockerfile:

FROM jenkinsci
ARG DOCKER_GROUP_ID

USER root
RUN curl -o /root/docker.tgz https://get.docker.com/builds/Linux/x86_64/docker-1.12.5.tgz && tar -C /root -xvf /root/docker.tgz && mv /root/docker/docker /usr/local/bin/docker && rm -rf /root/docker*
RUN curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
RUN groupadd -g $DOCKER_GROUP_ID docker && gpasswd -a jenkins docker
USER jenkins

И затем строит это, используя

docker build --build-arg DOCKER_GROUP_ID=`getent group docker | cut -d: -f3` -t my-jenkins-image .

После этого вы можете запустить свой образ и получить доступ к докеру как не-root

docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image

Поскольку это решение зависит от предоставления правильного идентификатора группы демону docker при создании образа, этот образ необходимо будет построить на компьютере (ах), где он используется. Если вы создаете образ, нажимаете его, а кто-то другой загружает его на свой компьютер, скорее всего, идентификаторы группы не будут совпадать снова.

Я использовал ваш dockerfile, но сделал небольшое редактирование:

FROM jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt

USER root
RUN apt-get update
RUN groupadd docker && gpasswd -a jenkins docker
USER jenkins

После построения изображения я могу начать его использовать (я на centos7):

docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
     -v $(which docker):/usr/bin/docker:ro \
     -v /lib64/libdevmapper.so.1.02:/usr/lib/x86_64-linux-gnu/libdevmapper.so.1.02 \
     -v /lib64/libudev.so.0:/usr/lib/x86_64-linux-gnu/libudev.so.0 \
     -p 8080:8080 \
     --name jenkins \
     --privileged=true -t -i \
test/jenkins

Вы пытались установить пакет docker.io внутри своего образа. Но этот пакет также находится на вашем хосте (в противном случае на нем нельзя запускать Docker-контейнеры). Поэтому рекомендуется монтировать это в ваш контейнер, а не устанавливать его в файле Docker. Я думаю, что смонтированный /lib64/... специфичен для Centos 7.

$ docker exec -it 9fc27d5fcec1 bash
jenkins@9fc27d5fcec1:/$ whoami 
jenkins
jenkins@9fc27d5fcec1:/$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
9fc27d5fcec1        test                "/bin/tini -- /usr/lo"   6 minutes ago       Up 6 minutes        0.0.0.0:8080->8080/tcp, 50000/tcp   jenkins
Другие вопросы по тегам