
Auf Habr gibt es viele Artikel über Jenkins, aber nur wenige beschreiben ein Beispiel für die Arbeit von Jenkins und Docker-Agenten. Alle gängigen Build-Tools wie , , , und andere können alles in Containern bauen. Aber wie steht es um Jenkins?
Heutzutage gibt es eine Lösung für dieses Problem: Jenkins 2 kann hervorragend mit arbeiten. In diesem Artikel möchte ich meine Erfahrung teilen und Ihnen zeigen, wie Sie es selbst machen können.
Warum habe ich mich mit diesem Problem beschäftigt?
Da wir in der Firma eine Vielzahl von Technologien verwenden, muss auf der Build-Maschine eine Vielzahl von Versionen wie Node.JS, Gradle, Ruby, JDK und andere gehalten werden. Aber oft sind Versionskonflikte unvermeidbar. Ja, Sie haben recht, wenn Sie sagen, dass es verschiedene Version-Manager wie nvm, rvm gibt, aber es ist nicht immer so reibungslos und diese Lösungen haben ihre Probleme:
- eine große Menge an Runtimes, die die Entwickler vergessen zu bereinigen;
- es gibt Konflikte zwischen verschiedenen Versionen derselben Runtimes;
- jeder Entwickler benötigt ein unterschiedliches Set an Komponenten.
Es gibt auch andere Probleme, aber lassen Sie mich lieber über die Lösung sprechen.
Jenkins in Docker
Da Docker sich mittlerweile gut im Entwicklungsbereich etabliert hat, kann fast alles mit Docker gestartet werden. Mein Vorschlag ist, Jenkins in Docker auszuführen, sodass es andere Docker-Container starten kann. Diese Frage wurde bereits 2013 in dem Artikel "«.
Kurz gefasst, Sie müssen Docker im Arbeitscontainer installieren und eine Datei einbinden. /var/run/docker.sock.
Hier ist ein Beispiel für einen Dockerfile, der 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 jenkinsSo haben wir einen Docker-Container erhalten, der Docker-Befehle auf der Hostmaschine ausführen kann.
Build-Konfiguration
Vor kurzem hat Jenkins die Möglichkeit hinzugefügt, seine Regeln mit Syntax, was es ermöglicht, das Build-Skript recht einfach zu ändern und in einem Repository zu speichern.
Lassen Sie uns also eine spezielle Dockerfile in das Repository legen, das alle notwendigen Bibliotheken für den Build enthalten wird. So kann der Entwickler eine wiederholbare Umgebung vorbereiten, ohne die OPS bitten zu müssen, eine bestimmte Version von Node.JS auf dem Host zu installieren.
FROM node:12.10.0-alpine
RUN npm install yarn -gSolch ein Build-Image eignet sich für die meisten Node.JS-Anwendungen. Und falls Sie beispielsweise ein Image für ein JVM-Projekt mit integriertem Sonar-Scanner benötigen? Sie können selbst die benötigten 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 die Build-Umgebung beschrieben, aber was hat Jenkins damit zu tun? Jenkins-Agents können mit solchen Docker-Images arbeiten und den Build innerhalb durchführen.
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"
}
}Direktive agent verwendet die Eigenschaft docker, wo Sie angeben können:
- den Namen des Build-Containers gemäß Ihrer Namenskonvention;
- die Argumente, die für den Start des Build-Containers erforderlich sind, wobei wir in unserem Fall das aktuelle Verzeichnis als Verzeichnis innerhalb des Containers mounten.
In den Build-Schritten geben wir dann an, welche Befehle innerhalb des Build-Docker-Agenten ausgeführt werden sollen. Das kann alles Mögliche sein; so starte ich auch den Deployment-Prozess von Anwendungen mit Ansible.
Im Folgenden möchte ich einen allgemeinen Jenkinsfile zeigen, der eine einfache 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 Build-Umgebung beträgt nun 10 - 15 Minuten pro Projekt;
- eine vollständig reproduzierbare Build-Umgebung für die Anwendung, da dieselbe auch lokal aufgebaut werden kann;
- keine Probleme mit Konflikten verschiedener Versionen von Build-Tools;
- immer ein sauberer Arbeitsbereich, der nicht überfüllt wird.
Die Lösung ist an sich einfach und offensichtlich und bietet ausschließlich Vorteile. Ja, die Einstiegshürde ist im Vergleich zu einfachen Befehlen für Builds etwas gestiegen, aber dafür gibt es jetzt die Garantie, dass immer gebaut wird, und der Entwickler kann selbst entscheiden, was er für seinen Build-Prozess benötigt.
Außerdem können Sie das von mir erstellte Image nutzen. . Alle Quellcodes sind offen und finden Sie unter .
Im Verlauf des Schreibens des Artikels entstand eine Diskussion über den Einsatz von Agenten auf Remote-Servern, um die Master-Node nicht zu belasten, mithilfe des Plugins . Darüber werde ich in Zukunft berichten.
Quelle: habr.com
