
Habr 上有很多關於 Jenkins 的文章,但很少有文章描述 Jenkins 和 Docker 代理的範例。所有流行的項目建立工具如 , , , 其他人可以將所有東西收集到容器中。但是詹金斯怎麼樣?
如今,這個問題有了解決方案:Jenkins 2 非常適合與 。在本文中,我想分享我的經驗並展示如何自己做到這一點。
我為什麼要開始解決這個問題?
因為我們在公司 由於我們使用了許多不同的技術,因此我們必須在建置機器上保留 Node.JS、Gradle、Ruby、JDK 和其他軟體的不同版本。但版本之間的衝突往往是無法避免的。是的,如果您說有各種版本管理器(如 nvm、rvm),那麼您是對的,但並非一切都如此順利,並且這些解決方案有問題:
- 開發人員忘記清理大量運行時;
- 同一運行時的不同版本之間存在衝突;
- 每個開發人員都需要一組不同的組件。
還有其他問題,但讓我告訴你解決方案。
Docker 中的 Jenkins
由於 Docker 現在已在開發領域確立了良好的地位,因此幾乎所有東西都可以使用 Docker 來運作。我的解決方案是讓 Jenkins 進入 Docker 並能夠運行其他 Docker 容器。這個問題最早是在 2013 年的文章““。
簡而言之,你只需要將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 應用程式。但是,例如,如果您需要包含 Sonar 掃描器的專案的 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分鐘;
- 完全可重複的應用程式建構環境,因為它也可以在本機電腦上建置;
- 不同版本的建置工具之間不存在衝突的問題;
- 始終保持工作空間整潔,不會雜亂。
解決方案本身簡單而明顯,並且只會讓您獲得優勢。是的,與簡單的構建命令相比,進入門檻有所增加,但現在可以保證它始終能夠構建,並且開發人員可以選擇構建過程所需的一切。
你也可以使用我編譯的圖像 。所有來源都是開放的,位於 .
在撰寫本文時,有人討論了在遠端伺服器上使用代理,以避免使用插件載入主節點。 。但我以後會告訴你這件事。
來源: www.habr.com
