溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于 kubernetes 的動態(tài) jenkins slav

發(fā)布時間:2020-02-24 14:56:37 來源:網(wǎng)絡(luò) 閱讀:648 作者:jxsdbk 欄目:云計算
                          **基于 Jenkins 的 CI/CD**

既然要創(chuàng)建一個deployment,那我們先給他創(chuàng)建一個namespace

kubectl create namespace kube-ops

然后我們創(chuàng)建一個deployment

基于 kubernetes 的動態(tài) jenkins slav
基于 kubernetes 的動態(tài) jenkins slav

我們這里使用一個名為 jenkins/jenkins:lts 的鏡像,這是 jenkins 官方的 Docker 鏡像,然后也有一些環(huán)境變量,當(dāng)然我們也可以根據(jù)自己的需求來定制一個鏡像,比如我們可以將一些插件打包在自定義的鏡像當(dāng)中,可以參考文檔:https://github.com/jenkinsci/docker,我們這里使用默認(rèn)的官方鏡像就行,另外一個還需要注意的是我們將容器的 /var/jenkins_home 目錄掛載到了一個名為 opspvc 的 PVC 對象上面,所以我們同樣還得提前創(chuàng)建一個對應(yīng)的 PVC 對象

然后我們?yōu)樗麆?chuàng)建pvc(pvc.yaml)
基于 kubernetes 的動態(tài) jenkins slav

我們?yōu)榱藴y試方便,使用了nfs做到持久化存儲

然后我們創(chuàng)建這個pvc對象。

kubectl apply -f pvc.yaml

我們這里還需要使用到一個擁有相關(guān)權(quán)限的 serviceAccount:jenkins2,我們這里只是給 jenkins 賦予了一些必要的權(quán)限,當(dāng)然如果你對 serviceAccount 的權(quán)限不是很熟悉的話,我們給這個 sa 綁定一個 cluster-admin 的集群角色權(quán)限也是可以的,當(dāng)然這樣具有一定的安全風(fēng)險:(rbac.yaml)

基于 kubernetes 的動態(tài) jenkins slav基于 kubernetes 的動態(tài) jenkins slav

kubectl apply -f rbac.yaml

為了方便我們測試,我們這里通過 NodePort(后面會使用traefik,nginx-ingress) 的形式來暴露 Jenkins 的 web 服務(wù),固定為30005端口,另外還需要暴露一個 agent 的端口,這個端口主要是用于 Jenkins 的 master 和 slave 之間通信使用的。

一切準(zhǔn)備的資源準(zhǔn)備好過后,我們直接創(chuàng)建 Jenkins 服務(wù):

kubectl apply -f jenkins2.yaml

我們首次創(chuàng)建的時候

基于 kubernetes 的動態(tài) jenkins slav

可以看到該 Pod 處于 Running 狀態(tài),但是 READY 值確為0,然后我們用 describe 命令去查看下該 Pod 的詳細(xì)信息:

基于 kubernetes 的動態(tài) jenkins slav

可以看到上面的 Warning 信息,健康檢查沒有通過,具體原因是什么引起的呢?可以通過查看日志進(jìn)一步了解:

基于 kubernetes 的動態(tài) jenkins slav

很明顯可以看到上面的錯誤信息,意思就是我們沒有權(quán)限在 jenkins 的 home 目錄下面創(chuàng)建文件,這是因為默認(rèn)的鏡像使用的是 jenkins 這個用戶,而我們通過 PVC 掛載到 nfs 服務(wù)器的共享數(shù)據(jù)目錄下面卻是 root 用戶的,所以沒有權(quán)限訪問該目錄,要解決該問題,也很簡單,我只需要在 nfs 共享數(shù)據(jù)目錄下面把我們的目錄權(quán)限重新分配下即可:

chown -R 1000 /data/k8s/jenkins2

然后我們重建

kubectl delete jenkins2.yaml
kubectl apply -f jenkins2.yaml

基于 kubernetes 的動態(tài) jenkins slav

你就可以看到這個pods的狀態(tài)已經(jīng)是正常的了。

我們就可以通過任意節(jié)點的 IP:30005 端口就可以訪問 jenkins 服務(wù)了,可以根據(jù)提示信息進(jìn)行安裝配置即可:

基于 kubernetes 的動態(tài) jenkins slav

到了這個頁面,我們就可以去pod里面獲取密碼了,或者在日志里面查看密碼

kubectl exec -it jenkins2-6bbb7d9f4c-v9cfd -n kube-ops bash

然后根據(jù)上面的提示獲取密碼。
基于 kubernetes 的動態(tài) jenkins slav

然后就看到了jenkins的主頁面了

先不要著集使用

我們知道持續(xù)構(gòu)建與發(fā)布是我們?nèi)粘9ぷ髦斜夭豢缮俚囊粋€步驟,目前大多公司都采用 Jenkins 集群來搭建符合需求的 CI/CD 流程,然而傳統(tǒng)的 Jenkins Slave 一主多從方式會存在一些痛點,比如:

主 Master 發(fā)生單點故障時,整個流程都不可用了
每個 Slave 的配置環(huán)境不一樣,來完成不同語言的編譯打包等操作,但是這些差異化的配置導(dǎo)致管理起來非常不方便,維護起來也是比較費勁
資源分配不均衡,有的 Slave 要運行的 job 出現(xiàn)排隊等待,而有的 Slave 處于空閑狀態(tài)
資源有浪費,每臺 Slave 可能是物理機或者虛擬機,當(dāng) Slave 處于空閑狀態(tài)時,也不會完全釋放掉資源。

正因為上面的這些種種痛點,我們渴望一種更高效更可靠的方式來完成這個 CI/CD 流程,而 Docker 虛擬化容器技術(shù)能很好的解決這個痛點,又特別是在 Kubernetes 集群環(huán)境下面能夠更好來解決上面的問題,下圖是基于 Kubernetes 搭建 Jenkins 集群的簡單示意圖:

基于 kubernetes 的動態(tài) jenkins slav

那么我們使用這種方式帶來了哪些好處呢?

服務(wù)高可用,當(dāng) Jenkins Master 出現(xiàn)故障時,Kubernetes 會自動創(chuàng)建一個新的 Jenkins Master 容器,并且將 Volume 分配給新創(chuàng)建的容器,保證數(shù)據(jù)不丟失,從而達(dá)到集群服務(wù)高可用。
動態(tài)伸縮,合理使用資源,每次運行 Job 時,會自動創(chuàng)建一個 Jenkins Slave,Job 完成后,Slave 自動注銷并刪除容器,資源自動釋放,而且 Kubernetes 會根據(jù)每個資源的使用情況,動態(tài)分配 Slave 到空閑的節(jié)點上創(chuàng)建,降低出現(xiàn)因某節(jié)點資源利用率高,還排隊等待在該節(jié)點的情況。
擴展性好,當(dāng) Kubernetes 集群的資源嚴(yán)重不足而導(dǎo)致 Job 排隊等待時,可以很容易的添加一個 Kubernetes Node 到集群中,從而實現(xiàn)擴展。

配置

接下來我們就需要來配置 Jenkins,讓他能夠動態(tài)的生成 Slave 的 Pod。

我們先進(jìn)去到插件管理

基于 kubernetes 的動態(tài) jenkins slav

因為我已經(jīng)安裝了,你們只需要在可選插件里面選擇kubernetes安裝就好了。

安裝好了之后,我們到系統(tǒng)管理的系統(tǒng)配置,拖到最下方,選擇kubernetes

基于 kubernetes 的動態(tài) jenkins slav

注意 namespace,我們這里填 kube-ops,然后點擊Test Connection,如果出現(xiàn) Connection test successful 的提示信息證明 Jenkins 已經(jīng)可以和 Kubernetes 系統(tǒng)正常通信了,然后下方的 Jenkins URL 地址:http://jenkins2.kube-ops.svc.cluster.local:8080,這里的格式為:服務(wù)名.namespace.svc.cluster.local:8080,根據(jù)上面創(chuàng)建的jenkins 的服務(wù)名填寫,我這里是之前創(chuàng)建的名為jenkins,如果是用上面我們創(chuàng)建的就應(yīng)該是jenkins2

另外需要注意,如果這里 Test Connection 失敗的話,很有可能是權(quán)限問題,這里就需要把我們創(chuàng)建的 jenkins 的 serviceAccount 對應(yīng)的 secret 添加到這里的 Credentials 里面。

然后我們配置 Pod Template,其實就是配置 Jenkins Slave 運行的 Pod 模板,命名空間我們同樣是用 kube-ops,Labels 這里也非常重要,對于后面執(zhí)行 Job 的時候需要用到該值,然后我們這里使用的是 cnych/jenkins:jnlp 這個鏡像,這個鏡像是在官方的 jnlp 鏡像基礎(chǔ)上定制的,加入了 kubectl 等一些實用的工具。

基于 kubernetes 的動態(tài) jenkins slav

后面運行的命令和命令參數(shù)我們給他刪掉。

另外需要注意我們這里需要在下面掛載兩個主機目錄,一個是/var/run/docker.sock,該文件是用于 Pod 中的容器能夠共享宿主機的 Docker,這就是大家說的 docker in docker 的方式,Docker 二進(jìn)制文件我們已經(jīng)打包到上面的鏡像中了,另外一個目錄下/root/.kube目錄,我們將這個目錄掛載到容器的 /root/.kube 目錄下面這是為了讓我們能夠在 Pod 的容器中能夠使用 kubectl 工具來訪問我們的 Kubernetes 集群,方便我們后面在 Slave Pod 部署 Kubernetes 應(yīng)用。

基于 kubernetes 的動態(tài) jenkins slav

配置了后運行 Slave Pod 的時候出現(xiàn)了權(quán)限問題,如果出現(xiàn)了權(quán)限不足的問題,在 Slave Pod 配置的地方點擊下面的高級,添加上對應(yīng)的 ServiceAccount 即可:

基于 kubernetes 的動態(tài) jenkins slav

到這里我們的 Kubernetes Plugin 插件就算配置完成了。

基于 kubernetes 的動態(tài) jenkins slav

然后我們創(chuàng)建一個自由項目。

基于 kubernetes 的動態(tài) jenkins slav

基于 kubernetes 的動態(tài) jenkins slav

然后我們保存。

我們測試構(gòu)建。

在構(gòu)建的時候,我們?nèi)タ磈enkins的狀態(tài),會創(chuàng)建一個jnlp的pod。

基于 kubernetes 的動態(tài) jenkins slav

構(gòu)建任務(wù)完成后,我們再去看pod列表,已經(jīng)沒有這個jnlp的pod的。

到這里我們就完成了使用 Kubernetes 動態(tài)生成 Jenkins Slave 的方法。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI