Использование команды docker (для размещения) в контейнере docker с пользователем без полномочий root в качестве агента Jenkinsfile - PullRequest
6 голосов
/ 24 октября 2019

Как часть моей сборки, у меня есть контейнер, содержащий инструменты сборки, которые используются для нескольких проектов. Один из моих проектов содержит этап сборки для создания и публикации контейнера, который выполняется из контейнера build-tools. Мой jenkins-slave с поддержкой докера настроен на использование пользователя jenkins, который входит в группу docker. Я использовал -v для монтирования бинарного файла docker и scoket. Это может быть достигнуто / воспроизведено одним из следующих способов:

  • Добавьте пользователя (jenkins) и группу (docker) в Dockerfile инструментов сборки и установите для них UID и GID хостов и GID
  • Запустите контейнер с параметром -u, указав UID и GUID (согласно документации, пользователь и группа не должны существовать в контейнере).

Проблема с первой стратегией заключается в том, чтоID пользователя и группы на разных машинах сборки разные. Я мог бы исправить это, настроив UID и GID всех машин сборки на одинаковые значения, но разве Docker не должен работать изолированно, не имея много зависимостей от среды / контекста? Это не похоже на правильное решение для меня. Вторая стратегия прекрасно работает в командной строке, однако, похоже, нет способа передать UID и GID команде агента в Jenkinsfile. параметр args не поддерживает сценарии или переменные, такие как $(id -u).

Я ожидал, что не буду первым сталкиваться с этой проблемой, однако я не смог найти решение этой проблемы самостоятельно, поискмашины и переполнение стека. Должен ли я пойти с «готовыми» сборочными рабами или есть способ заставить работать вторую стратегию?

.

-edit- Я понимаю варианты запуска контейнера от имени root и переключения после запуска (например, с использованием точки входа). Тем не менее, для этого потребуется, чтобы мой подчиненный Jenkins был подключен как root, что для меня неприемлемо. Другой найденной альтернативой является chmod777 всех ресурсов, который полностью игнорирует аспект безопасности, заключающийся в том, что подчиненный Jenkins не является пользователем root. Я бы предпочел использовать опцию -u для контейнеров, но не могу найти способ определить UID и GID на ведомом устройстве jenkins до запуска агента докера (команда docker run) из Jenkinsfile.

Ответы [ 2 ]

2 голосов
/ 02 ноября 2019

Простое решение

На самом деле, я полагаю, что ваша первая идея решения может быть легко реализована с помощью docker и без необходимости запускать любое ведомое устройство Jenkins от имени root.

Рассмотрим следующую команду:

docker run --rm -it -v /etc/passwd:/etc/passwd:ro -v /etc/shadow:/etc/shadow:ro -v /etc/group:/etc/group:ro debian:10 /bin/su linux-fan -c /bin/bash

Это создает новый контейнер и отображает пользователей с хоста в контейнер. Затем внутри этого контейнера он сразу падает пользователю linux-fan, который (только) должен быть определен во внешней системе.

Независимо от того, запускаете ли вы эту команду как root или как любой пользователь в dockergroup не имеет значения (обратите внимание, что комментарии очень правильны относительно docker group = root-доступ!)

Кроме того, сопоставление вещей внутри контейнера таким образом (уже при этом с помощью сокета Docker .. действительно отказывается от большей части изоляции, которую обеспечивает контейнер. Таким образом, было бы разумно рассмотреть возможность выполнения любой команды, требующей доступа к демону Docker хоста, для запуска непосредственно на хосте или в менее изолированной среде, такой как chroot? Конечно, простота вызова Docker здесь все же может перевесить отсутствие изоляции.

Альтернативное решение

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

0 голосов
/ 06 ноября 2019

Мы успешно используем следующее решение в течение более 6 месяцев:

  • run docker in docker: используйте команду docker из вашего контейнера, а не из хоста, чтобы избежать адской зависимости, гдевам необходимо смонтировать половину вашей хост-системы.
  • убедитесь, что ваш пользователь по умолчанию в вашем контейнере bulid может запустить docker (добавьте jenkins пользователя в группу docker )
  • просто смонтируйте docker.sock с разрешениями для всех: -v /var/run/docker.sock:/var/run/docker.sock:rw
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...