Ci sono molti articoli su Habré su Jenkins, ma pochi descrivono esempi di come funzionano Jenkins e gli agenti docker. Tutti gli strumenti più diffusi per la creazione di progetti come
Oggi c'è una soluzione al problema: Jenkins 2 è un ottimo modo per lavorare
Perché ho iniziato a risolvere questo problema?
Visto che siamo in compagnia
- una grande quantità di runtime che gli sviluppatori dimenticano di pulire;
- ci sono conflitti tra diverse versioni degli stessi runtime;
- Ogni sviluppatore ha bisogno di un diverso set di componenti.
Ci sono altri problemi, ma lascia che ti parli della soluzione.
Jenkins in Docker
Poiché Docker è ormai ben consolidato nel mondo dello sviluppo, quasi tutto può essere eseguito utilizzando Docker. La mia soluzione è avere Jenkins in Docker ed essere in grado di eseguire altri contenitori Docker. Questa domanda ha cominciato a essere posta nel 2013 nell'articolo “
In breve, devi solo installare Docker stesso in un contenitore funzionante e montare il file /var/run/docker.sock
.
Ecco un esempio di Dockerfile che si è rivelato per 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
Pertanto, abbiamo ottenuto un contenitore Docker in grado di eseguire comandi Docker sul computer host.
Costruisci la configurazione
Non molto tempo fa Jenkins ha avuto l'opportunità di descrivere le sue regole utilizzando
Inseriamo quindi un apposito Dockerfile nel repository stesso, che conterrà tutte le librerie necessarie per la build. In questo modo, lo sviluppatore stesso può preparare un ambiente ripetibile e non dovrà chiedere a OPS di installare una versione specifica di Node.JS sull'host.
FROM node:12.10.0-alpine
RUN npm install yarn -g
Questa immagine build è adatta per la maggior parte delle applicazioni Node.JS. Cosa succede se, ad esempio, hai bisogno di un'immagine per un progetto JVM con uno scanner Sonar incluso al suo interno? Sei libero di scegliere i componenti necessari per il montaggio.
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/
Abbiamo descritto l'ambiente di assembly, ma cosa c'entra Jenkins? E gli agenti Jenkins possono lavorare con tali immagini Docker e crearle internamente.
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"
}
}
direttiva agent
utilizza la proprietà docker
dove puoi specificare:
- il nome del contenitore dell'assembly in base alla politica di denominazione;
- argomenti necessari per eseguire il contenitore di compilazione, dove nel nostro caso montiamo la directory corrente come directory all'interno del contenitore.
E già nei passaggi di build indichiamo quali comandi eseguire all'interno del build agent Docker. Può trattarsi di qualsiasi cosa, quindi avvio anche la distribuzione dell'applicazione utilizzando ansible.
Di seguito voglio mostrare un Jenkinsfile generico che può essere creato da una semplice applicazione Node.JS.
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()
}
}
}
Quello che è successo?
Grazie a questo metodo abbiamo risolto i seguenti problemi:
- il tempo di configurazione dell'assemblaggio dell'ambiente è ridotto a 10 - 15 minuti per progetto;
- un ambiente di creazione dell'applicazione completamente ripetibile, poiché puoi crearlo in questo modo sul tuo computer locale;
- non ci sono problemi con conflitti tra diverse versioni degli strumenti di assemblaggio;
- sempre uno spazio di lavoro pulito che non si intasi.
La soluzione in sé è semplice ed ovvia e permette di ottenere alcuni vantaggi. Sì, la soglia di ingresso è leggermente aumentata rispetto ai semplici comandi per gli assiemi, ma ora c'è la garanzia che verrà sempre costruito e lo sviluppatore stesso potrà scegliere tutto ciò che è necessario per il suo processo di costruzione.
Puoi anche utilizzare l'immagine che ho raccolto
Durante la stesura di questo articolo è nata una discussione sull'utilizzo degli agenti su server remoti in modo da non caricare il nodo master utilizzando un plugin
Fonte: habr.com