Există multe articole despre Habré despre Jenkins, dar puține descriu exemple despre cum funcționează Jenkins și agenții docker. Toate instrumentele populare de construire a proiectelor, cum ar fi
Astăzi există o soluție la problemă: Jenkins 2 este grozav să lucreze cu
De ce am început să rezolv această problemă?
Din moment ce suntem in companie
- o cantitate mare de timp de rulare pe care dezvoltatorii uită să o curețe;
- există conflicte între diferite versiuni ale acelorași runtime;
- Fiecare dezvoltator are nevoie de un set diferit de componente.
Sunt și alte probleme, dar să vă spun despre soluție.
Jenkins în Docker
Deoarece Docker este acum bine stabilit în lumea dezvoltării, aproape orice poate fi rulat folosind Docker. Soluția mea este să am Jenkins în Docker și să pot rula alte containere Docker. Această întrebare a început să fie pusă încă din 2013 în articolul „
Pe scurt, trebuie doar să instalați Docker într-un container funcțional și să montați fișierul /var/run/docker.sock
.
Iată un exemplu Dockerfile care s-a dovedit pentru 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
Astfel, avem un container Docker care poate executa comenzi Docker pe mașina gazdă.
Configurare de construcție
Nu cu mult timp în urmă, Jenkins a avut ocazia să-și descrie regulile folosind
Deci, să punem un Dockerfile special în depozitul în sine, care va conține toate bibliotecile necesare construirii. În acest fel, dezvoltatorul însuși poate pregăti un mediu repetabil și nu va trebui să solicite OPS să instaleze o anumită versiune de Node.JS pe gazdă.
FROM node:12.10.0-alpine
RUN npm install yarn -g
Această imagine de compilare este potrivită pentru majoritatea aplicațiilor Node.JS. Ce se întâmplă dacă, de exemplu, aveți nevoie de o imagine pentru un proiect JVM cu un scaner Sonar inclus în interior? Sunteți liber să alegeți componentele de care aveți nevoie pentru asamblare.
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/
Am descris mediul de asamblare, dar ce legătură are Jenkins cu el? Iar agenții Jenkins pot lucra cu astfel de imagini Docker și le pot construi intern.
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"
}
}
Directivă agent
folosește proprietatea docker
unde poti specifica:
- numele containerului de asamblare conform politicii dvs. de denumire;
- argumentele necesare pentru a rula containerul de compilare, unde în cazul nostru montem directorul curent ca director în interiorul containerului.
Și deja în pașii de construire indicăm ce comenzi să executăm în agentul de compilare Docker. Acesta poate fi orice, așa că lansez și implementarea aplicației folosind ansible.
Mai jos vreau să arăt un fișier Jenkins generic pe care îl poate construi o aplicație simplă 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()
}
}
}
Ce s-a întâmplat?
Datorită acestei metode, am rezolvat următoarele probleme:
- timpul de configurare a asamblarii mediului este redus la 10 - 15 minute per proiect;
- un mediu de construire a aplicației complet repetabil, deoarece o puteți construi în acest fel pe computerul local;
- nu există probleme cu conflictele între diferite versiuni de instrumente de asamblare;
- întotdeauna un spațiu de lucru curat, care nu se înfundă.
Soluția în sine este simplă și evidentă și vă permite să obțineți câteva avantaje. Da, pragul de intrare a crescut puțin în comparație cu comenzile simple pentru ansambluri, dar acum există garanția că va fi întotdeauna construit și dezvoltatorul însuși poate alege tot ceea ce este necesar pentru procesul său de construire.
Puteți folosi și imaginea pe care am colectat-o
În timpul scrierii acestui articol, a apărut o discuție despre utilizarea agenților pe servere la distanță pentru a nu încărca nodul principal folosind un plugin
Sursa: www.habr.com