На Хабре шмат артыкулаў аб Jenkins, але мала дзе апісваецца прыклад працы Jenkins і докер агентаў. Усе папулярныя прылады зборкі праектаў тыпу
На сённяшні дзень ёсць рашэнне праблемы: Jenkins 2 выдатна ўмее працаваць з
Чаму я заняўся вырашэннем гэтай праблемы?
Бо мы ў кампаніі
- вялікі аб'ём рантаймаў, які распрацоўшчыкі забываюць чысціць;
- ёсць канфлікты паміж рознымі версіямі адных рантаймаў;
- кожнаму распрацоўніку патрэбен розны набор кампанентаў.
Ёсць і іншыя праблемы, але давайце я лепш раскажу пра рашэнне.
Jenkins у Docker
Бо зараз Docker ужо добра ўкараніўся ў сферы распрацоўкі, то амаль усё можна запусціць пры дапамозе Docker. Маё ж рашэнне ў тым, каб Jenkins быў у Docker і мог запускаць іншыя Docker кантэйнеры. Гэтым пытаннем сталі задавацца яшчэ ў 2013 годзе ў артыкуле «
Калі коратка проста неабходна ў працоўны кантэйнер усталяваць сам 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 атрымаў магчымасць апісваць свае правілы пры дапамозе
Дык давайце ж мы змесцім у сам рэпазітар спецыяльны 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()
}
}
}
Што ж выйшла?
Дзякуючы такому спосабу мы вырашылі наступныя праблемы:
- час канфігурацыі зборкі асяроддзя зводзіцца да 10 - 15 хвілін на праект;
- цалкам паўтаранае асяроддзе зборкі прыкладання, бо можна так збіраць і на лакальным кампутары;
- няма праблем з канфліктамі розных версій зборачных інструментаў;
- заўсёды чысты воркспейс, які не забіваецца.
Само па сабе рашэнне простае і відавочнае і дазваляе атрымаць адны плюсы. Так, парог уваходу крышачку падняўся ў параўнанні з простымі камандамі для зборак, але затое зараз ёсць гарантыя, што будзе збірацца заўсёды і распрацоўшчык сам можа абраць усё, што неабходна для яго працэсу зборкі.
Гэтак жа вы можаце скарыстацца сабранай мною выявай
Падчас напісання артыкула з'явілася дыскусія аб выкарыстанні агентаў на выдаленых серверах, каб не грузіць майстар ноду пры дапамозе плагіна
Крыніца: habr.com