1. 摘要
Jenkins是一個自動化服務(wù)器,目前發(fā)展超過15年耐薯,比較成熟的CI工具(也可以CD)能夠?qū)崿F(xiàn)自動化集成發(fā)布灶泵。
Jenkins構(gòu)件任務(wù)一般有2種,一種是“構(gòu)建一個自由風(fēng)格的軟件項目”和“流水線”項目羊精。本文講解的是使用pipeline流水線搭建一個GO工程的持續(xù)集成任務(wù)的完整方法。
2. 實踐內(nèi)容
2.1 pipeline流水線簡介
本質(zhì)上囚玫,jenkins是一個自動化引擎喧锦,它支持許多自動模式。流水線向Jenkins添加了一組強大的工具抓督,支持用例燃少、簡單的持續(xù)集成到全面的持續(xù)交付流水線。 通過對一系列的發(fā)布任務(wù)建立標(biāo)準(zhǔn)的模板铃在,用戶可以利用更多流水線的特性阵具,比如:
代碼化: 流水線是在代碼中實現(xiàn)的,通常會存放到源代碼控制定铜,使團隊具有編輯怔昨、審查和更新他們項目的交付流水線的能力。
耐用性:流水線可以從Jenkins的master節(jié)點重啟后繼續(xù)運行宿稀。
可暫停的:流水線可以由人功輸入或批準(zhǔn)繼續(xù)執(zhí)行流水線趁舀。
解決復(fù)雜發(fā)布: 支持復(fù)雜的交付流程。例如循環(huán)祝沸、并行執(zhí)行矮烹。
可擴展性: 支持?jǐn)U展DSL和其他插件集成。
構(gòu)建一個可擴展是Jenkins的核心價值罩锐,流水線可以通過ShareLibrary的方式來擴展奉狈。
2.2 Jenkins環(huán)境準(zhǔn)備
2.2.1 配置Jenkins的SSH key
由于jenkins需要從gitlab上拉取代碼,通過ssh方式涩惑。所以需要在jenkins機器上安裝git仁期,并且將jenkins機器上生成的ssh密鑰的公鑰(id_rsa.pub中的內(nèi)容)添加到gitlab的ssh keys中。
配置username和Email竭恬,生成ssh密鑰
git config --global user.name "duncan.wang"
git config --global user.email "duncan.wang@artarva.com"
ssh-keygen -t rsa -C "duncan.wang@artarva.com"
拷貝公鑰內(nèi)容填到gitlab服務(wù)器跛蛋。
2.2.2 配置GitLab connections
(1)配置GitLab connections連接到gitlab拉取代碼使用,配置證書痊硕,使用gitlab api token赊级。
token從gitlab中獲取,在個人設(shè)置中有Access Token一欄岔绸,創(chuàng)建一個token理逊。
(2)在jenkins的系統(tǒng)管理/憑據(jù)管理(manageCredentials)/全局憑證/添加憑證橡伞,如下:
把gitlab創(chuàng)建的Feed token填寫到API token的位置,描述增加點說明晋被,例如"GITLAB的授權(quán)信息"兑徘,ID不用設(shè)置,會被Jenkins系統(tǒng)自動更新出來羡洛。
(3)在Jenkins的系統(tǒng)管理處配置gitlab授權(quán)配置
授權(quán)憑證選擇剛才配置的GitLab API token即可挂脑。可以點擊“Test Connection”翘县,返回顯示為"Success"表示連接成功。
Test Connection谴分,顯示success則表示配置成功锈麸。
(4)配置Jenkins所在服務(wù)器拉取代碼的服務(wù)器私鑰訪問憑證
該憑證用于在下面章節(jié)的流水線配置拉取代碼時以私鑰訪問憑證形式訪問目標(biāo)環(huán)境。此處的私鑰“Private Key”為“2.2.1 配置Jenkins的SSH key”產(chǎn)生的rsa_privatekey牺蹄。
2.2.3 配置管道任務(wù)梳理
丟棄舊的構(gòu)建配置為只保留7天忘伞,10個構(gòu)建版本。
2.3 創(chuàng)建流水線任務(wù)
(1)輸入命名“preproduct-training-ip-demo”沙兰,選擇流水線風(fēng)格氓奈。
(2)配置Gitlab連接
選擇 2.2.2 配置GitLab connections 配置的“artarva”連接。
(3)設(shè)置流水線腳本
#!/usr/bin/env groovy
def git_address = "git@101.132.137.193:trainingipmanagement/training-ip-demo.git"
def git_auth = "10a4d4f3-1977-486c-945f-31cfcd8c04db"
def git_branch = "dev"
pipeline {
agent { node { label "master"}}
stages {
stage('1.拉取代碼'){
steps {
//checkout([$class: 'GitSCM', branches: [[name: '${Branch}']], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
git branch: "${git_branch}", credentialsId: "${git_auth}", url: "${git_address}"
// }
}
}
stage('3.編譯程序'){
steps {
sh """
export GOPATH=/opt/GOPATH
export PATH=$PATH:\$GOPATH/bin
go build -o training-ip-demo main.go
cp training-ip-demo /home/training-ip-management/training-ip-demo
"""
}
}
stage('4.部署程序'){
steps {
script{
PROCESS_ID = sh(script: "ps aux|grep training-ip|grep -v grep|grep -v jenkins|awk \'{print \$2}\'", returnStdout: true).trim()
echo "${PROCESS_ID}"
if (PROCESS_ID != "") {
sh """
echo "Kill process: ${PROCESS_ID}"
sudo kill -9 ${PROCESS_ID}
"""
}
}
sh """
JENKINS_NODE_COOKIE=dontKillMe nohup /home/training-ip-management/training-ip-demo/training-ip-demo &
"""
}
}
}
post {
always{
script{
println("流水線結(jié)束后鼎天,經(jīng)常做的事情")
}
}
success{
script{
println("流水線成功后舀奶,要做的事情")
}
}
failure{
script{
println("流水線失敗后,要做的事情")
}
}
aborted{
script{
println("流水線取消后斋射,要做的事情")
}
}
}
}
(4) 立即構(gòu)建
點擊“立即構(gòu)建”育勺,根據(jù)輸出結(jié)果排查問題后即可完成流水線工作,包含
拉取Gitlab版本罗岖,編輯代碼涧至,部署程序這3個主要步驟。
本樣例暫時不包含2.代碼靜態(tài)檢查的步驟桑包,后面其他文章再涉及南蓬。
2.4 典型問題解答
2.4.1 流水線配置的程序后臺部署運行正常后即被關(guān)閉
問題現(xiàn)象:
在普通的shell環(huán)境中,nohup哑了,并且& 某個程序后赘方,會拋到后臺執(zhí)行,在退出當(dāng)前shell環(huán)境后弱左,程序依然可以執(zhí)行蒜焊。但是在Jenkins的pipeline中,通過nohup科贬,且使用&之后泳梆,step結(jié)束后鳖悠,執(zhí)行的程序還是會退出,導(dǎo)致程序起不來优妙。
在pipeline中需要使用修改 JENKINS_NODE_COOKIE 的值來解決問題乘综,這樣后續(xù)結(jié)束的時候,后面的sh程序就不會被kill掉了套硼。
例如代碼:
stage('4.部署程序'){
steps {
script{
PROCESS_ID = sh(script: "ps aux|grep training-ip|grep -v grep|grep -v jenkins|awk \'{print \$2}\'", returnStdout: true).trim()
echo "${PROCESS_ID}"
if (PROCESS_ID != "") {
sh """
echo "Kill process: ${PROCESS_ID}"
sudo kill -9 ${PROCESS_ID}
"""
}
}
sh """
JENKINS_NODE_COOKIE=dontKillMe nohup /home/training-ip-management/training-ip-demo/training-ip-demo &
"""
}
}
2.4.2 GO編譯命令不認識
問題現(xiàn)象:
Jenkins有如下輸出卡辰,表示go 命令找不到。
[Pipeline] { (3.編譯程序)[](https://jenkins.artarva.com/job/preproduct-training-ip-demo/5/console#) [Pipeline] sh[](https://jenkins.artarva.com/job/preproduct-training-ip-demo/5/console#) + export GOPATH=/opt/GOPATH
+ GOPATH=/opt/GOPATH
+ export PATH=/usr/local/bin:/usr/local/java/jdk1.8.0_212//bin:/usr/local/java/jdk1.8.0_212//jre/bin:/usr/local/mycat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/GOPATH/bin
+ PATH=/usr/local/bin:/usr/local/java/jdk1.8.0_212//bin:/usr/local/java/jdk1.8.0_212//jre/bin:/usr/local/mycat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/GOPATH/bin
+ go build -o training-ip-demo main.go
/var/lib/jenkins/workspace/preproduct-training-ip-demo@tmp/durable-86459043/script.sh: line 4: go: command not found</pre>
運行的對應(yīng)流水線腳本為:
stage('3.編譯程序'){
steps {
sh """
export GOPATH=/opt/GOPATH
export PATH=$PATH:\$GOPATH/bin
go build -o training-ip-demo main.go
sudo cp training-ip-demo /home/training-ip-management/training-ip-demo
"""
}
}
問題分析:
JENKINS下邪意,默認采用Jenkins賬號運行九妈。該賬號下的PATH并沒有包含GO的環(huán)境,上面腳本的路徑也寫錯了雾鬼。改為如下即可成功運行萌朱。
運行成功的對應(yīng)流水線腳本為:
stage('3.編譯程序'){
steps {
sh """
export GOROOT=/opt/module/go
export PATH=$PATH:\$GOROOT/bin
go build -o training-ip-demo main.go
sudo cp training-ip-demo /home/training-ip-management/training-ip-demo
"""
}
}
關(guān)于Jenkins pipeline單引號憋他、雙引號和轉(zhuǎn)義字符的說明參考 https://blog.csdn.net/nklinsirui/article/details/100539935 這篇文章于置。
3.參考
(1)Jenkins持續(xù)集成Go項目
https://www.pianshen.com/article/8603599995/
(2)Jenkins流水線(pipeline)實戰(zhàn)之:golang項目
https://blog.csdn.net/qq_36270681/article/details/105449608
【說明】
[1]安裝插件,按照次更新了鏡像
jenkins Publish over SSH 的配置與使用
https://www.cnblogs.com/yechen2019/p/11529755.html
[2] 流水線失敗吧恃,不用又憨。
[3] GIT相關(guān)命令
https://www.jenkins.io/doc/pipeline/steps/git/
[4] SHELL相關(guān)命令
https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
[5] jenkins全局變量
https://wiki.jenkins.io/display/JENKINS/Building+a+software+project#Buildingasoftwareproject-JenkinsSetEnvironmentVariables
https://jenkins.artarva.com/env-vars.html/
[6]官方groovy語法
http://docs.groovy-lang.org/latest/html/documentation/core-operators.html#_conditional_operators
(3)使用Docker+Jenkins實現(xiàn)Go語言項目的持續(xù)集成
https://juejin.cn/post/6844904152829542413
【說明】自由風(fēng)格構(gòu)件成功GO項目翠霍,不是流水線
(4)使用Docker+Jenkins實現(xiàn)Go語言項目的持續(xù)集成
https://juejin.cn/post/6844904152829542413
【說明】自由風(fēng)格構(gòu)件成功GO項目,不是流水線
(5)搭建jenkins+gitlab持續(xù)集成環(huán)境
https://jingyan.baidu.com/article/5552ef47fbb9b3518ffbc983.html
【說明】構(gòu)建項目部分未使用蠢莺。
(6)Jenkins集成Gitlab配置提交流水線
https://blog.csdn.net/valada/article/details/104272152
(7)基于GitLab CI搭建Golang自動構(gòu)建環(huán)境
https://segmentfault.com/a/1190000019525332
【說明】將直接在GitLab上部署自動化構(gòu)件環(huán)境的寒匙。
(8)Jenkins中使用GitLab的配置
https://www.cnblogs.com/gongxr/p/9257434.html
(9)JENKINS插件查詢的地方
https://plugins.jenkins.io/
https://blog.csdn.net/valada/article/details/104272154
(10)Jenkins中pipeline后臺進程起不來的問題
https://shanhy.blog.csdn.net/article/details/79637311
【說明】有效,采用JENKINS_NODE_COOKIE=dontKillMe解決躏将。
(11)Jenkins pipeline中優(yōu)雅的執(zhí)行shell/python/groovy腳本
http://www.reibang.com/p/2cdc8efedf2f
(12)Jenkins pipeline單引號蒋情、雙引號和轉(zhuǎn)義字符
https://blog.csdn.net/nklinsirui/article/details/100539935
(13)Jenkins實踐
http://www.idevops.site/jenkins/
(14)版本控制系統(tǒng)集成
http://www.idevops.site/jenkins/pipelineintegrated/chapter03/
(15)Groovy 語法教程
https://www.w3cschool.cn/groovy/
【說明】
<1> DEF 是在 Groovy 用來定義標(biāo)識符的關(guān)鍵字。