您好,登錄后才能下訂單哦!
**基于 Jenkins 的 CI/CD**
既然要創建一個deployment,那我們先給他創建一個namespace
kubectl create namespace kube-ops
然后我們創建一個deployment
我們這里使用一個名為 jenkins/jenkins:lts 的鏡像,這是 jenkins 官方的 Docker 鏡像,然后也有一些環境變量,當然我們也可以根據自己的需求來定制一個鏡像,比如我們可以將一些插件打包在自定義的鏡像當中,可以參考文檔:https://github.com/jenkinsci/docker,我們這里使用默認的官方鏡像就行,另外一個還需要注意的是我們將容器的 /var/jenkins_home 目錄掛載到了一個名為 opspvc 的 PVC 對象上面,所以我們同樣還得提前創建一個對應的 PVC 對象
然后我們為他創建pvc(pvc.yaml)
我們為了測試方便,使用了nfs做到持久化存儲
然后我們創建這個pvc對象。
kubectl apply -f pvc.yaml
我們這里還需要使用到一個擁有相關權限的 serviceAccount:jenkins2,我們這里只是給 jenkins 賦予了一些必要的權限,當然如果你對 serviceAccount 的權限不是很熟悉的話,我們給這個 sa 綁定一個 cluster-admin 的集群角色權限也是可以的,當然這樣具有一定的安全風險:(rbac.yaml)
kubectl apply -f rbac.yaml
為了方便我們測試,我們這里通過 NodePort(后面會使用traefik,nginx-ingress) 的形式來暴露 Jenkins 的 web 服務,固定為30005端口,另外還需要暴露一個 agent 的端口,這個端口主要是用于 Jenkins 的 master 和 slave 之間通信使用的。
一切準備的資源準備好過后,我們直接創建 Jenkins 服務:
kubectl apply -f jenkins2.yaml
我們首次創建的時候
可以看到該 Pod 處于 Running 狀態,但是 READY 值確為0,然后我們用 describe 命令去查看下該 Pod 的詳細信息:
可以看到上面的 Warning 信息,健康檢查沒有通過,具體原因是什么引起的呢?可以通過查看日志進一步了解:
很明顯可以看到上面的錯誤信息,意思就是我們沒有權限在 jenkins 的 home 目錄下面創建文件,這是因為默認的鏡像使用的是 jenkins 這個用戶,而我們通過 PVC 掛載到 nfs 服務器的共享數據目錄下面卻是 root 用戶的,所以沒有權限訪問該目錄,要解決該問題,也很簡單,我只需要在 nfs 共享數據目錄下面把我們的目錄權限重新分配下即可:
chown -R 1000 /data/k8s/jenkins2
然后我們重建
kubectl delete jenkins2.yaml
kubectl apply -f jenkins2.yaml
你就可以看到這個pods的狀態已經是正常的了。
我們就可以通過任意節點的 IP:30005 端口就可以訪問 jenkins 服務了,可以根據提示信息進行安裝配置即可:
到了這個頁面,我們就可以去pod里面獲取密碼了,或者在日志里面查看密碼
kubectl exec -it jenkins2-6bbb7d9f4c-v9cfd -n kube-ops bash
然后根據上面的提示獲取密碼。
然后就看到了jenkins的主頁面了
先不要著集使用
我們知道持續構建與發布是我們日常工作中必不可少的一個步驟,目前大多公司都采用 Jenkins 集群來搭建符合需求的 CI/CD 流程,然而傳統的 Jenkins Slave 一主多從方式會存在一些痛點,比如:
主 Master 發生單點故障時,整個流程都不可用了
每個 Slave 的配置環境不一樣,來完成不同語言的編譯打包等操作,但是這些差異化的配置導致管理起來非常不方便,維護起來也是比較費勁
資源分配不均衡,有的 Slave 要運行的 job 出現排隊等待,而有的 Slave 處于空閑狀態
資源有浪費,每臺 Slave 可能是物理機或者虛擬機,當 Slave 處于空閑狀態時,也不會完全釋放掉資源。
正因為上面的這些種種痛點,我們渴望一種更高效更可靠的方式來完成這個 CI/CD 流程,而 Docker 虛擬化容器技術能很好的解決這個痛點,又特別是在 Kubernetes 集群環境下面能夠更好來解決上面的問題,下圖是基于 Kubernetes 搭建 Jenkins 集群的簡單示意圖:
那么我們使用這種方式帶來了哪些好處呢?
服務高可用,當 Jenkins Master 出現故障時,Kubernetes 會自動創建一個新的 Jenkins Master 容器,并且將 Volume 分配給新創建的容器,保證數據不丟失,從而達到集群服務高可用。
動態伸縮,合理使用資源,每次運行 Job 時,會自動創建一個 Jenkins Slave,Job 完成后,Slave 自動注銷并刪除容器,資源自動釋放,而且 Kubernetes 會根據每個資源的使用情況,動態分配 Slave 到空閑的節點上創建,降低出現因某節點資源利用率高,還排隊等待在該節點的情況。
擴展性好,當 Kubernetes 集群的資源嚴重不足而導致 Job 排隊等待時,可以很容易的添加一個 Kubernetes Node 到集群中,從而實現擴展。
配置
接下來我們就需要來配置 Jenkins,讓他能夠動態的生成 Slave 的 Pod。
我們先進去到插件管理
因為我已經安裝了,你們只需要在可選插件里面選擇kubernetes安裝就好了。
安裝好了之后,我們到系統管理的系統配置,拖到最下方,選擇kubernetes
注意 namespace,我們這里填 kube-ops,然后點擊Test Connection,如果出現 Connection test successful 的提示信息證明 Jenkins 已經可以和 Kubernetes 系統正常通信了,然后下方的 Jenkins URL 地址:http://jenkins2.kube-ops.svc.cluster.local:8080,這里的格式為:服務名.namespace.svc.cluster.local:8080,根據上面創建的jenkins 的服務名填寫,我這里是之前創建的名為jenkins,如果是用上面我們創建的就應該是jenkins2
另外需要注意,如果這里 Test Connection 失敗的話,很有可能是權限問題,這里就需要把我們創建的 jenkins 的 serviceAccount 對應的 secret 添加到這里的 Credentials 里面。
然后我們配置 Pod Template,其實就是配置 Jenkins Slave 運行的 Pod 模板,命名空間我們同樣是用 kube-ops,Labels 這里也非常重要,對于后面執行 Job 的時候需要用到該值,然后我們這里使用的是 cnych/jenkins:jnlp 這個鏡像,這個鏡像是在官方的 jnlp 鏡像基礎上定制的,加入了 kubectl 等一些實用的工具。
后面運行的命令和命令參數我們給他刪掉。
另外需要注意我們這里需要在下面掛載兩個主機目錄,一個是/var/run/docker.sock,該文件是用于 Pod 中的容器能夠共享宿主機的 Docker,這就是大家說的 docker in docker 的方式,Docker 二進制文件我們已經打包到上面的鏡像中了,另外一個目錄下/root/.kube目錄,我們將這個目錄掛載到容器的 /root/.kube 目錄下面這是為了讓我們能夠在 Pod 的容器中能夠使用 kubectl 工具來訪問我們的 Kubernetes 集群,方便我們后面在 Slave Pod 部署 Kubernetes 應用。
配置了后運行 Slave Pod 的時候出現了權限問題,如果出現了權限不足的問題,在 Slave Pod 配置的地方點擊下面的高級,添加上對應的 ServiceAccount 即可:
到這里我們的 Kubernetes Plugin 插件就算配置完成了。
然后我們創建一個自由項目。
然后我們保存。
我們測試構建。
在構建的時候,我們去看jenkins的狀態,會創建一個jnlp的pod。
構建任務完成后,我們再去看pod列表,已經沒有這個jnlp的pod的。
到這里我們就完成了使用 Kubernetes 動態生成 Jenkins Slave 的方法。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。