喝杯咖啡,一鍵部署完成!
背景
新項目沒有完善的部署流程,只能自己先搭一套來頂一頂了。
服務器資源如下:
原理圖如下所示:
Jenkins 打包部署原理圖
- Jenkins 部署在一臺服務器上,然后安裝了很多必備的 Jenkins 插件。比如拉取 Gitlab 倉庫代碼的插件、遠程執行命令和拷貝文件的插件。
- Jenkins 開始運行一個任務時,通過 Git 插件從 Gitlab 倉庫拉取代碼到本地目錄。
- Jenkins 通過 JDK 和 Maven 工具對 Java 代碼進行打包部署。
- Jenkins 通過 SSH 插件執行遠程命令,將包進行備份、清理操作。
- Jenkins 將 JAR 包拷貝到遠程服務器的固定目錄下。
- Jenkins 執行遠程命令,更新服務。
Jenkins 簡易安裝教程
Jenkins 官方網站對 Jenkins 如何安裝已經講解得非常清晰了,所以這里不再贅述,貼一下官方網站,自行去看吧。
Jenkins 下載地址:
https://www.jenkins.io/download/
Jenkins 安裝步驟:
https://www.jenkins.io/doc/book/installing/
安裝完成后,我們需要配置 Jenkins。
配置 Jenkins
因為我們要打包部署的項目是 Java 項目,所以需要將 Java JDK 所在的目錄和 Maven 所在目錄配置到 Jenkins 中,這樣 Jenkins 打包時就能利用這兩個工具進行打包。
配置全局工具:Maven
配置如下:
Jenkins配置入口
Jenkins Global Tool Configuration
配置環境變量:
- Java JDK
- Maven
全局屬性配置
上面的配置完成后,我們就可以測試下是否可以將代碼倉庫中的某個分支的代碼拉取下來進行打包。
通過 Jenkins 一鍵部署
在使用 Jenkins 時,我們必須創建一個任務才行,然后這個任務里面可以配置要執行的各種操作。
Jenkins中自動構建項目的類型有很多,常用的有以下三種:
- 自由風格軟件項目(FreeStyle Project)
- Maven項目(Maven Project)
- 流水線項目(Pipeline Project)
每種類型的構建其實都可以完成一樣的構建過程與結果,只是在操作方式、靈活度等方面有所區別,在
實際開發中可以根據自己的需求和習慣來選擇。
下面演示創建一個簡單的自由風格項目來完成項目的集成過程:
拉取代碼->編譯 Java 項目->備份服務器 JAR 包->刪除服務器 JAR 包->拷貝 JAR 包到服務器->更新服務。
創建一個項目
創建一個項目
創建成功后就會出現一條記錄:
Dashboard 界面
為了測試我們的 Jenkins 是否能正常拉取代碼并打包,我們需要配置 Gitlab 代碼倉庫的地址、用戶名、密碼。
配置拉取的代碼倉庫
- 倉庫 URL
- 用戶名和密碼
配置拉取的代碼倉庫地址和認證方式
配置打包
配置 Maven 打包
echo "開始打包"
mvn clean package
echo "打包完成"
配置到這一步后,我們可以先驗證下這些配置是否生效。
運行項目
在 Dashboard 可以看到配置完成的任務,點擊 Build Now 按鈕即可開始拉取代碼、打包項目。
我們還可以從控制臺輸出看到打包記錄。
Jenkins 會從 Gitlab 倉庫拉取指定分支的代碼,然后運行 mvn clean package 命令,進行打包。
打印 Jenkins 運行項目的結果
輸出記錄中打印出了以下關鍵信息:代碼拉取后存放在哪,打的 jar 包在哪。
代碼和生成的 jar 包在到這個根目錄找到:
C:\ProgramData\Jenkins.jenkins\workspace\passjava-dev
還可以從打印日志的最后看到這次打包用時 2 min 33 秒,任務的執行狀態為 Finished Success。
接下來就是將這些 JAR 包拷貝到遠程服務器地址。
拷貝安裝包
安裝插件
拷貝安裝包需要用到一個插件:Publish Over SSH。
Dashboard>Manage Jenkins->插件管理->Avaliable plugins。
下圖是已經安裝好了這款插件的截圖。
Jenkins 插件管理
配置這個插件的全局配置:
- SSH Server Name:遠程服務器的名字,后面在配置拷貝包的時候可以根據名字選擇拷貝到哪臺服務器。
- Hostname:SSH Server 的 Hostname。
- Username:SSH Server 登錄名和密碼或密鑰。
- Remote Directory:指定將文件拷貝到哪個目錄。
配置遠程服務器地址
備份服務器 JAR 包
在上傳打包好的 JAR 包之前,需要將應用服務器上的 JAR 備份。
備份的步驟如下:
- 在遠程服務器創建一個備份目錄 bak。
- 在備份目錄bak上創建一個以當前時間作為目錄名的目錄。
- 將遠程服務器的上 JAR 重命名為原文件名+時間戳的名字。
備份服務器 JAR 包
拷貝 JAR 包到遠程服務器
需要配置以下內容:
- SSH Server:指定要將文件拷貝到哪個服務器,格式為 <用戶名>@<ip 地址>。
- Transfer Set Source files:jenkins 編譯后的 JAR 地址。通過之前的編譯信息我們知道,JAR 包地址在如下路徑:
C:\ProgramData\Jenkins.jenkins\workspace<Jenkins 任務名><編譯目錄>
- Remove prefix:要移除的文件路徑前綴。
- Remte directory:拷貝到哪個路徑下,如果之前已經配置過全局的文件夾,則拷貝的文件會放到 <全局文件夾>/之下,如果全局文件夾之下沒有這個 Remote directory 目錄,則創建一個。這里我們不需要配置,全局配置已經可以滿足條件了。
- 如果還有其他 JAR 包也需要拷貝則需要再添加一項。
拷貝多個 JAR 包到遠程服務器
滾動更新服務
項目采用的 Docker Swarm 方式來管理集群中的微服務。
Jenkins 通過 插件 發送命令到應用服務器上執行指定的腳本
配置遠程執行腳本的命令
echo "部署 jar 包"
cd /nfs-data/wukong/
nohup sudo sh restart.sh
exit
這個命令使用 nohup 和 sudo 權限來執行名為 restart.sh 的腳本。nohup 命令用于將腳本在后臺運行,即使終端會話結束,腳本仍然繼續運行。
遠程服務器上創建腳本
如果想要 jenkins 執行遠程服務器上的腳本,則需要先在遠程服務器上創建一個可執行的腳本。
這里我們需要重啟服務器的容器服務,所以在這個目錄 /nfs-data/wukong/ 編寫一個 restart.sh 腳本。
echo "部署 passjava 服務"
nohup sudo docker service update accountservice --force > /nfs-data/wukong/jenkins/account.txt
nohup sudo docker service update gatewayservice --force > /nfs-data/wukong/jenkins/gateway.txt
nohup sudo docker service update qmsservice --force > /nfs-data/wukong/jenkins/qms.txt
這個命令使用--force選項來更新名為"accountservice、gatewayservice、qmsservice"的 Docker 服務。命令的輸出被重定向到文件/nfs-data/wukong/jenkins/xxx.txt中。
部署
再次測試是否能正確編譯代碼,上傳 jar 包,部署微服務。
部署結果如下:Finished: SUCESS
部署結果
遇到的問題
問題 1、添加 Git 倉庫時,無法訪問
SSL certificate problem: unable to get local issuer certificate
解決方案:
git config --system http.sslVerify false
git config --global http.sslVerify false
參考鏈接:https://stackoverflow.com/questions/39746535/jenkins-git-ssl-certificate-error
問題 2
stderr: fatal: unable to access 'url of my git/': SSL certificate problem: self signed certificate in certificate chain
解決方案:
git config --system http.sslVerify false
git config --global http.sslVerify false
參考鏈接:https://stackoverflow.com/questions/39746535/jenkins-git-ssl-certificate-error
問題 3
Exception when publishing, exception message
問題 3 的記錄
解決方案
遠程機器上需要用 sudo 命令執行 docker 命令,這個時候需要輸入密碼,通過配置賬號 xx 執行 sudo 命令不需要輸入密碼。
解決思路
問題 3 的解決思路
問題 4:could not identify password for [xxx]
問題 4 解決思路
問題 5:ssh 超時配置
ERROR: Exception when publishing, exception message [Exec timed out or was interrupted after 120,011 ms]
問題 5 的記錄
解決方案:修改超時時間設置
問題 5 的解決方案
關于我
InfoQ 簽約作者、藍橋簽約作者、阿里云專家博主、51CTO 紅人。