Hur man samlar projekt i Jenkins om mÄnga olika miljöer behövs

Hur man samlar projekt i Jenkins om mÄnga olika miljöer behövs

Det finns mÄnga artiklar om Jenkins pÄ Habré, men fÄ stÀllen beskriver exempel pÄ hur Jenkins och Docker-agenter fungerar. Alla populÀra projektbyggverktyg som Drone.io, Bitbucket Pipeline, GitLab, GitHub Actions och andra kan bygga allt i containrar. Men hur fungerar Jenkins?

Idag finns det en lösning pÄ problemet: Jenkins 2 fungerar utmÀrkt med Docker-agenter. I den hÀr artikeln vill jag dela med mig av mina erfarenheter och visa hur du kan göra detta sjÀlv.

Varför började jag lösa detta problem?

Eftersom vi pÄ företaget Citronium anvÀnder mÄnga olika teknologier, mÄste byggmaskinen ha olika versioner av Node.JS, Gradle, Ruby, JDK och andra. Men det Àr ofta oundvikligt med versionskonflikter. Ja, du har rÀtt om du sÀger att det finns olika versionshanterare som nvm, rvm, men det Àr inte alltid sÄ enkelt med dem och dessa lösningar har sina problem:

  • stora mĂ€ngder av runtime-miljöer som utvecklare glömmer att rensa;
  • det finns konflikter mellan olika versioner av samma runtime-miljöer;
  • varje utvecklare behöver olika uppsĂ€ttningar av komponenter.

Det finns andra problem, men lÄt mig hellre berÀtta om lösningen.

Jenkins i Docker

Eftersom Docker nu har fÄtt ett starkt fÀste inom utvecklingsvÀrlden kan nÀstan allt köras med hjÀlp av Docker. Min lösning Àr att Jenkins ska köras i Docker och kunna starta andra Docker-containrar. Denna frÄga började diskuteras redan 2013 i artikeln "Docker can now run within Docker«.

Kort sagt, det Àr nödvÀndigt att installera Docker i arbetscontainern och montera filen /var/run/docker.sock.

HÀr Àr ett exempel pÄ Dockerfile som skapades för 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

PÄ sÄ sÀtt fick vi en Docker-container som kan utföra Docker-kommandon pÄ vÀrdmaskinen.

InstÀllning av byggning

För inte sÄ lÀnge sedan fick Jenkins möjlighet att beskriva sina regler med Pipeline syntax, vilket gör det ganska enkelt att Àndra byggskriften och lagra den i ett repository.

LÄt oss sÀtta en speciell Dockerfile i sjÀlva arkivet som kommer att innehÄlla alla nödvÀndiga bibliotek för byggprocessen. PÄ sÄ sÀtt kan utvecklaren sjÀlv förbereda en reproducerbar miljö och behöver inte be OPS att installera en viss version av Node.JS pÄ vÀrden.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Den hÀr byggavbildningen passar för de flesta Node.JS-applikationer. Men om du till exempel behöver en avbildning för ett JVM-projekt med en inbyggd Sonar-scanner? Du har friheten att vÀlja de nödvÀndiga komponenterna för byggprocessen.

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 har beskrivit byggmiljön, men vad har Jenkins med saken att göra? Jenkins-agenter kan arbeta med sÄdana Docker-avbilder och utföra byggprocesser inuti.

stage("Bygg 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"
    }
}

Direktiv agent anvÀnder egenskapen docker, dÀr du kan ange:

  • namnet pĂ„ byggcontainern enligt din namngivningspolicy;
  • de argument som behövs för att köra byggcontainern, dĂ€r vi i vĂ„rt fall monterar den aktuella katalogen som en katalog inuti containern.

Och redan i byggstegen anger vi vilka kommandon som ska köras inuti bygg-Docker-agenten. Det kan vara vad som helst, pÄ sÄ sÀtt utför jag Àven distribution av applikationer med hjÀlp av ansible.

Nedan vill jag visa en allmÀn Jenkinsfile som kan bygga en enkel Node.JS-applikation.

def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""

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

    agent any

    stages {

        stage("Förbered byggbild") {
            steps {
                sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
            }
        }

        stage("Bygg 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()
        }
    }

}

Vad blev resultatet?

Genom denna metod löste vi följande problem:

  • tiden för att konfigurera byggmiljön reduceras till 10 - 15 minuter per projekt;
  • en helt reproducerbar byggmiljö, eftersom den kan byggas Ă€ven pĂ„ den lokala datorn;
  • inga problem med konflikter mellan olika versioner av byggverktyg;
  • alltid en ren arbetsyta som inte blir överbelastad.

SjÀlva lösningen Àr enkel och uppenbar och ger enbart fördelar. Ja, intrÀdesbarriÀren har höjts nÄgot jÀmfört med enklare byggkommandon, men nu finns det en garanti pÄ att bygget alltid kommer att lyckas och utvecklaren kan sjÀlv vÀlja allt som behövs i sin byggprocess.

Du kan ocksÄ anvÀnda den bild jag har byggt Jenkins + Docker. All kÀllkod Àr öppen och ligger pÄ rmuhamedgaliev/jenkins_docker.

Under skrivandet av artikeln uppstod en diskussion om anvÀndningen av agenter pÄ fjÀrrservrar för att inte belasta huvudnoden med hjÀlp av pluginet docker-plugin. Men det kommer jag att berÀtta om i framtiden.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster