Wie man in Jenkins Projekte erstellt, wenn viele verschiedene Umgebungen benötigt werden

Wie man in Jenkins Projekte erstellt, wenn viele verschiedene Umgebungen benötigt werden

Auf Habr gibt es viele Artikel über Jenkins, aber nur wenige beschreiben ein Beispiel für die Arbeit von Jenkins und Docker-Agenten. Alle gängigen Build-Tools wie Drone.io, Bitbucket Pipeline, GitLab, GitHub Actions und andere können alles in Containern bauen. Aber wie steht es um Jenkins?

Heutzutage gibt es eine Lösung für dieses Problem: Jenkins 2 kann hervorragend mit Docker-Agentenarbeiten. In diesem Artikel möchte ich meine Erfahrung teilen und Ihnen zeigen, wie Sie es selbst machen können.

Warum habe ich mich mit diesem Problem beschäftigt?

Da wir in der Firma Citronium eine Vielzahl von Technologien verwenden, muss auf der Build-Maschine eine Vielzahl von Versionen wie Node.JS, Gradle, Ruby, JDK und andere gehalten werden. Aber oft sind Versionskonflikte unvermeidbar. Ja, Sie haben recht, wenn Sie sagen, dass es verschiedene Version-Manager wie nvm, rvm gibt, aber es ist nicht immer so reibungslos und diese Lösungen haben ihre Probleme:

  • eine große Menge an Runtimes, die die Entwickler vergessen zu bereinigen;
  • es gibt Konflikte zwischen verschiedenen Versionen derselben Runtimes;
  • jeder Entwickler benötigt ein unterschiedliches Set an Komponenten.

Es gibt auch andere Probleme, aber lassen Sie mich lieber über die Lösung sprechen.

Jenkins in Docker

Da Docker sich mittlerweile gut im Entwicklungsbereich etabliert hat, kann fast alles mit Docker gestartet werden. Mein Vorschlag ist, Jenkins in Docker auszuführen, sodass es andere Docker-Container starten kann. Diese Frage wurde bereits 2013 in dem Artikel "Docker kann jetzt innerhalb von Docker ausgeführt werden.«.

Kurz gefasst, Sie müssen Docker im Arbeitscontainer installieren und eine Datei einbinden. /var/run/docker.sock.

Hier ist ein Beispiel für einen Dockerfile, der für Jenkins erstellt wurde.

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

So haben wir einen Docker-Container erhalten, der Docker-Befehle auf der Hostmaschine ausführen kann.

Build-Konfiguration

Vor kurzem hat Jenkins die Möglichkeit hinzugefügt, seine Regeln mit Pipeline Syntax, was es ermöglicht, das Build-Skript recht einfach zu ändern und in einem Repository zu speichern.

Lassen Sie uns also eine spezielle Dockerfile in das Repository legen, das alle notwendigen Bibliotheken für den Build enthalten wird. So kann der Entwickler eine wiederholbare Umgebung vorbereiten, ohne die OPS bitten zu müssen, eine bestimmte Version von Node.JS auf dem Host zu installieren.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Solch ein Build-Image eignet sich für die meisten Node.JS-Anwendungen. Und falls Sie beispielsweise ein Image für ein JVM-Projekt mit integriertem Sonar-Scanner benötigen? Sie können selbst die benötigten Komponenten für den Build auswählen.

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/

Wir haben die Build-Umgebung beschrieben, aber was hat Jenkins damit zu tun? Jenkins-Agents können mit solchen Docker-Images arbeiten und den Build innerhalb durchführen.

stage("Projekt bauen") {
    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"
    }
}

Direktive agent verwendet die Eigenschaft docker, wo Sie angeben können:

  • den Namen des Build-Containers gemäß Ihrer Namenskonvention;
  • die Argumente, die für den Start des Build-Containers erforderlich sind, wobei wir in unserem Fall das aktuelle Verzeichnis als Verzeichnis innerhalb des Containers mounten.

In den Build-Schritten geben wir dann an, welche Befehle innerhalb des Build-Docker-Agenten ausgeführt werden sollen. Das kann alles Mögliche sein; so starte ich auch den Deployment-Prozess von Anwendungen mit Ansible.

Im Folgenden möchte ich einen allgemeinen Jenkinsfile zeigen, der eine einfache Node.JS-Anwendung bauen kann.

def DOCKER_IMAGE_BRANCH = ""
def GIT_COMMIT_HASH = ""

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

    agent any

    stages {

        stage("Build-Image vorbereiten") {
            steps {
                sh "docker build -f Dockerfile.build . -t project-build:${DOCKER_IMAGE_BRANCH}"
            }
        }

        stage("Projekt bauen") {
            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()
        }
    }

}

Was ist das Ergebnis?

Durch diese Methode haben wir folgende Probleme gelöst:

  • die Konfigurationszeit für die Build-Umgebung beträgt nun 10 - 15 Minuten pro Projekt;
  • eine vollständig reproduzierbare Build-Umgebung für die Anwendung, da dieselbe auch lokal aufgebaut werden kann;
  • keine Probleme mit Konflikten verschiedener Versionen von Build-Tools;
  • immer ein sauberer Arbeitsbereich, der nicht überfüllt wird.

Die Lösung ist an sich einfach und offensichtlich und bietet ausschließlich Vorteile. Ja, die Einstiegshürde ist im Vergleich zu einfachen Befehlen für Builds etwas gestiegen, aber dafür gibt es jetzt die Garantie, dass immer gebaut wird, und der Entwickler kann selbst entscheiden, was er für seinen Build-Prozess benötigt.

Außerdem können Sie das von mir erstellte Image nutzen. Jenkins + Docker. Alle Quellcodes sind offen und finden Sie unter rmuhamedgaliev/jenkins_docker.

Im Verlauf des Schreibens des Artikels entstand eine Diskussion über den Einsatz von Agenten auf Remote-Servern, um die Master-Node nicht zu belasten, mithilfe des Plugins docker-plugin. Darüber werde ich in Zukunft berichten.

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster