天天看點

在kubernetes中部署Jenkins并簡單使用

在kubernetes中部署Jenkins并簡單使用

之前我們都是在實體機或者虛拟機上部署jenkins,但是這種部署方式會有一些難點,如下:

主 master 發生單點故障時,整個流程都不可用了

每個 slave 的配置環境不一樣,來完成不同語言的編譯打包等操作,但是這些差異化的配置導緻管理起來非常不友善,維護起來也是比較費勁

資源配置設定不均衡,有的 slave 要運作的 job 出現排隊等待,而有的 slave 處于空閑狀态

資源有浪費,每台 slave 可能是實體機或者虛拟機,當 slave 處于空閑狀态時,也不會完全釋放掉資源。

正因為上面的這些種種痛點,我們渴望一種更高效更可靠的方式來完成這個 ci/cd 流程,而 docker 虛拟化容器技術能很好的解決這個痛點,又特别是在 kubernetes 叢集環境下面能夠更好來解決上面的問題,下圖是基于 kubernetes 搭建 jenkins 叢集的簡單示意圖:

在kubernetes中部署Jenkins并簡單使用

從圖上可以看到 jenkins master 和 jenkins slave 以 pod 形式運作在 kubernetes 叢集的 node 上,master 運作在其中一個節點,并且将其配置資料存儲到一個 volume 上去,slave 運作在各個節點上,并且它不是一直處于運作狀态,它會按照需求動态的建立并自動删除。

這種方式的工作流程大緻為:當 jenkins master 接受到 build 請求時,會根據配置的 label 動态建立一個運作在 pod 中的 jenkins slave 并注冊到 master 上,當運作完 job 後,這個 slave 會被登出并且這個 pod 也會自動删除,恢複到最初狀态。

這種方式部署給我們帶來如下好處:

服務高可用,當 jenkins master 出現故障時,kubernetes 會自動建立一個新的 jenkins master 容器,并且将 volume 配置設定給新建立的容器,保證資料不丢失,進而達到叢集服務高可用。

動态伸縮,合理使用資源,每次運作 job 時,會自動建立一個 jenkins slave,job 完成後,slave 自動登出并删除容器,資源自動釋放,而且 kubernetes 會根據每個資源的使用情況,動态配置設定 slave 到空閑的節點上建立,降低出現因某節點資源使用率高,還排隊等待在該節點的情況。

擴充性好,當 kubernetes 叢集的資源嚴重不足而導緻 job 排隊等待時,可以很容易的添加一個 kubernetes node 到叢集中,進而實作擴充。

1、建立pv、pvc,為jenkins提供資料持久化:

2、建立角色授權

1、在kubernetes中部署jenkins,建立deployment,jenkins-deploy.yaml

5、建立上面的資源清單

啟動如果報如下錯誤(因為我們容器裡是以jenkins使用者啟動,而我們nfs伺服器上是root啟動,是以沒有權限):

然後給我們nfs伺服器上的目錄授權即可:

然後登入網站,因為我們service是采用nodeport類型,其端口為30002,我們直接在浏覽器用這個端口通路:

在kubernetes中部署Jenkins并簡單使用

密碼可以通過如下指令獲得:

然後安裝插件到安裝完成。

1、安裝插件kubernetes

在kubernetes中部署Jenkins并簡單使用

2、填寫kubernetes和jenkins的配置資訊

配置管理->系統配置->新增cloud。

在kubernetes中部署Jenkins并簡單使用
在kubernetes中部署Jenkins并簡單使用
在kubernetes中部署Jenkins并簡單使用

按照圖中紅色框中填寫,其中kubernetes命名空間填寫我們jenkins所在的命名空間。

備注:

如果連接配接測試失敗,很可能是權限問題,我們就需要把serviceaccount的憑證jenkins-sa添加進來。

3、配置pod模闆

在kubernetes中部署Jenkins并簡單使用

另外需要挂載兩個主機目錄:

/var/run/docker.sock:該檔案是用于 pod 中的容器能夠共享主控端的 docker;

/root/.kube:這個目錄挂載到容器的/root/.kube目錄下面這是為了讓我們能夠在 pod 的容器中能夠使用 kubectl 工具來通路我們的 kubernetes 叢集,友善我們後面在 slave pod 部署 kubernetes 應用;

在kubernetes中部署Jenkins并簡單使用

避免一些權限不足,需要配置serviceaccount

在kubernetes中部署Jenkins并簡單使用

1、建立一個項目

在kubernetes中部署Jenkins并簡單使用

2、在标簽位置填寫我們前面模闆中定義的label

在kubernetes中部署Jenkins并簡單使用

3、直接在建構處執行shell進行測試

在kubernetes中部署Jenkins并簡單使用

然後點選建構,在終端可以看到整個過程:

也可以在jenkins裡看日志如下:

在kubernetes中部署Jenkins并簡單使用

pipeline,簡單來說,就是一套運作在 jenkins 上的工作流架構,将原來獨立運作于單個或者多個節點的任務連接配接起來,實作單個任務難以完成的複雜流程編排和可視化的工作。

jenkins pipeline 有幾個核心概念:

node:節點,一個 node 就是一個 jenkins 節點,master 或者 agent,是執行 step 的具體運作環境,比如我們之前動态運作的 jenkins slave 就是一個 node 節點

stage:階段,一個 pipeline 可以劃分為若幹個 stage,每個 stage 代表一組操作,比如:build、test、deploy,stage 是一個邏輯分組的概念,可以跨多個 node

step:步驟,step 是最基本的操作單元,可以是列印一句話,也可以是建構一個 docker 鏡像,由各類 jenkins 插件提供,比如指令:sh 'make',就相當于我們平時 shell 終端中執行 make 指令一樣。

pipeline的使用:

pipeline 腳本是由 groovy 語言實作的

pipeline 支援兩種文法:declarative(聲明式)和 scripted pipeline(腳本式)文法

pipeline 也有兩種建立方法:可以直接在 jenkins 的 web ui 界面中輸入腳本;也可以通過建立一個 jenkinsfile 腳本檔案放入項目源碼庫中

一般我們都推薦在 jenkins 中直接從源代碼控制(scmd)中直接載入 jenkinsfile pipeline 這種方法

2.2.1、簡單的pipeline

直接 在jenkins的web ui上輸入腳本。

在kubernetes中部署Jenkins并簡單使用
在kubernetes中部署Jenkins并簡單使用

腳本内容:

然後儲存--> 點選建構--> 觀察日志

在kubernetes中部署Jenkins并簡單使用

輸出符合我們腳本内容。

2.2.2、在slave中運作pipeline

上面對jenkins的pipeline做了簡單的測試,但是其并未在我們的slave中運作,如果要在slave中運作,其就要使用我們前面添加的label,如下:

然後我們儲存并點選建構,觀察pod的變化:

我們可以看到其依據我們定義的模闆動态生成了jenkins-slave的pod,我們在jenkins的日志中檢視:

在kubernetes中部署Jenkins并簡單使用

可以看到兩個的名字是一樣的。

部署應用的流程如下:

編寫代碼

測試

編寫 dockerfile

建構打包 docker 鏡像

推送 docker 鏡像到倉庫

編寫 kubernetes yaml 檔案

更改 yaml 檔案中 docker 鏡像 tag

利用 kubectl 工具部署應用

是以基本的pipeline腳本架構應該如下:

第一步:克隆代碼

我們這裡采用和git commit的記錄為鏡像的 tag,這裡有一個好處就是鏡像的 tag 可以和 git 送出記錄對應起來,也友善日後對應檢視。但是由于這個 tag 不隻是我們這一個 stage 需要使用,下一個推送鏡像是不是也需要,是以這裡我們把這個 tag 編寫成一個公共的參數,把它放在 clone 這個 stage 中。

第二步:測試

測試可以是單測,也可以是工具,我們這裡就簡單存在這個步驟。

第三步:建構鏡像

這一步我們就使用到上面定義的build_tag變量。

第四步:推送鏡像

配置jenkins,隐藏使用者名密碼資訊:

在kubernetes中部署Jenkins并簡單使用

其中id:aliregistry 是我們後面要用的值。

這樣我們上面的腳本就可以定義如下:

注意我們這裡在 stage 中使用了一個新的函數withcredentials,其中有一個 credentialsid 值就是我們剛剛建立的 id 值,而對應的使用者名變量就是 id 值加上 user,密碼變量就是 id 值加上 password,然後我們就可以在腳本中直接使用這裡兩個變量值來直接替換掉之前的登入 docker hub 的使用者名和密碼,現在是不是就很安全了,我隻是傳遞進去了兩個變量而已,别人并不知道我的真正使用者名和密碼,隻有我們自己的 jenkins 平台上添加的才知道。

第五步:更改yaml檔案

其yaml檔案為(yaml檔案放在項目根目錄):

第六步:部署

部署階段我們增加人工幹預,可能需要将該版本先釋出到測試環境、qa 環境、或者預覽環境之類的,總之直接就釋出到線上環境去還是挺少見的,是以我們需要增加人工确認的環節,一般都是在 cd 的環節才需要人工幹預,比如我們這裡的最後兩步,我們就可以在前面加上确認,比如:

我們将yaml這一步改為:

然後再部署階段:

由于這一步也屬于部署的範疇,是以我們可以将最後兩步都合并成一步,我們最終的pipeline腳本如下:

然後建構面闆如下:

在kubernetes中部署Jenkins并簡單使用

然後檢視pod日志如下:

2.2.4、jenkinsfile

萬裡長征,貌似我們的任務完成了,其實不然,我們這裡隻是完成了一次手動的添加任務的建構過程,在實際的工作實踐中,我們更多的是将 pipeline 腳本寫入到 jenkinsfile 檔案中,然後和代碼一起送出到代碼倉庫中進行版本管理。現在我們将上面的 pipeline 腳本拷貝到一個 jenkinsfile 中,将該檔案放入上面的 git 倉庫中,但是要注意的是,現在既然我們已經在 git 倉庫中了,是不是就不需要 git clone 這一步驟了,是以我們需要将第一步 clone 操作中的 git clone 這一步去掉。

如下:

然後我們更改上面的 jenkins-demo 這個任務,點選 configure -> 最下方的 pipeline 區域 -> 将之前的 pipeline script 更改成 pipeline script from scm,然後根據我們的實際情況填寫上對應

的倉庫配置,要注意 jenkinsfile 腳本路徑。

在kubernetes中部署Jenkins并簡單使用

在實際的項目中,往往一個代碼倉庫都會有很多分支的,比如開發、測試、線上這些分支都是分開的,一般情況下開發或者測試的分支我們希望送出代碼後就直接進行 ci/cd 操作,而線上的話最好增加一個人工幹預的步驟,這就需要 jenkins 對代碼倉庫有多分支的支援,當然這個特性是被 jenkins 支援的。

然後建立一個 jenkinsfile 檔案,配置如下:

在第一步中我們增加了checkout scm指令,用來檢出代碼倉庫中目前分支的代碼,為了避免各個環境的鏡像 tag 産生沖突,我們為非 master 分支的代碼建構的鏡像增加了一個分支的字首,在第五步中如果是 master 分支的話我們才增加一個确認部署的流程,其他分支都自動部署,并且還需要替換 k8s.yaml 檔案中的環境變量的值。

我們這裡使用 blueocean 這種方式來完成此處 ci/cd 的工作,blueocean 是 jenkins 團隊從使用者體驗角度出發,專為 jenkins pipeline 重新設計的一套 ui 界面,仍然相容以前的 fressstyle 類型的 job,blueocean 具有以下的一些特性:

連續傳遞(cd)pipeline 的複雜可視化,允許快速直覺的了解 pipeline 的狀态

可以通過 pipeline 編輯器直覺的建立 pipeline

需要幹預或者出現問題時快速定位,blueocean 顯示了 pipeline 需要注意的地方,便于異常處理和提高生産力

用于分支和拉取請求的本地內建可以在 github 或者 bitbucket 中與其他人進行代碼協作時最大限度提高開發人員的生産力。

blueocean 可以安裝在現有的 jenkins 環境中,也可以使用 docker 鏡像的方式直接運作,我們這裡直接在現有的 jenkins 環境中安裝 blueocean 插件:登入 jenkins web ui -> 點選左側的 manage jenkins -> manage plugins -> available -> 搜尋查找 blueocean -> 點選下載下傳安裝并重新開機

在kubernetes中部署Jenkins并簡單使用

點選建立:

在kubernetes中部署Jenkins并簡單使用
在kubernetes中部署Jenkins并簡單使用

擷取token的步驟:

在kubernetes中部署Jenkins并簡單使用
在kubernetes中部署Jenkins并簡單使用
在kubernetes中部署Jenkins并簡單使用

然後擷取token:

在kubernetes中部署Jenkins并簡單使用

建立完成如下所示:

在kubernetes中部署Jenkins并簡單使用