Paano mangolekta ng mga proyekto sa Jenkins kung kailangan mo ng maraming iba't ibang kapaligiran

Paano mangolekta ng mga proyekto sa Jenkins kung kailangan mo ng maraming iba't ibang kapaligiran

Maraming mga artikulo sa HabrΓ© tungkol kay Jenkins, ngunit kakaunti ang naglalarawan ng mga halimbawa kung paano gumagana ang mga ahente ng Jenkins at docker. Lahat ng mga sikat na tool sa pagbuo ng proyekto tulad ng Drone.io, Bitbucket Pipeline, GitLab, Mga pagkilos sa GitHub at iba pa, maaaring kolektahin ang lahat sa mga lalagyan. Pero paano si Jenkins?

Ngayon ay may solusyon sa problema: Ang Jenkins 2 ay mahusay sa pakikipagtulungan Mga ahente ng docker. Sa artikulong ito nais kong ibahagi ang aking karanasan at ipakita kung paano mo ito magagawa sa iyong sarili.

Bakit ko sinimulang lutasin ang problemang ito?

Since nasa company kami Citronium Dahil gumagamit kami ng maraming iba't ibang teknolohiya, kailangan naming panatilihin ang iba't ibang bersyon ng Node.JS, Gradle, Ruby, JDK at iba pa sa assembly machine. Ngunit kadalasan ang mga salungatan sa bersyon ay hindi maiiwasan. Oo, magiging tama ka kung sasabihin mo na mayroong iba't ibang mga tagapamahala ng bersyon tulad ng nvm, rvm, ngunit hindi lahat ay maayos sa kanila at ang mga solusyon na ito ay may mga problema:

  • isang malaking halaga ng runtime na nakalimutan ng mga developer na linisin;
  • may mga salungatan sa pagitan ng iba't ibang bersyon ng parehong mga runtime;
  • Ang bawat developer ay nangangailangan ng iba't ibang hanay ng mga bahagi.

Mayroong iba pang mga problema, ngunit hayaan mo akong sabihin sa iyo ang tungkol sa solusyon.

Jenkins sa Docker

Dahil ang Docker ay matatag na ngayon sa mundo ng pag-unlad, halos anumang bagay ay maaaring patakbuhin gamit ang Docker. Ang aking solusyon ay ang magkaroon ng Jenkins sa Docker at makapagpatakbo ng iba pang mga lalagyan ng Docker. Ang tanong na ito ay nagsimulang itanong noong 2013 sa artikulong "Maaari na ngayong tumakbo ang Docker sa loob ng Docker".

Sa madaling salita, kailangan mo lang i-install ang Docker mismo sa isang gumaganang lalagyan at i-mount ang file /var/run/docker.sock.

Narito ang isang halimbawa ng Dockerfile na naging para kay 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

Kaya, nakakuha kami ng lalagyan ng Docker na maaaring magsagawa ng mga utos ng Docker sa host machine.

Bumuo ng setup

Hindi nagtagal, nagkaroon ng pagkakataon si Jenkins na ilarawan ang mga panuntunan nito gamit Padaanin sa tubo syntax, na ginagawang medyo madaling baguhin ang build script at iimbak ito sa repository.

Kaya't maglagay tayo ng isang espesyal na Dockerfile sa repositoryo mismo, na maglalaman ng lahat ng mga aklatan na kinakailangan para sa pagbuo. Sa ganitong paraan, ang developer mismo ay makakapaghanda ng isang umuulit na kapaligiran at hindi na kailangang hilingin sa OPS na mag-install ng isang partikular na bersyon ng Node.JS sa host.

FROM node:12.10.0-alpine

RUN npm install yarn -g

Ang build na imahe na ito ay angkop para sa karamihan ng mga application ng Node.JS. Paano kung, halimbawa, kailangan mo ng isang imahe para sa isang proyekto ng JVM na may kasamang Sonar scanner sa loob? Malaya kang pumili ng mga sangkap na kailangan mo para sa pagpupulong.

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/

Inilarawan namin ang kapaligiran ng pagpupulong, ngunit ano ang kinalaman ni Jenkins dito? At ang mga ahente ng Jenkins ay maaaring gumana sa mga naturang Docker na imahe at bumuo ng mga ito sa loob.

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

Direktiba agent gumagamit ng ari-arian dockerkung saan maaari mong tukuyin:

  • ang pangalan ng lalagyan ng pagpupulong ayon sa iyong patakaran sa pagbibigay ng pangalan;
  • mga argumento na kailangan upang patakbuhin ang build container, kung saan sa aming kaso ini-mount namin ang kasalukuyang direktoryo bilang isang direktoryo sa loob ng container.

At nasa mga hakbang na ng build, ipinapahiwatig namin kung aling mga utos ang isasagawa sa loob ng ahente ng build ng Docker. Maaari itong maging anuman, kaya inilunsad ko rin ang pag-deploy ng application gamit ang ansible.

Sa ibaba gusto kong magpakita ng generic na Jenkinsfile na maaaring buuin ng isang simpleng Node.JS application.

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

}

Anong nangyari?

Salamat sa pamamaraang ito, nalutas namin ang mga sumusunod na problema:

  • ang oras ng pagsasaayos ng pagpupulong ng kapaligiran ay binabawasan sa 10 - 15 minuto bawat proyekto;
  • isang ganap na repeatable application build environment, dahil maaari mo itong buuin sa ganitong paraan sa iyong lokal na computer;
  • walang mga problema sa mga salungatan sa pagitan ng iba't ibang mga bersyon ng mga tool sa pagpupulong;
  • palaging isang malinis na workspace na hindi nababara.

Ang solusyon mismo ay simple at halata at nagbibigay-daan sa iyo upang makakuha ng ilang mga pakinabang. Oo, ang entry threshold ay tumaas ng kaunti kumpara sa mga simpleng utos para sa mga pagtitipon, ngunit ngayon ay may garantiya na ito ay palaging itatayo at ang developer mismo ay maaaring pumili ng lahat ng kailangan para sa kanyang proseso ng pagbuo.

Maaari mo ring gamitin ang larawang nakolekta ko Jenkins + Docker. Ang lahat ng mga mapagkukunan ay bukas at matatagpuan sa rmuhamedgaliev/jenkins_docker.

Habang isinusulat ang artikulong ito, lumitaw ang isang talakayan tungkol sa paggamit ng mga ahente sa mga malalayong server upang hindi mai-load ang master node gamit ang isang plugin docker-plugin. Ngunit pag-uusapan ko ito sa hinaharap.

Pinagmulan: www.habr.com

Magdagdag ng komento