如果您需要許多不同的環境,如何在 Jenkins 中收集項目

如果您需要許多不同的環境,如何在 Jenkins 中收集項目

Habré 上有很多關於 Jenkins 的文章,但很少有描述 Jenkins 和 docker 代理如何運作的範例。 所有流行的項目建立工具,例如 無人機大作戰, 位桶管道, GitLab, GitHub 操作 和其他人,可以將所有東西收集到容器中。 但是詹金斯呢?

今天這個問題有了解決方案:Jenkins 2 非常擅長與 Docker 代理。 在這篇文章中,我想分享我的經驗,並向您展示如何自己做到這一點。

我為什麼開始解決這個問題?

既然我們在公司 香櫞 因為我們使用許多不同的技術,所以我們必須在組裝機上保留不同版本的 Node.JS、Gradle、Ruby、JDK 等。 但版本衝突往往是無法避免的。 是的,如果你說有像 nvm、rvm 這樣的各種版本管理器,那麼你是對的,但它們並不是一切都那麼順利,這些解決方案也存在問題:

  • 開發人員忘記清理大量運行時;
  • 同一運行時的不同版本之間存在衝突;
  • 每個開發人員都需要一組不同的組件。

還有其他問題,但讓我告訴你解決方案。

Docker 中的詹金斯

由於 Docker 現在在開發領域已經很成熟,幾乎任何東西都可以使用 Docker 運行。 我的解決方案是讓 Jenkins 位於 Docker 並能夠運行其他 Docker 容器。 這個問題早在 2013 年的文章《Docker 現在可以在 Docker 中運行“。

簡而言之,你只需要在工作容器中安裝 Docker 本身並掛載文件 /var/run/docker.sock.

下面是為 Jenkins 產生的 Dockerfile 範例。

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

這樣,我們就得到了一個可以在宿主機上執行Docker指令的Docker容器。

建置設定

不久前 Jenkins 有機會使用以下方式描述其規則 管道 語法,這使得更改建置腳本並將其儲存在儲存庫中變得非常容易。

因此,讓我們在儲存庫本身中放置一個特殊的 Dockerfile,其中包含建置所需的所有庫。 這樣,開發者可以自己準備一個可重複的環境,而不必要求OPS在主機上安裝特定版本的Node.JS。

FROM node:12.10.0-alpine

RUN npm install yarn -g

此建置映像適用於大多數 Node.JS 應用程式。 例如,如果您需要一個 JVM 專案的映像,其中包含聲納掃描儀,該怎麼辦? 您可以自由選擇組裝所需的組件。

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/

我們描述了組裝環境,但是 Jenkins 與它有什麼關係呢? Jenkins 代理程式可以使用此類 Docker 映像並在內部建置它們。

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

指示 agent 使用財產 docker您可以在其中指定:

  • 根據您的命名策略的組件容器的名稱;
  • 運行建置容器所需的參數,在我們的例子中,我們將目前目錄掛載為容器內的目錄。

在建置步驟中,我們已經指示了要在 Docker 建置代理程式內執行哪些命令。 這可以是任何東西,所以我還使用 ansible 啟動應用程式部署。

下面我想展示一個簡單的 Node.JS 應用程式可以建立的通用 Jenkinsfile。

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

}

發生了什麼事?

透過這種方法,我們解決了以下問題:

  • 每個項目的環境組裝配置時間減少至 10 - 15 分鐘;
  • 完全可重複的應用程式建構環境,因為您可以在本機電腦上以這種方式建構它;
  • 不存在不同版本組裝工具衝突的問題;
  • 始終保持乾淨、不會阻塞的工作空間。

解決方案本身簡單明了,並且可以讓您獲得一些優勢。 是的,與程序集的簡單命令相比,入門門檻有所提高,但現在可以保證它將始終被構建,並且開發人員自己可以選擇其構建過程所需的一切。

您也可以使用我收集的圖片 詹金斯+碼頭工人。 所有來源都是開放的,位於 rmuhamedgaliev/jenkins_docker.

在撰寫本文時,出現了關於在遠端伺服器上使用代理以避免使用插件載入主節點的討論 docker-插件。 但我以後會談到這個問題。

來源: www.habr.com

添加評論