- PVSM.RU - https://www.pvsm.ru -
На Хабре много статей о Jenkins, но мало где описывается пример работы Jenkins и докер агентов. Все популярные инструменты сборки проектов типа Drone.io [1], Bitbucket Pipeline [2], GitLab [3], GitHub actions [4] и другие, могут собирать все в контейнерах. Но как же Jenkins?
На сегодняшний день есть решение проблемы: Jenkins 2 замечательно умеет работать с Docker агентами [5]. В статье я хочу поделиться опытом и показать, как вы можете это сделать сами.
Так как мы в компании используем множество различных технологий, то на сборочной машине приходится держать разные версии Node.JS, Gradle, Ruby, JDK и прочих. Но зачастую конфликтов версий не избежать. Да, вы будете правы если скажете, что есть различные менеджеры версий типа nvm, rvm, но не всё так гладкос ними и у этих решений есть проблемы:
Есть и другие проблемы, но давайте я лучше расскажу про решение.
Так как сейчас Docker уже хорошо укоренился в сфере разработки, то почти все можно запустить при помощи Docker. Мое же решение в том, чтобы Jenkins был в Docker и мог запускать другие Docker контейнеры. Этим вопросом стали задаваться еще в 2013 году в статье "Docker can now run within Docker [6]".
Если вкратце просто необходимо в рабочий контейнер установить сам Docker и примонтировать файл /var/run/docker.sock
.
Вот пример Dockerfile, который получился для Jenkins.
FROM jenkins/jenkins:lts
USER root
RUN apt-get update &&
apt-get -y install apt-transport-https
ca-certificates
curl
gnupg2
git
software-properties-common &&
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey &&
add-apt-repository
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")
$(lsb_release -cs)
stable" &&
apt-get update &&
apt-get -y install docker-ce &&
usermod -aG docker jenkins
RUN curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
RUN apt-get clean autoclean && apt-get autoremove —yes && rm -rf /var/lib/{apt,dpkg,cache,log}/
USER jenkins
Таким образом мы получили Docker контейнер который может выполнять Docker команды на хостовой машине.
Не так давно Jenkins получил возможность описывать свои правила при помощи Pipeline [7] синтаксиса, что позволяет достаточно просто менять скрипт сборки и хранить его в репозитории.
Так давайте же мы поместим в сам репозиторий специальный Dockerfile, который будет содержать в себе все необходимые для сборки библиотеки. Таким образом сам разработчик может подготовить повторяемую среду и не нужно будет OPS просить поставить на хост определенную версию Node.JS.
FROM node:12.10.0-alpine
RUN npm install yarn -g
Такой сборочный образ подходит для большинства Node.JS приложений. А если вам, например, нужен образ для JVM проекта со включенным внутрь Sonar сканером? Вы сами вольны выбирать нужные для сборки компоненты.
FROM adoptopenjdk/openjdk12:latest
RUN apt update
&& apt install -y
bash unzip wget
RUN mkdir -p /usr/local/sonarscanner
&& cd /usr/local/sonarscanner
&& wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-linux.zip
&& unzip sonar-scanner-cli-3.3.0.1492-linux.zip
&& mv sonar-scanner-3.3.0.1492-linux/* ./
&& rm sonar-scanner-cli-3.3.0.1492-linux.zip
&& rm -rf sonar-scanner-3.3.0.1492-linux
&& ln -s /usr/local/sonarscanner/bin/sonar-scanner /usr/local/bin/sonar-scanner
ENV PATH $PATH:/usr/local/sonarscanner/bin/
ENV SONAR_RUNNER_HOME /usr/local/sonarscanner/bin/
Мы описали сборочное окружение, но при чем тут Jenkins? А Jenkins агенты умеют работать с такими Docker образами и проводить сборку внутри.
stage("Build project") {
agent {
docker {
image "project-build:${DOCKER_IMAGE_BRANCH}"
args "-v ${PWD}:/usr/src/app -w /usr/src/app"
reuseNode true
label "build-image"
}
}
steps {
sh "yarn"
sh "yarn build"
}
}
Директива agent
использует свойство docker
, где вы можете указать:
А уже в шагах сборки мы указываем, какие команды выполнить внутри сборочного Docker агента. Это может все что угодно, таким образом я так же запускаю деплой приложений при помощи ansible.
Ниже я хочу показать общий Jenkinsfile, который может собрать простое Node.JS приложение.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("Prepare build image") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Build project") {
agent {
docker {
image "project-build:${DOCKER_IMAGE_BRANCH}"
args "-v ${PWD}:/usr/src/app -w /usr/src/app"
reuseNode true
label "build-image"
}
}
steps {
sh "yarn"
sh "yarn build"
}
}
post {
always {
step([$class: "WsCleanup"])
cleanWs()
}
}
}
Благодаря такому способу мы решили следующие проблемы:
Само по себе решение простое и очевидное и позволяет получить одни плюсы. Да, порог входа чуточку поднялся по сравнению с простыми командами для сборок, но зато теперь есть гарантия, что будет собираться всегда и разработчик сам может выбрать все, что необходимо для его процесса сборки.
Так же вы можете воспользоваться собранным мною образом Jenkins + Docker [8]. Все исходники открыты и лежат на rmuhamedgaliev/jenkins_docker [9].
В ходе написания статьи появилась дискуссия о использовании агентов на удаленных серверах, чтобы не грузить мастер ноду при помощи плагина docker-plugin [10]. Но об этом я расскажу в будущем.
Автор: Ринат Мухамедгалиев
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/node-js/340799
Ссылки в тексте:
[1] Drone.io: https://drone.io
[2] Bitbucket Pipeline: https://bitbucket.org/product/ru/features/pipelines
[3] GitLab: https://about.gitlab.com/
[4] GitHub actions: https://github.com/features/actions
[5] Docker агентами: https://jenkins.io/doc/book/pipeline/docker/
[6] Docker can now run within Docker: https://www.docker.com/blog/docker-can-now-run-within-docker/
[7] Pipeline: https://jenkins.io/doc/book/pipeline/
[8] Jenkins + Docker: https://hub.docker.com/repository/docker/rmuhamedgaliev/jenkins/general
[9] rmuhamedgaliev/jenkins_docker: https://github.com/rmuhamedgaliev/jenkins_docker
[10] docker-plugin: https://plugins.jenkins.io/docker-plugin
[11] Источник: https://habr.com/ru/post/481466/?utm_source=habrahabr&utm_medium=rss&utm_campaign=481466
Нажмите здесь для печати.