
Es gibt viele Artikel über Jenkins auf Habr, aber nur wenige beschreiben ein Beispiel für die Arbeit mit Jenkins und Docker-Agenten. Alle beliebten Tools zur Projektbuild-Erstellung, wie , , , und andere, können alles in Containern bauen. Aber wie steht es um Jenkins?
Heute gibt es eine Lösung für dieses Problem: Jenkins 2 kann hervorragend mit arbeiten. In diesem Artikel möchte ich meine Erfahrungen teilen und zeigen, wie Sie das selbst machen können.
Warum habe ich mich mit der Lösung dieses Problems beschäftigt?
Da wir in der Firma viele verschiedene Technologien nutzen, müssen auf der Build-Maschine unterschiedliche Versionen von Node.JS, Gradle, Ruby, JDK und anderen ausgestattet werden. Oft sind Versionskonflikte unvermeidbar. Ja, Sie haben recht, wenn Sie sagen, dass es verschiedene Versionsmanager wie nvm, rvm gibt, aber so einfach ist es damit nicht und diese Lösungen haben ihre Probleme:
- ein großer Umfang an Runtimes, die Entwickler vergessen zu bereinigen;
- es gibt Konflikte zwischen verschiedenen Versionen der gleichen Runtimes;
- jeder Entwickler benötigt eine andere Sammlung von Komponenten.
Es gibt auch andere Probleme, aber lassen Sie mich besser über die Lösung sprechen.
Jenkins in Docker
Da Docker mittlerweile gut in der Entwicklungswelt verankert ist, kann fast alles mit Docker gestartet werden. Meine Lösung besteht darin, Jenkins in Docker zu betreiben und andere Docker-Container zu starten. Diese Frage wurde bereits 2013 in dem Artikel „«.
diskutiert. Kurz gesagt, es ist notwendig, Docker im Arbeitscontainer zu installieren und die Datei zu mounten. /var/run/docker.sock.
Hier ist ein Beispiel für das Dockerfile, das für Jenkins erstellt wurde.
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 jenkinsAuf diese Weise haben wir einen Docker-Container erhalten, der Docker-Befehle auf der Hostmaschine ausführen kann.
Build-Einrichtung
Vor nicht allzu langer Zeit gab Jenkins die Möglichkeit, seine Regeln mithilfe von Syntax zu beschreiben, was es relativ einfach macht, das Build-Skript zu ändern und es im Repository zu speichern.
Lassen Sie uns also eine spezielle Dockerfile in das Repository einfügen, die alle notwendigen Bibliotheken für den Build enthält. So kann der Entwickler eine wiederholbare Umgebung vorbereiten, und es ist nicht notwendig, OPS um die Installation einer bestimmten Version von Node.JS auf dem Host zu bitten.
FROM node:12.10.0-alpine
RUN npm install yarn -gDieses Build-Image eignet sich für die meisten Node.JS-Anwendungen. Und wenn Sie zum Beispiel ein Image für ein JVM-Projekt mit einem integrierten Sonar-Scanner benötigen? Sie können selbst die notwendigen Komponenten für den Build auswählen.
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/
Wir haben das Build-Umfeld beschrieben, aber was hat Jenkins damit zu tun? Jenkins-Agenten können mit solchen Docker-Images arbeiten und den Build innerhalb durchführen.
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"
}
}Direktive agent verwendet eine Eigenschaft docker, wo Sie angeben können:
- den Namen des Build-Containers gemäß Ihrer Namensrichtlinie;
- Argumente, die zum Starten des Build-Containers erforderlich sind, wo wir in unserem Fall das aktuelle Verzeichnis als Verzeichnis innerhalb des Containers mounten.
Und bereits in den Build-Schritten geben wir an, welche Befehle im Build-Docker-Agenten ausgeführt werden sollen. Das kann alles Mögliche sein, so starte ich auch die Bereitstellung von Anwendungen mit Hilfe von Ansible.
Unten möchte ich ein allgemeines Jenkinsfile zeigen, das ein einfaches Node.JS-Anwendung bauen kann.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("Build-Image vorbereiten") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Projekt bauen") {
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()
}
}
}Was ist das Ergebnis?
Durch diese Methode haben wir folgende Probleme gelöst:
- Die Konfigurationszeit für die Umgebung beträgt 10 bis 15 Minuten pro Projekt;
- vollständig reproduzierbare Bauumgebungen für Anwendungen, da man auch lokal so bauen kann;
- keine Probleme mit Konflikten zwischen verschiedenen Versionen von Build-Tools;
- immer ein sauberer Workspace, der sich nicht aufstaut.
Die Lösung selbst ist einfach und offensichtlich und bringt nur Vorteile. Ja, die Einstiegshürde ist etwas höher im Vergleich zu einfachen Build-Befehlen, aber dafür gibt es jetzt die Garantie, dass immer gebaut wird, und der Entwickler kann alles, was für seinen Build-Prozess notwendig ist, selbst wählen.
Außerdem können Sie das von mir erstellte Image verwenden . Alle Quellcodes sind offen und liegen bei .
Im Verlauf des Schreibens des Artikels gab es eine Diskussion über die Verwendung von Agenten auf entfernten Servern, um die Master-Node nicht mit dem Plugin zu belasten. . Aber darüber werde ich in Zukunft berichten.
Quelle: habr.com
