
Na Habr je mnoho článků o Jenkins, ale jen málo kde je popsán příklad použití Jenkins a Docker agentů. Všechny populární nástroje pro sestavení projektů jako , , , a další mohou sestavovat vše v kontejnerech. Ale jak je to s Jenkins?
V současnosti existuje řešení tohoto problému: Jenkins 2 skvěle zvládá práci s . V článku se chci podělit o zkušenosti a ukázat, jak to můžete udělat sami.
Proč jsem se zabýval řešením tohoto problému?
Protože ve společnosti používáme mnoho různých technologií, musíme mít na sestavovacím stroji různé verze Node.JS, Gradle, Ruby, JDK a dalších. Ale většinou se konfliktům verzí nevyhneme. Ano, měli byste pravdu, když řeknete, že existují různé správce verzí jako nvm, rvm, ale není to s nimi tak hladké a tato řešení mají problémy:
- velký objem runtime, který vývojáři zapomínají čistit;
- existují konflikty mezi různými verzemi stejných runtime;
- každý vývojář potřebuje jinou sadu komponent.
Existují i další problémy, ale raději vám povím o řešení.
Jenkins v Dockeru
Protože Docker se nyní již dobře usadil v oblasti vývoje, téměř vše lze spustit pomocí Dockeru. Moje řešení spočívá v tom, že Jenkins bude v Dockeru a bude moci spouštět další Docker kontejnery. Tímto problémem se začali zabývat již v roce 2013 v článku „«.
Pokud to shrneme, je nutné do pracovního kontejneru nainstalovat Docker a přimountovat soubor. /var/run/docker.sock.
Zde je příklad Dockerfile, který vznikl pro 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 jenkinsTímto jsme získali Docker kontejner, který může vykonávat Docker příkazy na hostitelské stroji.
Nastavení sestavení
Nedávno získal Jenkins možnost popisovat svá pravidla pomocí syntaktických, což umožňuje poměrně snadno měnit skript sestavení a uchovávat ho v repozitáři.
Tak pojďme umístit do samotného repozitáře speciální Dockerfile, který bude obsahovat všechny potřebné knihovny pro sestavení. Tímto způsobem může vývojář připravit opakovatelnou prostředí a nebude muset žádat OPS, aby nainstalovalo na hostitel určitou verzi Node.JS.
FROM node:12.10.0-alpine
RUN npm install yarn -gTento obraz pro sestavení je vhodný pro většinu aplikací Node.JS. A pokud potřebujete například obraz pro projekt JVM se zabudovaným Sonar skenerem? Můžete si svobodně vybrat potřebné komponenty pro sestavení.
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/
Popisujeme sestavovací prostředí, ale co má společného s Jenkins? Jenkins agenti umí pracovat s takovými Docker obrazy a provádět sestavení uvnitř.
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"
}
}Direktiva agent používá vlastnost docker, kde můžete uvést:
- název sestavovacího kontejneru podle vaší pojmenovací politiky;
- argumenty potřebné k spuštění sestavovacího kontejneru, kde v našem případě připojujeme aktuální adresář jako adresář uvnitř kontejneru.
A v krocích sestavení uvádíme, jaké příkazy vykonat uvnitř sestavovacího Docker agenta. To může být cokoliv, takto také spouštím nasazení aplikací pomocí ansible.
Níže chci ukázat obecný Jenkinsfile, který dokáže sestavit jednoduchou aplikaci Node.JS.
def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""
pipeline {
options {
buildDiscarder(
logRotator(
artifactDaysToKeepStr: "",
artifactNumToKeepStr: "",
daysToKeepStr: "",
numToKeepStr: "10"
)
)
disableConcurrentBuilds()
}
agent any
stages {
stage("Připravit obraz pro sestavení") {
steps {
sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
}
}
stage("Sestavit projekt") {
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()
}
}
}Jaké máme výsledky?
Díky tomuto postupu jsme vyřešili následující problémy:
- doba konfigurace sestavení prostředí se zkrátila na 10 – 15 minut na projekt;
- úplně reprodukovatelné prostředí pro sestavení aplikace, jelikož lze sestavovat i na místním počítači;
- žádné problémy se konflikty různých verzí nástrojů pro sestavení;
- vždy čistý pracovní prostor, který se nezaplní.
Samo o sobě je řešení jednoduché a očividné a nabízí pouze výhody. Ano, vstupní práh se mírně zvýšil v porovnání s jednoduchými příkazy pro sestavení, ale nyní je zaručeno, že se bude sestavovat vždy, a vývojář si může vybrat vše, co potřebuje pro svůj proces sestavení.
Také můžete využít můj vytvořený obraz . Všechny zdrojové kódy jsou otevřené a nacházejí se na .
Během psaní článku se objevila diskuse o používání agentů na vzdálených serverech, aby se nezatěžovala hlavní uzel pomocí pluginu . O tom však budu hovořit v budoucnu.
Zdroj: habr.com
