Hogyan lehet projekteket összeállítani a Jenkins-ben, ha sok különböző környezet szükséges

Hogyan lehet projekteket összeállítani a Jenkins-ben, ha sok különböző környezet szükséges

A Habrán sok cikk található a Jenkins-ről, de kevés helyen van példa a Jenkins és a Docker ügynökök működésére. Minden népszerű projekt-összeállító eszköz, mint például Drone.io, Bitbucket Pipeline, GitLab, GitHub actions és mások, mind konténerekben tudnak összerakni mindent. De mi a helyzet a Jenkinnel?

Manapság van megoldás a problémára: a Jenkins 2 rendkívül jól tud dolgozni a Docker ügynökökkel. A cikkben szeretném megosztani a tapasztalataimat, és megmutatni, hogyan tudjátok ezt ti is megcsinálni.

Miért foglalkoztam ezzel a problémával?

Mivel a cégünkben Citronium sokféle technológiát használunk, a build gépen számos Node.JS, Gradle, Ruby, JDK és más különböző verziót kell tartani. De gyakran nem kerülhetjük el a verziókonfliktusokat. Igen, igazatok van, ha azt mondjátok, hogy vannak különböző verziókezelő menedzserek, mint az nvm, rvm, de nem minden olyan sima velük, és ezeknek a megoldásoknak is megvannak a problémáik:

  • nagy számú runtime, amelyet a fejlesztők elfelejtenek kitisztítani;
  • konfliktusok vannak az egyes runtime-ok különböző verziói között;
  • minden fejlesztőnek különböző komponenskészletre van szüksége.

Egyéb problémák is léteznek, de inkább a megoldásról szeretnék beszélni.

Jenkins Dockerben

Mivel ma már a Docker jól beágyazódott a fejlesztési szférába, szinte mindent lehet futtatni Docker segítségével. Az én megoldásom az, hogy a Jenkins Dockerben van, és képes más Docker konténereket elindítani. E kérdéssel már 2013-ban elkezdtek foglalkozni a "A Docker most már Dockerben is futhat«.

Röviden, a munkakonténerbe egyszerűen be kell állítani a Docker-t és csatolni kell egy fájlt. /var/run/docker.sock.

Íme egy példa Dockerfile, amelyet a Jenkinshez készítettem.

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

Így kaptunk egy Docker konténert, amely képes Docker parancsokat végrehajtani a gazdagépen.

Build beállítások

Nem olyan régen a Jenkins megkapta a lehetőséget, hogy a szabályait a következő módon írja le Pipeline a szintaxis, amely lehetővé teszi, hogy viszonylag egyszerűen módosítsuk az összesítési szkriptet és tároljuk azt a tárolóban.

Tehát helyezzük el a tárolóban egy különleges Dockerfile-t, amely tartalmazza az összes szükséges könyvtárat az összesítéshez. Így a fejlesztő képes lesz előkészíteni egy ismételhető környezetet, és nem kell az OPS-t arra kérnie, hogy telepítsen egy adott verziót a Node.JS-ból a hoszton.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Ez az összesítő kép a legtöbb Node.JS alkalmazás számára megfelelő. Például, ha egy JVM projekthez lenne szükség egy belső Sonar szkennerrel ellátott képre? Akkor szabadon választhatja meg az összesítéshez szükséges összetevőket.

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/

Leírtuk az összesítési környezetet, de mi köze van ehhez a Jenkinsnek? A Jenkins ügynökök képesek dolgozni az ilyen Docker képekkel és belül végrehajtani az összesítést.

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"
    }
}

Direktíva ügynök használja a tulajdonságot docker, ahol megadhatja:

  • az összesítő konténer nevét az elnevezési irányelvei szerint;
  • az összesítő konténer indításához szükséges argumentumokat, ahol az esetünkben a jelenlegi könyvtárat a konténeren belüli könyvtárként szereljük fel.

Aztán az összesítési lépésekben meg kell adnunk, milyen parancsokat hajtsunk végre az összesítő Docker ügynökén belül. Ez bármi lehet, így én is elindítom az alkalmazások telepítését Ansible segítségével.

Alább szeretném bemutatni a teljes Jenkinsfile-t, amely egyszerű Node.JS alkalmazást képes összesíteni.

def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""

pipeline { 
    options {
        buildDiscarder(
            logRotator(
                artifactDaysToKeepStr: "",
                artifactNumToKeepStr: "",
                daysToKeepStr: "",
                numToKeepStr: "10"
            )
        )
        disableConcurrentBuilds()
    }

    agent any

    stages {

        stage("Készítsen build képet") {
            steps {
                sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
            }
        }

        stage("Projekt építése") {
            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()
        }
    }

}

Mi lett a végeredmény?

Ezzel a módszerrel a következő problémákat oldottuk meg:

  • a build környezet konfigurálásának ideje 10-15 percre csökkent projektenként;
  • teljesen reprodukálható build környezet, mivel ezt a folyamatot lokálisan is végrehajthatjuk;
  • nincsenek problémák a különböző build eszközök verzió-konfliktusaival;
  • mindig tiszta munkaterület, amely nem zsúfolódik tele.

A megoldás önmagában egyszerű és nyilvánvaló, és csak előnyöket hoz. Igen, a belépési küszöb egy kicsit megemelkedett az egyszerű build parancsokhoz képest, de így garantált, hogy mindig elkészül, és a fejlesztő maga választhatja ki mindazt, ami szükséges a build folyamatához.

Ezen kívül használhatja az én általom készített képet Jenkins + Docker. Az összes forrásnyílt és elérhető a rmuhamedgaliev\/jenkins_docker.

A cikk írása során vita alakult ki arról, hogy távoli szervereken használjunk ügynököket, hogy ne terheljük túl a mester nót a docker-plugin. De erről a jövőben fogok beszélni.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster