Il existe de nombreux articles sur Habré à propos de Jenkins, mais peu décrivent des exemples du fonctionnement de Jenkins et des agents Docker. Tous les outils de création de projets populaires comme
Il existe aujourd'hui une solution au problème : Jenkins 2 est excellent pour travailler avec
Pourquoi ai-je commencé à résoudre ce problème ?
Puisque nous sommes en compagnie
- une grande quantité de temps d'exécution que les développeurs oublient de nettoyer ;
- il existe des conflits entre différentes versions des mêmes environnements d'exécution ;
- Chaque développeur a besoin d'un ensemble différent de composants.
Il existe d'autres problèmes, mais laissez-moi vous parler de la solution.
Jenkins dans Docker
Puisque Docker est désormais bien implanté dans le monde du développement, presque tout peut être exécuté avec Docker. Ma solution est d'avoir Jenkins dans Docker et de pouvoir exécuter d'autres conteneurs Docker. Cette question a commencé à être posée en 2013 dans l'article «
En bref, il vous suffit d'installer Docker lui-même dans un conteneur fonctionnel et de monter le fichier /var/run/docker.sock
.
Voici un exemple de Dockerfile qui s'est avéré pour 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
Ainsi, nous avons un conteneur Docker capable d'exécuter des commandes Docker sur la machine hôte.
Configuration de la construction
Il n'y a pas si longtemps, Jenkins a eu l'occasion de décrire ses règles en utilisant
Mettons donc un Dockerfile spécial dans le référentiel lui-même, qui contiendra toutes les bibliothèques nécessaires à la construction. De cette façon, le développeur peut lui-même préparer un environnement reproductible et n'aura pas à demander à OPS d'installer une version spécifique de Node.JS sur l'hôte.
FROM node:12.10.0-alpine
RUN npm install yarn -g
Cette image de build convient à la plupart des applications Node.JS. Que se passe-t-il si, par exemple, vous avez besoin d'une image pour un projet JVM avec un scanner Sonar inclus ? Vous êtes libre de choisir les composants dont vous avez besoin pour l’assemblage.
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/
Nous avons décrit l'environnement d'assemblage, mais qu'est-ce que Jenkins a à voir avec cela ? Et les agents Jenkins peuvent travailler avec de telles images Docker et les créer en interne.
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
utilise la propriété docker
où vous pouvez préciser :
- le nom du conteneur d'assemblage selon votre politique de dénomination ;
- arguments nécessaires pour exécuter le conteneur de construction, où dans notre cas, nous montons le répertoire courant en tant que répertoire à l'intérieur du conteneur.
Et déjà dans les étapes de construction, nous indiquons les commandes à exécuter dans l'agent de construction Docker. Cela peut être n'importe quoi, donc je lance également le déploiement d'applications en utilisant ansible.
Ci-dessous, je souhaite montrer un fichier Jenkins générique qu'une simple application Node.JS peut créer.
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 qui s'est passé?
Grâce à cette méthode, nous avons résolu les problèmes suivants :
- le temps de configuration de l'assemblage de l'environnement est réduit à 10 à 15 minutes par projet ;
- un environnement de création d'applications entièrement reproductible, puisque vous pouvez le créer de cette façon sur votre ordinateur local ;
- il n'y a aucun problème de conflits entre les différentes versions des outils d'assemblage ;
- toujours un espace de travail propre et non obstrué.
La solution elle-même est simple et évidente et vous permet de bénéficier de certains avantages. Oui, le seuil d'entrée a un peu augmenté par rapport aux commandes simples pour les assemblys, mais il existe désormais une garantie qu'il sera toujours construit et le développeur lui-même peut choisir tout ce qui est nécessaire à son processus de construction.
Vous pouvez également utiliser l'image que j'ai collectée
Lors de la rédaction de cet article, une discussion a eu lieu sur l'utilisation d'agents sur des serveurs distants afin de ne pas charger le nœud maître à l'aide d'un plugin
Source: habr.com