DevOps系列——Jenkins/Gitlab自動打包部署
前面只說了DevOps的兩個基礎組件Jenkins和GitLab,客官也不要著急,我們玩就玩的深入一點,Gitlab和Jenkins的各種配置和
插件很多,也夠啃一陣子的,不要照著操作一通就感覺萬事大吉了,多做些邊緣測試,多玩點不一樣的操作,那今天我們來點
實戰整合加強訓練。
作者原創文章,謝絕一切轉載,違者必究!
準備:
VMwareWorkstation15Pro/RHEL8.0/Jenkins2.222.3/Gitlab-ee-13.0.0
難度: 新手–戰士–老兵–大師
說明:
為了遇見各種問題,同時保持時效性,我盡量使用最新的軟體版本。源碼地址,其中的day30://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 //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 //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未配置好!
全文完!
我近期其他文章:
只寫原創,敬請關注