Получение конвейера Jenkins для использования контейнеров Docker для агентов Jenkins и для сборок, совместно использующих локальный репозиторий Maven, является непростым делом, поскольку необходимо решить две проблемы: предоставить общий доступ к файлам локального репозитория и убедиться, что файлы имеют доступные разрешения .
Я создал Docker Volume для хранения общих файлов:
docker volume create maven-cache
Затем велел Дженкинсу смонтировать этот том Docker в подходящем месте для каждого агента, передав ему параметр --mount
для своей команды docker run
. Это делает том Docker доступным ... но принадлежит root
, а не jenkins
пользователю, работающему с Агентом.
Сложность в устранении этой проблемы с разрешениями заключается в том, что Jenkins docker run
изменит ваше изображение, используя UID Jenkins, и вы не можете знать, каким будет этот UID. Как и Я уже отмечал в другом месте , вы можете обойти это, используя магию сценариев оболочки и команды RUN, чтобы установить jenkins
имя пользователя (и docker
имя группы, если необходимо) для вашего образа агента .
Вы можете решить проблему с разрешениями, добавив sudo
к своему образу Docker и сконфигурировав образ, чтобы пользователь jenkins
мог запускать команды sudo
без пароля. Затем на раннем этапе конвейера Jenkins можно использовать sudo
для создания подходящего каталога для локального хранилища в рамках общего монтирования и изменить владельца этого каталога на jenkins
.
Наконец, вы можете настроить файл настроек Maven для использования агентом Jenkins, который говорит Maven использовать общий локальный репозиторий.
Мой Jenkinsfile
выглядит так:
pipeline {
agent {
dockerfile {
filename 'Dockerfile.jenkinsAgent'
additionalBuildArgs '--build-arg JENKINSUID=`id -u jenkins` --build-arg JENKINSGID=`id -g jenkins` --build-arg DOCKERGID=`stat -c %g /var/run/docker.sock`'
args '-v /var/run/docker.sock:/var/run/docker.sock --mount type=volume,source=maven-cache,destination=/var/cache/maven -u jenkins:docker'
}
}
stages {
...
stage('Prepare') {
steps {
sh '[ -d /var/cache/maven/jenkins ] || sudo -n mkdir /var/cache/maven/jenkins'
sh 'sudo -n chown jenkins /var/cache/maven/jenkins'
...
sh 'mvn -B -s maven-jenkins-settings.xml clean'
}
}
И последующие шаги с использованием Maven также говорят mvn -B -s maven-jenkins-settings.xml ...
.
Мой Dockerfile.jenkinsAgent
выглядит так:
FROM debian:stretch-backports
ARG JENKINSUID
ARG JENKINSGID
ARG DOCKERGID
# Add Docker CE
RUN apt-get -y update && \
apt-get -y install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
software-properties-common
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
RUN add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
RUN apt-get -y update && \
apt-get -y install \
docker-ce \
docker-ce-cli \
containerd.io
# Add the build and test tools and libraries
RUN apt-get -y install \
... \
maven \
sudo \
...
# Set up the named users and groups
# Installing docker-ce will already have added a "docker" group,
# but perhaps with the wrong ID.
RUN groupadd -g ${JENKINSGID} jenkins
RUN groupmod -g ${DOCKERGID} docker
RUN useradd -c "Jenkins user" -g ${JENKINSGID} -G ${DOCKERGID} -M -N -u ${JENKINSUID} jenkins
# Allow the build agent to run root commands if it *really* wants to:
RUN echo "jenkins ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
(Если ваш конвейер Jenkins сам по себе не запускает команды Docker, вы можете удалить команды RUN для установки Docker, но тогда вам потребуется groupadd
группа docker
вместо groupmod
)
И файл настроек Maven для агента Jenkins (maven-jenkins-settings.xml
) выглядит так:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>/var/cache/maven/jenkins</localRepository>
<interactiveMode>false</interactiveMode>
</settings>