DevOps系列——Jenkins/Gitlab自動打包部署
前面只說了DevOps的兩個基礎元件Jenkins和GitLab,客官也不要著急,我們玩就玩的深入一點,Gitlab和Jenkins的各種配置和
外掛很多,也夠啃一陣子的,不要照著操作一通就感覺萬事大吉了,多做些邊緣測試,多玩點不一樣的操作,那今天我們來點
實戰整合加強訓練。
作者原創文章,謝絕一切轉載,違者必究!
準備:
VMwareWorkstation15Pro/RHEL8.0/Jenkins2.222.3/Gitlab-ee-13.0.0
難度: 新手--戰士--老兵--大師
說明:
為了遇見各種問題,同時保持時效性,我儘量使用最新的軟體版本。原始碼地址,其中的day30:https://github.com/xiexiaobiao/dubbo-project
目標:
- window主機提交程式碼到Gitlab主機,Jenkins自動完成jar打包,併發布到Gitlab主機(可為任意主機)上執行。
1 架構
整體部署架構:
2 環境
2.1開發Java應用,一個極簡的服務,可打包為jar執行:
package com.biao.study; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class AppMain { public static void main(String[] args) { SpringApplication.run(AppMain.class,args); System.out.println("AppMain app started >>>>>>>>>>>>"); } @RequestMapping("/jenkins/{name}") public String hello(@PathVariable(name = "name") String name){ System.out.println("Variable: "+ name); return "hello, " + name; } }
執行測試,GET http://localhost:8081/jenkins/biao
輸出:hello, biao
2.2 GitLab主機上建立一個專案,操作步驟,略!注意看下專案的兩個git地址,顯示的埠號是Gitlab的埠號,不是Nginx的:
2.3 配置Jenkins主機到Gitlab主機的SSH,(配置window到Gitlab主機的SSH,也是一樣,window在CMD 下執行):
[root@server224 docker-deploy]#ssh-keygen #生成金鑰對
[root@server224 docker-deploy]#ssh-copy-id [email protected] #傳送公鑰
Window下使用git測試ssh安裝:
2.4 Jenkins主機上測試使用SSH協議連線GitLab,這樣Git可以免密連線,並使用SSH連線執行shell,
進入新建的空白目錄 /usr/hellojenkins 下:
[root@server224 hellojenkins]# ssh -T [email protected] #測試ssh
[root@server224 hellojenkins]# git init #初始化本地git庫,否則報錯not a git repository
[root@server224 hellojenkins]# git remote –v # -verbose檢視遠端gitlab url
[root@server224 hellojenkins]# git remote add origin [email protected]:biao/hellojenkins.git
[root@server224 hellojenkins]# git pull origin master
如下,可見連線成功,其他git操作客官請隨意:
2.5 Jenkins主機上測試使用HTTP協議連線GitLab,在 /usr/hellojenkins 下:
[root@server224 hellojenkins]# rm -rf ./* #清空hellojenkins目錄,.git和 .idea也要刪除
[root@server224 hellojenkins]# git init
[root@server224 hellojenkins]# git remote -v
[root@server224 hellojenkins]# git remote add origin http://192.168.2.226:9099/biao/hellojenkins.git #注意url,不是gitlabUI中給的專案url,因有Nginx代理
[root@server224 hellojenkins]# git pull origin master
如下,可見http連線成功,其他git操作客官請隨意
特別注意:如開啟了Nginx代理,會導致gitlab UI中給的專案url (見圖1),在git中無法使用,應使用Nginx的埠號!
2.6 訪問JenkinsUI,新增 ”Publish Over SSH” 外掛(見前文:Jenkins安裝),並在 ”系統管理-系統配置” 新增SSH目標主機 (比如我這是192.168.2.226):
要點: 1.SSH主機登入密碼和私鑰key,可以二選一,推薦使用私鑰key,這樣可以使用相同的私鑰key登入多個目標主機。
2.使用私鑰key測試不通過,可能是格式問題,見後文問題部分。
3.RemoteDirectory為SSH連線後要訪問的目錄 4.Test必須顯示為Success才算配置成功
2.7 其他工具配置:Jenkins主機需先安裝好Maven,Git,JDK,略!並在 “系統管理—>全域性工具配置”中做對應的配置:
3 任務構建
3.1 我們來個Jenkins自動構建的實驗:新建一個任務,選擇”構建一個自由風格的軟體專案”:
General中我全空,懶得寫了。
原始碼管理使用Git,(也可使用Subversion,需對應的外掛),並選擇前面配置好的”憑證”:
自動構建觸發的條件是 push 事件:
構建前清空工作目錄:
構建時執行的shell指令碼,source /etc/profile
不能省,可能導致mvn命令無法識別,cd $JENKINS_HOME/workspace/hellojenkins
,使用環境變數來進入工作目錄,
也可使用 $WORKSPACE/hellojenkins
效果一樣,有個環境變數列表連結,可供參考;mvn clean package
即 maven 編譯打包命令,記憶體不足的話可先只測試 mvn clean:
構建後操作:1 source files是待發送的原始檔,這裡特別注意要寫相對路徑target/*.jar
,不是絕對路徑/var/lib/jenkins/workspace/hellojenkins/target/*.jar
;
2 remove prefix是需要去掉的字首,置空則將檔案和路徑一起傳送,並在遠端主機建立對應目錄結構;
3 remote directory是遠端主機的目錄,傳送的檔案將儲存至此;
4 執行的shell指令碼,會在檔案傳送後執行,先可直接簡化為如下建立一個日期檔案(最常見的是停止舊jar的執行,並執行新的jar,完整版見後面的指令碼);如果需要檔案傳送前執行,可以新增兩個"構建後操作",並將shell指令碼執行放前,檔案transfer放後:
附,完整Exec comand指令碼:
#!/bin/bash pid=$(ps -ef | grep HelloJenkins-1.0-SNAPSHOT | grep 'java' | grep -v grep | awk '{print $2'}) if [ -z "$pid" ]; then echo 'there are no HelloJenkins process. starting will be continue.' fi if [ -n "$pid" ]; then echo 'java process id is '$pid if ps -p $pid > /dev/null then echo $pid' will be kill' kill -9 $pid fi fi echo 'start HelloJenkins wait.' nohup java -jar HelloJenkins-1.0-SNAPSHOT.jar > /dev/null 2>error.log & echo 'finish starting HelloJenkins'
3.2 進行 ”立即構建” 測試:
3.3 等待構建完畢檢視控制檯日誌,或左側”構建執行狀態”檢視正在進行的Job:
控制檯內容:
以上步驟解析:1 Jenkins生成對應的工作目錄,注意 /var/lib/jenkins 對應 JENKINS_HOME
變數,即Jenkins家目錄;
2對應配置選項Delete workspace before build starts,構建前刪除; 3使用SSH連線遠端Gitlab程式碼庫; 4 Git操作完畢後的訊息,可用於記錄本次構建;
5可以看到Jenkins將構建的配置和構建流程共同生成了一個臨時的Shell指令碼,然後執行,這也是Jenkins的工作原理之一。
總結:這裡的Jenkins自動構建流程是使用Git從遠端庫clone到本地,然後本地構建,同時部分流程和配置會組合生成一個臨時的Shell指令碼來執行,最終完成整個構建工作流程。(Jenkins還有其他構建方式)。
以上步驟解析:1對應執行”構建”配置中shell命令mvn clean package的結果; 2-5是對應”構建後操作” 中的配置,其中2是開始SSH連線,
3是開始執行”Exec command”中的shell命令,4斷開SSH連線,5檔案傳輸的結果
以下為server226上對應”構建後操作”中的結果,生成的檔案和傳輸過來的jar包:
4 題外話
4.1 我上傳的程式碼中還包含了 Dockerfile 和自動打包/部署Docker映象的shell指令碼,內容太多,各位看官可以嘗試一下:使用Jenkins自動構建
並生成映象和部署執行,有空我就後期再說吧,一次寫太多看的也累。
4.2 Gitlab的WebHook功能:在Gitlab收到push事件後,可以 POST 傳送定製的資訊至指定的URL,從而觸發更新。比如SpringCloud的config
配置自動更新,當GitHub上的配置檔案更新後,WebHook自動觸發Refresh 到Config Server 上,而完成配置自動重新整理。
5 問題
5.1 新增SSH伺服器時,test失敗,提示:
Failed to connect or change directory jenkins.plugins.publish_over.BapPublisherException: Failed to add SSH key. Message [invalid privatekey: [B@d8d395a]
這是因為私鑰格式Jenkins無法識別,如果開啟私鑰檔案,"-----BEGIN OPENSSH PRIVATE KEY-----" 表示使用的是最新的OpenSSH格式,需要使用舊版格式,重新生成金鑰,命令如下:
ssh-keygen -t rsa -b 4096 -m PEM
再開啟私鑰檔案,可見私鑰檔案內容開頭:”-----BEGIN RSA PRIVATE KEY-----”,
5.2 執行自動生成映象指令碼錯誤提示$'\r' command not found
:
這種錯誤是因為編寫的 shell指令碼是在window下編寫的,每行結尾是 \r\n,而 Unix 結束行是 \n , 所以在Linux下執行指令碼會認為 \r 是一個字元,需要把檔案轉換下:
[root@server224 docker-deploy]# sed -i 's/\r//' auto-image.sh
5.3 錯誤提示:Does not have a commit checked out
,這是因為當前目錄下存在沒有提交的目錄,首先使用 pwd
(present working directory)命令檢視當前目錄,
需保持 .init
命令和 pwd
命令目錄一致:
5.4 提示 http/https協議不支援,可能原因是url錯誤,或者沒新增遠端地址,初始化沒完成,即git remote add
命令:
5.5 打包編譯時,記憶體不足,看控制檯輸出,我將Jenkins主機由6G調整為8G才解決,還好我的小電腦記憶體足夠大:
總結:控制檯輸出是個非常有用的記錄,比如我之前的構建失敗記錄,可以看到無法識別 mvn 命令,於是知道是maven未配置好!
全文完!
我近期其他文章:
- 1 DevOps系列——Jenkins私服
- 2 DevOps系列——Gitlab私服
- 3 聊聊演算法——滑動視窗
- 4 聊聊演算法——回溯演算法
- 5 Redis高階應用
只寫原創,敬請關注