Jak zbierać projekty w Jenkins, jeśli potrzebujesz wielu różnych środowisk

Jak zbierać projekty w Jenkins, jeśli potrzebujesz wielu różnych środowisk

Istnieje wiele artykułów na temat Habré na temat Jenkinsa, ale niewiele opisuje przykłady działania Jenkinsa i agentów dokerów. Wszystkie popularne narzędzia do tworzenia projektów, takie jak Drone.io, Rurociąg Bitbucketa, GitLab, Działania GitHuba i inni, mogą zebrać wszystko w pojemnikach. Ale co z Jenkinsem?

Dzisiaj istnieje rozwiązanie tego problemu: Jenkins 2 świetnie się z nim pracuje Agenci Dockera. W tym artykule chcę podzielić się swoim doświadczeniem i pokazać, jak możesz to zrobić samodzielnie.

Dlaczego zacząłem rozwiązywać ten problem?

Ponieważ jesteśmy w towarzystwie Cytron Ponieważ używamy wielu różnych technologii, musimy trzymać na maszynie montażowej różne wersje Node.JS, Gradle, Ruby, JDK i innych. Często jednak nie da się uniknąć konfliktów wersji. Tak, będziesz miał rację, jeśli powiesz, że istnieją różne menedżery wersji, takie jak nvm, rvm, ale nie wszystko jest z nimi tak płynne i te rozwiązania mają problemy:

  • duża ilość środowiska wykonawczego, o której programiści zapominają wyczyścić;
  • istnieją konflikty między różnymi wersjami tych samych środowisk wykonawczych;
  • Każdy programista potrzebuje innego zestawu komponentów.

Istnieją inne problemy, ale pozwól, że przedstawię Ci rozwiązanie.

Jenkins w Dockerze

Ponieważ Docker jest obecnie dobrze ugruntowany w świecie programistów, prawie wszystko można uruchomić za jego pomocą. Moje rozwiązanie polega na posiadaniu Jenkinsa w Dockerze i możliwości uruchamiania innych kontenerów Docker. To pytanie zaczęto zadawać już w 2013 roku w artykule „Docker może teraz działać w Dockerze".

Krótko mówiąc, wystarczy zainstalować samego Dockera w działającym kontenerze i zamontować plik /var/run/docker.sock.

Oto przykładowy plik Dockerfile, który okazał się dla Jenkinsa.

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

W ten sposób otrzymaliśmy kontener Dockera, który może wykonywać polecenia Dockera na komputerze-hoście.

Konfiguracja kompilacji

Niedawno Jenkins miał okazję opisać jego zasady za pomocą Rurociąg składnię, co sprawia, że ​​dość łatwo jest zmienić skrypt kompilacji i zapisać go w repozytorium.

Umieśćmy więc w samym repozytorium specjalny plik Dockerfile, który będzie zawierał wszystkie biblioteki niezbędne do kompilacji. W ten sposób programista może sam przygotować powtarzalne środowisko i nie będzie musiał prosić OPS o zainstalowanie konkretnej wersji Node.JS na hoście.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Ten obraz kompilacji jest odpowiedni dla większości aplikacji Node.JS. A co jeśli na przykład potrzebujesz obrazu do projektu JVM z dołączonym skanerem Sonar? Możesz dowolnie wybierać komponenty potrzebne do montażu.

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/

Opisaliśmy środowisko asemblera, ale co ma z tym wspólnego Jenkins? Agenci Jenkinsa mogą pracować z takimi obrazami Dockera i tworzyć je wewnętrznie.

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

Dyrektywa agent korzysta z własności dockergdzie możesz określić:

  • nazwę kontenera montażowego zgodnie z Twoją polityką nazewnictwa;
  • argumenty potrzebne do uruchomienia kontenera kompilacji, gdzie w naszym przypadku montujemy bieżący katalog jako katalog wewnątrz kontenera.

Już na etapie kompilacji wskazujemy, które polecenia należy wykonać w agencie kompilacji Docker. Może to być cokolwiek, więc uruchamiam także wdrażanie aplikacji za pomocą ansible.

Poniżej chcę pokazać ogólny plik Jenkinsfile, który może zbudować prosta aplikacja Node.JS.

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

}

Co się stało?

Dzięki tej metodzie rozwiązaliśmy następujące problemy:

  • czas konfiguracji zestawu środowiska został skrócony do 10 - 15 minut na projekt;
  • całkowicie powtarzalne środowisko budowania aplikacji, ponieważ możesz je zbudować w ten sposób na swoim komputerze lokalnym;
  • nie ma problemów z konfliktami pomiędzy różnymi wersjami narzędzi montażowych;
  • zawsze czyste miejsce pracy, które się nie zatyka.

Samo rozwiązanie jest proste i oczywiste, a pozwala uzyskać pewne korzyści. Tak, próg wejścia nieco wzrósł w porównaniu z prostymi poleceniami dla złożeń, ale teraz istnieje gwarancja, że ​​zawsze zostanie zbudowany, a sam programista będzie mógł wybrać wszystko, co jest niezbędne do jego procesu kompilacji.

Możesz także użyć zebranego przeze mnie obrazu Jenkins + Docker. Wszystkie źródła są otwarte i zlokalizowane pod adresem rmuhamedgaliev/jenkins_docker.

Podczas pisania tego artykułu wywiązała się dyskusja na temat używania agentów na zdalnych serwerach, aby nie ładować węzła głównego za pomocą wtyczki wtyczka dokująca. Ale o tym opowiem w przyszłości.

Źródło: www.habr.com

Dodaj komentarz