
Op Habr zijn er veel artikelen over Jenkins, maar zelden wordt een voorbeeld gegeven van hoe Jenkins en Docker-agenten werken. Alle populaire buildtools zoals , , , en anderen kunnen alles in containers bouwen. Maar hoe zit het met Jenkins?
Tegenwoordig is er een oplossing voor het probleem: Jenkins 2 kan uitstekend overweg met . In dit artikel wil ik mijn ervaring delen en laten zien hoe je dit zelf kunt doen.
Waarom ben ik begonnen met het oplossen van dit probleem?
Aangezien we in het bedrijf veel verschillende technologieën gebruiken, moet er op de buildmachine een verscheidenheid aan versies van Node.JS, Gradle, Ruby, JDK en andere worden geïnstalleerd. Maar vaak zijn er versieconflicten onvermijdelijk. Ja, je hebt gelijk als je zegt dat er verschillende versiesbeheerders zijn zoals nvm, rvm, maar het is niet altijd eenvoudig met hen en deze oplossingen hebben hun problemen:
- een groot aantal runtimes dat ontwikkelaars vergeten schoon te maken;
- er zijn conflicten tussen verschillende versies van dezelfde runtimes;
- elke ontwikkelaar heeft een andere set componenten nodig.
Er zijn ook andere problemen, maar laat me je beter vertellen over de oplossing.
Jenkins in Docker
Aangezien Docker nu goed is geĆÆntegreerd in de ontwikkelingssfeer, kan bijna alles met Docker worden uitgevoerd. Mijn oplossing is dat Jenkins in Docker draait en andere Docker-containers kan opstarten. Deze vraag werd al in 2013 gesteld in het artikel "Ā«.
Kort gezegd, je moet Docker in de werkcontainer installeren en het bestand koppelen. /var/run/docker.sock.
Hier is een voorbeeld van de Dockerfile die we voor Jenkins hebben gekregen.
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 jenkinsZo hebben we een Docker-container verkregen die Docker-commando's op de hostmachine kan uitvoeren.
Configuratie van de build
Niet zo lang geleden kreeg Jenkins de mogelijkheid om zijn regels te beschrijven met behulp van syntax waardoor het behoorlijk eenvoudig is om het buildscript te wijzigen en het in de repository op te slaan.
Dus laten we een speciale Dockerfile in de repository plaatsen die alle noodzakelijke bibliotheken voor de build bevat. Op deze manier kan de ontwikkelaar een herhaalbare omgeving voorbereiden zonder dat de OPS gevraagd hoeft te worden om een specifieke versie van Node.JS op de host te installeren.
FROM node:12.10.0-alpine
RUN npm install yarn -gDeze build-image is geschikt voor de meeste Node.JS-applicaties. Maar als je bijvoorbeeld een image nodig hebt voor een JVM-project met een ingebouwde Sonar-scanner? Je bent vrij om de benodigde componenten voor de build te kiezen.
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/
We hebben de build-omgeving beschreven, maar wat heeft Jenkins hiermee te maken? Jenkins-agenten kunnen met dergelijke Docker-images werken en de build intern uitvoeren.
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"
}
}Directive agent maakt gebruik van de eigenschap docker, waar je kunt opgeven:
- de naam van de build-container volgens je naamgevingsbeleid;
- de argumenten die nodig zijn om de build-container uit te voeren, waar we in ons geval de huidige directory als directory binnen de container monteren.
En in de build-stappen geven we aan welke commando's we binnen de build Docker-agent willen uitvoeren. Dit kan van alles zijn, op deze manier voer ik ook de deployment van applicaties uit met behulp van Ansible.
Hieronder wil ik een algemene Jenkinsfile laten zien die een eenvoudige Node.JS-applicatie kan bouwen.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("Build afbeelding voorbereiden") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Project bouwen") {
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()
}
}
}Wat is het resultaat?
Dankzij deze aanpak hebben we de volgende problemen opgelost:
- de configuratietijd van de buildomgeving bedraagt nu 10 tot 15 minuten per project;
- volledig reproduceerbare buildomgeving voor de applicatie, omdat men ook lokaal kan bouwen;
- geen problemen met conflicten tussen verschillende versies van buildtools;
- altijd een schone werkruimte die niet volloopt.
De oplossing zelf is eenvoudig en duidelijk en biedt alleen voordelen. Ja, de instapdrempel is iets verhoogd vergeleken met eenvoudige buildcommando's, maar nu is er de garantie dat de build altijd zal plaatsvinden en kan de ontwikkelaar zelf alles kiezen wat nodig is voor zijn bouwproces.
U kunt ook gebruikmaken van de afbeelding die ik heb gebouwd . Alle bronbestanden zijn open en te vinden op .
Tijdens het schrijven van dit artikel ontstond er een discussie over het gebruik van agenten op externe servers, om de masternode niet te belasten via de plugin . Maar hier ga ik in de toekomst verder op in.
Bron: habr.com
