
Det finns mÄnga artiklar om Jenkins pÄ Habré, men fÄ stÀllen beskriver exempel pÄ hur Jenkins och Docker-agenter fungerar. Alla populÀra projektbyggverktyg som , , , och andra kan bygga allt i containrar. Men hur fungerar Jenkins?
Idag finns det en lösning pÄ problemet: Jenkins 2 fungerar utmÀrkt med . I den hÀr artikeln vill jag dela med mig av mina erfarenheter och visa hur du kan göra detta sjÀlv.
Varför började jag lösa detta problem?
Eftersom vi pÄ företaget anvÀnder mÄnga olika teknologier, mÄste byggmaskinen ha olika versioner av Node.JS, Gradle, Ruby, JDK och andra. Men det Àr ofta oundvikligt med versionskonflikter. Ja, du har rÀtt om du sÀger att det finns olika versionshanterare som nvm, rvm, men det Àr inte alltid sÄ enkelt med dem och dessa lösningar har sina problem:
- stora mÀngder av runtime-miljöer som utvecklare glömmer att rensa;
- det finns konflikter mellan olika versioner av samma runtime-miljöer;
- varje utvecklare behöver olika uppsÀttningar av komponenter.
Det finns andra problem, men lÄt mig hellre berÀtta om lösningen.
Jenkins i Docker
Eftersom Docker nu har fÄtt ett starkt fÀste inom utvecklingsvÀrlden kan nÀstan allt köras med hjÀlp av Docker. Min lösning Àr att Jenkins ska köras i Docker och kunna starta andra Docker-containrar. Denna frÄga började diskuteras redan 2013 i artikeln "«.
Kort sagt, det Àr nödvÀndigt att installera Docker i arbetscontainern och montera filen /var/run/docker.sock.
HÀr Àr ett exempel pÄ Dockerfile som skapades för 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 jenkinsPÄ sÄ sÀtt fick vi en Docker-container som kan utföra Docker-kommandon pÄ vÀrdmaskinen.
InstÀllning av byggning
För inte sÄ lÀnge sedan fick Jenkins möjlighet att beskriva sina regler med syntax, vilket gör det ganska enkelt att Àndra byggskriften och lagra den i ett repository.
LÄt oss sÀtta en speciell Dockerfile i sjÀlva arkivet som kommer att innehÄlla alla nödvÀndiga bibliotek för byggprocessen. PÄ sÄ sÀtt kan utvecklaren sjÀlv förbereda en reproducerbar miljö och behöver inte be OPS att installera en viss version av Node.JS pÄ vÀrden.
FROM node:12.10.0-alpine
RUN npm install yarn -gDen hÀr byggavbildningen passar för de flesta Node.JS-applikationer. Men om du till exempel behöver en avbildning för ett JVM-projekt med en inbyggd Sonar-scanner? Du har friheten att vÀlja de nödvÀndiga komponenterna för byggprocessen.
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/
Vi har beskrivit byggmiljön, men vad har Jenkins med saken att göra? Jenkins-agenter kan arbeta med sÄdana Docker-avbilder och utföra byggprocesser inuti.
stage("Bygg projekt") {
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"
}
}Direktiv agent anvÀnder egenskapen docker, dÀr du kan ange:
- namnet pÄ byggcontainern enligt din namngivningspolicy;
- de argument som behövs för att köra byggcontainern, dÀr vi i vÄrt fall monterar den aktuella katalogen som en katalog inuti containern.
Och redan i byggstegen anger vi vilka kommandon som ska köras inuti bygg-Docker-agenten. Det kan vara vad som helst, pÄ sÄ sÀtt utför jag Àven distribution av applikationer med hjÀlp av ansible.
Nedan vill jag visa en allmÀn Jenkinsfile som kan bygga en enkel Node.JS-applikation.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("Förbered byggbild") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Bygg projekt") {
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()
}
}
}Vad blev resultatet?
Genom denna metod löste vi följande problem:
- tiden för att konfigurera byggmiljön reduceras till 10 - 15 minuter per projekt;
- en helt reproducerbar byggmiljö, eftersom den kan byggas Àven pÄ den lokala datorn;
- inga problem med konflikter mellan olika versioner av byggverktyg;
- alltid en ren arbetsyta som inte blir överbelastad.
SjÀlva lösningen Àr enkel och uppenbar och ger enbart fördelar. Ja, intrÀdesbarriÀren har höjts nÄgot jÀmfört med enklare byggkommandon, men nu finns det en garanti pÄ att bygget alltid kommer att lyckas och utvecklaren kan sjÀlv vÀlja allt som behövs i sin byggprocess.
Du kan ocksÄ anvÀnda den bild jag har byggt . All kÀllkod Àr öppen och ligger pÄ .
Under skrivandet av artikeln uppstod en diskussion om anvÀndningen av agenter pÄ fjÀrrservrar för att inte belasta huvudnoden med hjÀlp av pluginet . Men det kommer jag att berÀtta om i framtiden.
KĂ€lla: habr.com
