Hvordan samle prosjekter i Jenkins hvis du trenger mange forskjellige miljøer

Hvordan samle prosjekter i Jenkins hvis du trenger mange forskjellige miljøer

Det finnes mange artikler på Habré om Jenkins, men få beskriver eksempler på hvordan Jenkins og havnearbeidere jobber. Alle populære prosjektbyggingsverktøy som Drone.io, Bitbucket Pipeline, GitLab, GitHub-handlinger og andre, kan samle alt i containere. Men hva med Jenkins?

I dag finnes det en løsning på problemet: Jenkins 2 er fantastisk å jobbe med Docker-agenter. I denne artikkelen vil jeg dele min erfaring og vise hvordan du kan gjøre det selv.

Hvorfor begynte jeg å løse dette problemet?

Siden vi er i selskap Sitronium Fordi vi bruker mange forskjellige teknologier, må vi ha forskjellige versjoner av Node.JS, Gradle, Ruby, JDK og andre på monteringsmaskinen. Men ofte kan ikke versjonskonflikter unngås. Ja, du vil ha rett hvis du sier at det finnes forskjellige versjonsbehandlere som nvm, rvm, men ikke alt er så glatt med dem, og disse løsningene har problemer:

  • en stor mengde kjøretid som utviklere glemmer å rense;
  • det er konflikter mellom forskjellige versjoner av samme kjøretid;
  • Hver utvikler trenger et annet sett med komponenter.

Det er andre problemer, men la meg fortelle deg om løsningen.

Jenkins i Docker

Siden Docker nå er godt etablert i utviklingsverdenen, kan nesten alt kjøres med Docker. Min løsning er å ha Jenkins i Docker og kunne kjøre andre Docker-containere. Dette spørsmålet begynte å bli stilt tilbake i 2013 i artikkelen "Docker kan nå kjøre i Docker".

Kort sagt, du trenger bare å installere selve Docker i en fungerende beholder og montere filen /var/run/docker.sock.

Her er et eksempel på Dockerfile som viste seg for 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

Dermed fikk vi en Docker-beholder som kan utføre Docker-kommandoer på vertsmaskinen.

Bygg oppsett

For ikke lenge siden fikk Jenkins muligheten til å beskrive sine regler ved hjelp av Rørledning syntaks, som gjør det ganske enkelt å endre byggeskriptet og lagre det i depotet.

Så la oss legge inn en spesiell Dockerfile i selve depotet, som vil inneholde alle bibliotekene som er nødvendige for byggingen. På denne måten kan utvikleren selv forberede et repeterbart miljø og slipper å be OPS om å installere en spesifikk versjon av Node.JS på verten.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Dette byggebildet passer for de fleste Node.JS-applikasjoner. Hva om du for eksempel trenger et bilde for et JVM-prosjekt med en ekkoloddskanner inkludert? Du står fritt til å velge komponentene du trenger for montering.

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/

Vi beskrev monteringsmiljøet, men hva har Jenkins med det å gjøre? Og Jenkins-agenter kan jobbe med slike Docker-bilder og bygge dem internt.

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

direktiv agent bruker eiendom dockerhvor du kan spesifisere:

  • navnet på monteringsbeholderen i henhold til din navnepolicy;
  • argumenter som trengs for å kjøre byggebeholderen, hvor vi i vårt tilfelle monterer gjeldende katalog som en katalog inne i beholderen.

Og allerede i byggetrinnene indikerer vi hvilke kommandoer som skal utføres inne i Docker byggeagenten. Dette kan være hva som helst, så jeg starter også applikasjonsdistribusjon ved å bruke ansible.

Nedenfor vil jeg vise en generisk Jenkinsfil som en enkel Node.JS-applikasjon kan bygge.

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()
        }
    }

}

Hva skjedde?

Takket være denne metoden løste vi følgende problemer:

  • Konfigurasjonstiden for miljømontering reduseres til 10 - 15 minutter per prosjekt;
  • et fullstendig repeterbart applikasjonsbyggemiljø, siden du kan bygge det på denne måten på din lokale datamaskin;
  • det er ingen problemer med konflikter mellom forskjellige versjoner av monteringsverktøy;
  • alltid et rent arbeidsområde som ikke blir tilstoppet.

Selve løsningen er enkel og åpenbar og lar deg få noen fordeler. Ja, inngangsterskelen har steget litt sammenlignet med enkle kommandoer for monteringer, men nå er det en garanti for at den alltid vil bli bygget og utvikleren selv kan velge alt som er nødvendig for byggeprosessen hans.

Du kan også bruke bildet jeg har samlet Jenkins + Docker. Alle kilder er åpne og ligger kl rmuhamedgaliev/jenkins_docker.

Mens du skrev denne artikkelen oppsto det en diskusjon om bruk av agenter på eksterne servere for ikke å laste masternoden ved hjelp av en plugin docker-plugin. Men jeg skal snakke om dette i fremtiden.

Kilde: www.habr.com

Legg til en kommentar