Sådan samler du projekter i Jenkins, hvis du har brug for mange forskellige miljøer

Sådan samler du projekter i Jenkins, hvis du har brug for mange forskellige miljøer

Der er mange artikler på Habré om Jenkins, men få beskriver eksempler på, hvordan Jenkins og havnearbejdere arbejder. Alle populære projektbyggerværktøjer som Drone.io, Bitbucket Pipeline, GitLab, GitHub-handlinger og andre, kan samle alt i containere. Men hvad med Jenkins?

I dag er der en løsning på problemet: Jenkins 2 er fantastisk til at arbejde med Docker-agenter. I denne artikel vil jeg dele min erfaring og vise, hvordan du selv kan gøre det.

Hvorfor begyndte jeg at løse dette problem?

Da vi er i selskab Citronium Fordi vi bruger mange forskellige teknologier, er vi nødt til at beholde forskellige versioner af Node.JS, Gradle, Ruby, JDK og andre på samlemaskinen. Men ofte kan versionskonflikter ikke undgås. Ja, du vil have ret, hvis du siger, at der er forskellige versionsadministratorer som nvm, rvm, men ikke alt er så glat med dem, og disse løsninger har problemer:

  • en stor mængde runtime, som udviklere glemmer at rense;
  • der er konflikter mellem forskellige versioner af de samme kørselstider;
  • Hver udvikler har brug for et andet sæt komponenter.

Der er andre problemer, men lad mig fortælle dig om løsningen.

Jenkins i Docker

Da Docker nu er veletableret i udviklingsverdenen, kan næsten alt køres ved hjælp af Docker. Min løsning er at have Jenkins i Docker og kunne køre andre Docker-containere. Dette spørgsmål begyndte at blive stillet tilbage i 2013 i artiklen "Docker kan nu køre i Docker".

Kort sagt, du skal bare installere Docker selv i en fungerende container og montere filen /var/run/docker.sock.

Her er et eksempel på Dockerfile, der viste sig 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

Således fik vi en Docker-container, der kan udføre Docker-kommandoer på værtsmaskinen.

Byg opsætning

For ikke længe siden fik Jenkins muligheden for at beskrive sine regler ved hjælp af Pipeline syntaks, hvilket gør det ret nemt at ændre build-scriptet og gemme det i depotet.

Så lad os lægge en speciel Dockerfile i selve depotet, som vil indeholde alle de biblioteker, der er nødvendige for opbygningen. På denne måde kan udvikleren selv forberede et gentageligt miljø og behøver ikke at bede OPS om at installere en specifik version af Node.JS på værten.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Dette build-billede er velegnet til de fleste Node.JS-applikationer. Hvad hvis du for eksempel har brug for et billede til et JVM-projekt med en ekkolodsscanner inkluderet indeni? Du kan frit vælge de komponenter, du skal bruge til 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 hvad har Jenkins med det at gøre? Og Jenkins-agenter kan arbejde med sådanne Docker-billeder 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 bruger ejendom dockerhvor du kan angive:

  • navnet på samlebeholderen i henhold til din navnepolitik;
  • nødvendige argumenter for at køre build-containeren, hvor vi i vores tilfælde monterer den aktuelle mappe som en mappe inde i containeren.

Og allerede i build-trinene angiver vi, hvilke kommandoer der skal udføres inde i Docker build-agenten. Dette kan være hvad som helst, så jeg starter også applikationsimplementering ved hjælp af ansible.

Nedenfor vil jeg vise en generisk Jenkinsfil, som en simpel Node.JS-applikation 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()
        }
    }

}

Hvad skete der?

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

  • Konfigurationstiden for miljømontering reduceres til 10 - 15 minutter pr. projekt;
  • et fuldstændigt gentageligt applikationsopbygningsmiljø, da du kan bygge det på denne måde på din lokale computer;
  • der er ingen problemer med konflikter mellem forskellige versioner af monteringsværktøjer;
  • altid et rent arbejdsområde, der ikke bliver tilstoppet.

Selve løsningen er enkel og indlysende og giver dig mulighed for at få nogle fordele. Ja, indgangstærsklen er steget lidt i forhold til simple kommandoer til samlinger, men nu er der garanti for, at den altid vil blive bygget, og udvikleren selv kan vælge alt, hvad der er nødvendigt for hans byggeproces.

Du kan også bruge det billede, jeg har samlet Jenkins + Docker. Alle kilder er åbne og placeret kl rmuhamedgaliev/jenkins_docker.

Under skrivningen af ​​denne artikel opstod en diskussion om brug af agenter på fjernservere for ikke at indlæse masterknuden ved hjælp af et plugin docker-plugin. Men jeg vil tale om dette i fremtiden.

Kilde: www.habr.com

Tilføj en kommentar