Build great things at any scale.
快速上手
起源
一個項目比較完整的生命周期該是怎樣的?
由開發的coding階段和coding階段的質量測試,再到多次發布投入使用階段
而現代化的測試階段並不是從coding結束后開始,而是和coding同步進行的,今天上午coding完成一個功能,下午就要投入測試
如何測試呢,也就是將開發者完成的代碼,拉取到服務器A(一般是linux)上,按照開發者的部署文檔搭建各種依賴服務(可能是mysql,redis,kafka等等),然后運行代碼編譯后的文件或者是運行腳本
如果我們測試得出開發者今天完成的新功能存在問題,我們需要提出bug,然后開發者解決這個bug,解決完之后呢?
如果開發者在bug解決文檔中沒有說明是依賴服務出現了問題導致的這個bug,那么A機器上的依賴服務我們是不用重新搭建的,無非就是啟動和停止.
變化的往往都是開發者的功能的代碼部分.對於java coder,一般是將開發者在git的指定分支上的代碼pull下來之后編譯打包,然后替換掉A機器上的編譯后的包,重啟服務,繼續測試
每當需求發生變化,功能需要改進,bug等等問題的時候,代碼就會發成變化,而將這種變化需要我們在測試機器上得以體現,可能就是替換代碼包之類的,這個過程重復而且繁雜,也容易出現部署失誤,這種需求背景下產生了自動化持續構建的概念.
而jenkins正是貫徹和發揚了這一理念的持續構建工具
The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.
領先的開源自動化服務,jenkins中提供了眾多的插件以支持使用自動化的方式構建和發布任何工程.
本文作者同大家一起開始步入jenkins的鏡像世界,一步一步,深入jenkins,從入門到精通,從使用到理解掌握
為什么選擇jenkins
既然都是為了實現自動化持續構建,難道就jenkins這一個選擇嗎
通常我會使用百度指數,在涉足一個新的領域的時候幫助我了解這個領域哪些將會是趨勢,哪些只是殘留
百度指數只能反映國內的一部分情況,以后會加入google指數來反映國外的情況.
hudson/jenkins
hudson是jenkins的前稱
jenkins 2012-2019百度搜索指數趨勢圖
hudson的趨勢數量級在百,忽略不計
TeamCity
TeamCity是jet大腦的出品,百度搜索指數還未收錄
Travis
Travis CI是最老的托管解決方案之一
其他
其他有如gitlab ci,bamboo由於存在關鍵詞意義重疊的情況,目前還沒有想到比較好的解決方案,這次不加入比較.
結論
從上面的趨勢圖中無論是基數還是趨勢,jenkins的學習性價比對比travis要高許多.
當你選擇了一種語言,意味着你還選擇了一組技術、一個社區
從二次開發的角度來看,jenkins開源,而且使用的語言是java,使用的框架為spring,兩者分別為國內語言社區和框架社區中的頂級社區,發展的特別的好.
使用
我們將使用jenkins完成三個最為重要和基礎的功能
拉取遠程git庫代碼到本地
主界面是這樣的
為了規整,我們可以先創建一個文件夾(目錄)
點擊new任務,出現
點擊文件夾,然后在輸入框中輸入文件夾的名字,后點擊ok后進入了文件夾屬性配置界面
不管這個界面,點擊左上方的jenkins圖標回到jenkins主頁
發現此時多了一個文件夾
點擊進入
點左上方的New item
和之前的new 任務頁面類似
點擊構建一個自由風格的軟件項目
在輸入框輸入這個自動化任務的名稱
點ok之后進入配置界面
在這個配置界面下拉到Source Code Management,點擊選中git
在Repository URL中輸入需要maven構建的代碼的倉庫地址
Branch Specifier中輸入需要構建的分支的名稱,/master表示構建分支名為master,/你的分支的名字
接下來需要認證這個倉庫,點擊Credentials右邊的add
出現了下拉,一個是jenkins,一個是我們的文件夾名稱(githubTasks)
我們選擇文件夾名稱
在彈出的窗口中類型選擇為Username with password
然后輸入你的登錄到git倉庫的用戶名和密碼
然后點擊添加,在Credentials的無 下拉,有我們剛剛添加的賬戶
點擊最下方的Save,完成這個自動化構建任務的第一步,拉取遠程git庫的代碼到本地(jenkins所在服務器,docker的話就是docker的容器內部)
我們可以看到是否拉取成功,回到這個界面
點擊進入
坐下方的Build History里面有一個 #1
點擊進入
點擊左側欄的Console Output進入
注意這個位置是導航欄,這里我們可以隨意跳轉到主界面,文件夾界面或者是任務界面
jenkins是主界面,githubTasks是文件夾
compileGithub是任務界面
我們點擊compileGithub進入任務界面
點擊workSpace
進入到了這個界面,里面可以看到我們的拉取的代碼
可以看到這個界面的標題節點master上的工作空間,在之后的將代碼編譯后的成品發布到任意指定機器上的那部份,我會對節點,加以解釋,現在這個節點master值得就是jenkins所在的這台機器.
上面的工作完成了將代碼從遠程git倉庫拉取到本地,接下來需要在本地編譯這些代碼
引申
如果我經常需要拉取不同的分支的代碼,也就是分支這個字符串,是經常需要改變的,難道我每次都要修改任務配置中的Branch Specifier嗎?
讓我們返回到jenkins主頁,這兒需要加入一個git參數動態化的插件
主頁中點擊系統設置,點擊插件管理
然后點擊Available
filter 中輸入:git parameter
篩選出來的插件中勾選 Git Parameter
點擊install without restart之后
等到Git Parameter 圖標為 Success即ok
點擊Go Back to the top page,回到首頁
點擊導航欄任務compileGithubCode,沒有的話先進入文件夾githubTasks,然后從這里點擊compileGithubCode進入任務
點擊左側的Configure
進入到了任務的配置界面
找到並勾選參數化構建過程
下拉選擇Git Parameter
在name中為這個分支字符串變量起個名字,以后用$獲取
Parameter Type下拉選擇branch
點擊左下角save
這時候我們發現任務左側邊欄的開始構建沒有了,取而代之的是Build With Parameters
點擊Build With Parameters轉到界面
這個列表會羅列出該git倉庫的所有分支,我們選擇點擊選擇一個,然后點Build就好了
使用編譯工具本地編譯拉取到的代碼
得到了遠程庫的代碼,現在要在本地編譯這些代碼
java coder的話,使用maven編譯打包
這個時候就要添加maven這一全局工具了
注意: 接下來是自動的在jenkins機器上安裝了一個maven,但是如果你原本項目的maven編譯依賴着.setting.xml中配置的maven私服或者是proxy代理的話,還需要別的操作,最粗暴不過進入到jenkins所在機器(這里是docker的容器內部),找到並配置maven的setting.xml
導航欄點擊jenkins進入到主界面
點擊左側系統管理進入到了
點擊全局工具配置,然后下拉到
點擊add maven
在name中輸入你給它起得名字,這里起了名字maven36來標識他是3.6.0版本
點擊左下角的Save
然后回到了主界面,點擊jenkins,點擊文件夾githubTasks,點擊任務compileGithubCode
點擊左側Configure
其實可以注意到,這里也有導航欄
我們點擊Build
然后點擊add build step
選擇 執行頂層Maven目標
出來的界面中
maven version 中下拉選擇我們上一步在系統設置的全局工具配置中起得maven名稱
Goals部分大部分都是clean install,clean package之類的maven編譯命令
點擊左下方save,ok
回到任務compileGithub界面,點擊左側立即構建
看到了左下方build中標志着任務正在進行中的閃爍的圖標
點擊這個#3,進入到日志界面
我們在系統設置的全局工具配置中配置了如何下載maven等,但是實際上它是類似於單例模式,在第一次運行的時候初始化,以后都能使用
由於沒有配置中央倉庫為國內maven鏡像庫,而且是maven第一次構建,所以我這里構建的特別慢,花了將近15min
構建完成后的日志
構建完成之后我們進入任務界面compileGithubCode
點擊workspace
進入到jar產生的target目錄,發現成功編譯得到了jar文件
但是以后比如別的人想從網頁上下載這個編譯好的jar,能不能直接從頁面上下載下來,當然可以,點擊這個jar就會下載下來
但是我們要明白這個任務的目的是什么,其實就是得到這個編譯后的成果,過程怎么樣是沒人關心的,也就是這個任務應該對外完美暴露它的成功,也就是這個jar,不僅要方便大家從頁面上下載這個jar,還有后面的任務可能會從這個任務上拿取jar
需要添加構建后操作,回到這個任務的配置頁面,找到Post-build Actions,下拉選擇歸檔成品
在Files to archive中填寫需要暴露的jar的位置
位置是可以從任務的工作空間中看到的
然后我們回到任務主頁,點擊開始Build with parameter,選擇分支,build
build成功后,我們進入該任務的主頁
發現多了一個Last Successful Artifacts,這樣就可以很方便的從頁面上下載這個jar,而不用擔心忘了編譯后的成果在什么文件夾位置的情況.
注意: 這一步是必備的,不然下面的發布的任務會無法從這個任務中自動化的獲取jar
至此完成了本地編譯從遠程庫pull下來的代碼的階段.
將編譯的結果部署到指定的機器上
接下來我們需要理解jenkins中節點的概念
jenkins安裝在一台機器,所有的jobs都在這台機器上運行,如果超過太多jobs去運行,會形成等待,節點存在就是解決這個問題提高效率,安裝jenkins的機器稱為master機,而其它機器就屬於master的分支,成為slave;而要利用其它機器用執行jenkins的jobs,則需要一些配置,形成兩台機器互通,當然下面的例子你用本機當做slave也是可以的
從機節點的建立意味着這台從機就是master的一個復刻,master能執行的任務它都能干(master的向從機發送命令這一功能除外)
也就是完整的發布過程是這樣的,master機器訪問從機B,向B發送 拉取代碼到本地 的命令,master機器做的僅僅是發送命令,然后干別的,等到B將遠程代碼pull到了B的本地
本地編譯代碼的過程也是如此
而現在我們就是需要從機得到代碼,編譯,然后在本地執行啟動服務的腳,如果是tomcat應用的話(外置),可能是將編譯后的war放入webapps下,然后啟動tomcat的startup.sh
那我們先完成第一步,建立從機節點,說白了,就是我作為master,怎么訪問從機,用戶名加密碼也好,ssh認證也好
建立從機節點
為了方便用戶管理,我們最好不要使用使得master訪問從機的root用戶,比如這里,我們使用用戶jenkins用戶
連接到一台從機(root用戶)
groupadd jenkins
useradd jenkins -g jenkins
passwd jenkins
接下來需要輸入jenkins用戶的密碼,要求比較嚴格,密碼要求為至少8位的非簡單字符串
密碼定位kinsjen0
然后我們切換到jenkins用戶
su - jenkins
pwd
jenkins的~目錄在/home/jenkins
因為jenkins是用java寫的后台,需要注意這台從機機器需要有java環境
which java
得到的路徑地址會在后面配置節點信息的時候用到
接下來我們進入jenkins主頁,點擊左側系統管理,然后下拉找到節點管理,點擊之后是這樣的
注意到已經有了一個節點master,就是我們安裝jenkins的機器,我們點擊左邊的New Node
在輸入框中輸入我們給這個節點機器起得名字
並勾選固定節點
切記這里的節點名不能包含中文字符,不然之后的操作會無法識別這個節點,如果已經發現了問題,可以在節點的設置中修改名稱.
點擊ok后展開頁面
Remote root directory中輸入你的從機的用戶的~地址
也就是我們的從機的jenkins用戶的~,/home/jenkins
然后下拉Usage,切換到 只允許綁定到這台機器的job,Host輸入這台節點的ip
注意,要確保在master機器上能夠ping通這個ip
然后下拉Host Key Verification Strategy,選擇Manually trusted key Verification Strategy
隨后點擊Credentials右側的add,點擊下拉出現的jenkins,出現界面
在username中輸入節點機器的用戶名jenkins,在password中輸入這個用戶的密碼,然后點擊添加
隨后在Credentials的下拉中選擇我們剛剛添加的用戶密碼信息
點擊Launch method右下方的Advanced,這里唯一要做的是填寫javapath,也就是我們在節點機器上新建用戶的時候說道的which java得到的java路徑
注意: 如果ssh端口暴露的是36000,記得這里修改port的22為36000,不然啟動日志會報錯
點擊左下方Save完成節點的配置.此時跳轉到了節點管理界面.
可以看到此時的節點處於未啟動狀態,因為啟動需要一段時間,主機會將服務的相關代碼copy到從機的/home/jenkins下
可以點擊節點 測試機器1jenkins用戶,進入后的界面點擊啟動;也可以稍等一會兒,它會自動去啟動,啟動成功后可以看到這個節點管理界面發生了變化,這樣表示成功建立了節點
至此完成了從機節點的配置.
提示: 可以登錄到從機機器上,切到jenkins用戶,切換到~目錄下,ls后可以看到名為remoting.jar和remoting文件夾
在節點上部署服務
接下來讓我們收貨最終的成果,在節點機器上發布應用
這時候我們需要什么?
我們需要在從機機器上運行我們的代碼編譯完成的jar
那么第一步就是取得我們的jar
如何取得我們的代碼的jar,我們已經在任務compileGithub中得到了遠程代碼,並編譯了它,現在我們需要它的編譯結果
有這么一個插件需要我們添加,來幫助我們在一個新的任務中拉取另一個任務的編譯結果
回到jenkins首頁,左側系統管理,之后點插件管理,filter中輸入:Copy Arti
勾選篩選出來的插件Copy Artifact
點擊install without restart
Copy Artifact變為success之后
點擊Go Back to the top page,完成插件的添加.
回到jenkins主頁,進入githubTasks文件夾,點擊左側New Item,輸入任務名稱,比如deployMyCode,然后選擇構建一個自由風格的軟件項目,點OK
勾選Restrict where this project can be run,Label Expression中輸入我們之前新建的節點的名字,輸入了MachineTest1就已經有了提示,選中它
這樣就相當於是會讓這個機器執行發布任務
接下來我們獲取之前的任務構建的jar
然后在Project name中輸入我們之前的拉取代碼並本地編譯的任務名稱 compileGitHubCode,
Artifacts to copy中輸入vertx-api/target/*.jar,這個就是我們的任務compileGitHubCode執行完后在工作空間中能找到的jar的位置.
提示: 這個在前面提到了編譯代碼厚的保存構建生成物操作
Target directory中輸入packages
之后我們創建一個shell
注意順序,這個添加的shell應該在Copy artifacts from another project的下面
按道理我們應該在這個shell腳本中執行我們獲得的jar,完成類似這樣的發布任務的,但是為了熟悉一下這個腳本的執行環境,我們先運行一個簡單的腳本
#!/bin/bash
deploy_testMachine() {
touch test.log
}
deploy_testMachine
然后點擊左下方的Save,回到了任務的主頁面,我們點擊左側欄的立即構建
點擊左下方的#5
然后點擊左側的Console Output
可以從日志中發現一些端倪
Building remotely on MachineTest1UserJenkins in workspace /home/jenkins/workspace/githubTasks/deployMyCode
也就是我們經常說的任務的工作空間實際是:
/home/jenkins也就是我們的節點用戶
/workspace是我們的所有的工作空間的最上級
/githubTasks我們之前的文件夾
/deployMyCode是我們的這次任務
切入到/home/jenkins/workspace/githubTasks/deployMyCode
ls
packages test.log
cd packages
ls
vertx-api
cd vertx-api
ls
target
cd target
ls
vertx-api-1.0.0.jar
這樣我們就明白了,這個腳本的執行目錄在/home/jenkins/workspace/githubTasks/deployMyCode下,也就是我們的腳本實際上是在這個目錄下被執行的
之后我們回到這個任務的配置界面,將我們的腳本修改為
#!/bin/bash
deploy_testMachine() {
java -jar ./packages/*.jar
}
deploy_testMachine
然后回到任務主頁,立即構建,即可完成類似服務的發布這種
如果你需要每次刪除上次殘留在節點中的舊的代碼,需要進入到任務的配置,在Build Environment下勾選Delete workspace before build starts即可
至此完成從編譯產物到產物發布的過程