Com recollir projectes a Jenkins si necessiteu molts entorns diferents

Com recollir projectes a Jenkins si necessiteu molts entorns diferents

Hi ha molts articles sobre Habré sobre Jenkins, però pocs descriuen exemples de com funcionen Jenkins i els agents docker. Totes les eines populars de creació de projectes com Drone.io, Bitbucket Pipeline, GitLab, Accions de GitHub i altres, poden recollir-ho tot en contenidors. Però què passa amb Jenkins?

Avui hi ha una solució al problema: Jenkins 2 és fantàstic per treballar Agents Docker. En aquest article vull compartir la meva experiència i mostrar com pots fer-ho tu mateix.

Per què vaig començar a resoldre aquest problema?

Ja que estem en companyia Citronium Com que fem servir moltes tecnologies diferents, hem de mantenir diferents versions de Node.JS, Gradle, Ruby, JDK i d'altres a la màquina de muntatge. Però sovint els conflictes de versions no es poden evitar. Sí, tindreu raó si dieu que hi ha diversos gestors de versions com nvm, rvm, però no tot és tan fluid amb ells i aquestes solucions tenen problemes:

  • una gran quantitat de temps d'execució que els desenvolupadors obliden netejar;
  • hi ha conflictes entre diferents versions dels mateixos temps d'execució;
  • Cada desenvolupador necessita un conjunt diferent de components.

Hi ha altres problemes, però deixeu-me que us expliqui la solució.

Jenkins a Docker

Com que Docker està ben establert al món del desenvolupament, gairebé qualsevol cosa es pot executar amb Docker. La meva solució és tenir Jenkins a Docker i poder executar altres contenidors Docker. Aquesta pregunta es va començar a fer el 2013 a l'article "Docker ara es pot executar dins de Docker".

En resum, només cal instal·lar Docker en un contenidor que funcioni i muntar el fitxer /var/run/docker.sock.

Aquí teniu un exemple de Dockerfile que va resultar per a 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

Així, tenim un contenidor Docker que pot executar ordres Docker a la màquina amfitriona.

Configuració de la construcció

No fa molt, Jenkins va tenir l'oportunitat de descriure les seves regles utilitzant Canonada sintaxi, que fa que sigui bastant fàcil canviar l'script de compilació i emmagatzemar-lo al repositori.

Per tant, posem un Dockerfile especial al mateix repositori, que contindrà totes les biblioteques necessàries per a la compilació. D'aquesta manera, el propi desenvolupador pot preparar un entorn repetible i no haurà de demanar a OPS que instal·li una versió específica de Node.JS a l'amfitrió.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Aquesta imatge de compilació és adequada per a la majoria d'aplicacions Node.JS. Què passa si, per exemple, necessiteu una imatge per a un projecte JVM amb un escàner Sonar inclòs a l'interior? Podeu triar els components que necessiteu per al muntatge.

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/

Hem descrit l'entorn de muntatge, però què hi té a veure Jenkins? I els agents de Jenkins poden treballar amb aquestes imatges de Docker i crear-les internament.

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

Directiva agent utilitza propietats dockeron pots especificar:

  • el nom del contenidor de muntatge segons la vostra política de denominació;
  • arguments necessaris per executar el contenidor de compilació, on en el nostre cas muntem el directori actual com a directori dins del contenidor.

I ja als passos de compilació indiquem quines ordres cal executar dins de l'agent de compilació de Docker. Això pot ser qualsevol cosa, així que també inicio el desplegament d'aplicacions amb ansible.

A continuació, vull mostrar un fitxer Jenkinsgen genèric que pot crear una aplicació Node.JS senzilla.

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

}

Què va passar?

Gràcies a aquest mètode hem resolt els següents problemes:

  • el temps de configuració del muntatge de l'entorn es redueix a 10 - 15 minuts per projecte;
  • un entorn de creació d'aplicacions completament repetible, ja que podeu crear-lo d'aquesta manera al vostre ordinador local;
  • no hi ha problemes amb conflictes entre diferents versions d'eines de muntatge;
  • sempre un espai de treball net que no s'obstrueixi.

La solució en si és senzilla i òbvia i us permet obtenir alguns avantatges. Sí, el llindar d'entrada ha augmentat una mica en comparació amb les ordres simples per a muntatges, però ara hi ha la garantia que sempre es construirà i el mateix desenvolupador pot triar tot el que sigui necessari per al seu procés de construcció.

També podeu utilitzar la imatge que vaig recopilar Jenkins + Docker. Totes les fonts estan obertes i es troben a rmuhamedgaliev/jenkins_docker.

Mentre escrivia aquest article, va sorgir una discussió sobre l'ús d'agents en servidors remots per no carregar el node mestre mitjançant un connector docker-plugin. Però d'això en parlaré en el futur.

Font: www.habr.com

Afegeix comentari