Как подключить гнездо док-станции в качестве тома в контейнере докера с правильной группой
Я хочу запустить экземпляр Jenkins в контейнере докеров.
Я хочу, чтобы сам Дженкинс мог разворачивать контейнеры докеров в качестве ведомых для запуска тестов.
Кажется, лучший способ сделать это - использовать
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
[email protected]:/# docker info
Containers: 42
Images: 50
...
Итак, я думаю, что группа docker
, в которую я добавляю пользователя jenkins, является группой для внутреннего докера, поэтому сокет не читается без sudo. Такая проблема, как плагин docker jenkins и т.д., Не настроена для использования sudo.
Как смонтировать сокет, чтобы его можно было использовать из образа без sudo?
Ответы
Ответ 1
Немного поздно, но это может помочь другим пользователям, которые борются с одной и той же проблемой:
Проблема заключается в том, что группа 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
Поскольку это решение зависит от предоставления правильного идентификатора группы демонам докеров при создании изображения, это изображение должно быть построено на машине (машинах), где она используется. Если вы создадите изображение, нажмите его, а кто-то другой потянет его на свою машину, скорее всего, идентификатор группы больше не будет соответствовать.
Ответ 2
Я использовал ваш файл docker, но сделал небольшое редактирование:
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 внутри своего изображения. Но этот пакет также находится на вашем хосте (иначе он не может запускать на нем контейнеры докеров). Поэтому рекомендуется установить это в ваш контейнер вместо установки его в файл докера.
Я думаю, что mount/lib64/... специфичен для Centos 7.
$ docker exec -it 9fc27d5fcec1 bash
[email protected]:/$ whoami
jenkins
[email protected]:/$ 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