Jenkins:乘着 Kubernetes 的翅膀

前言

Kubernetes + Docker 是一對有意思的組合,爲微服務架構的落地,掃清了最後一公里的障礙,在符合企業 IT 治理需求的前提之下,爲傳統企業應用的平滑過渡提供了有效條件和方法。

作爲軟件生產環節中重要組成部分的持續構建和發佈過程,自然也要隨勢而動,這方面的老將 Jenkins 不但提供了用於構建、推送 Docker 鏡像的插件,更提供了利用 Kubernetes 運行構建集羣的能力。本文將利用一個簡單的 Hello world 項目,來展示 Jenkins 的這一特性。

準備工作

Kubernetes 集羣安裝

要在 Kubernetes 集羣完成下面所有的工作,因此首先進行集羣的安裝和配置,這方面可以參考官方入門文檔,如果英語不靈但動手排錯能力強的話,也可以參考已經過時的拙作

集羣安裝後,應該具有以下能力:

  1. 集羣具有受 DNS 支持的服務尋址能力;
  2. 能夠利用 Kubectl 或者其他方法發佈容器應用的能力;
  3. 私有鏡像庫,或者到 Docker Hub 的網絡連接;
  4. Pause 鏡像也自然是 Kubernetes 中運行應用的必須條件。

Jenkins 鏡像

本文例子採用自制的一個集成鏡像爲基礎工具,該鏡像集成了衆多常用的 CI/CD 工具,另外同時還包含了 Jenkins 的 Master 和 Slave 兩種模式,鏡像託管在 Docker Hub,源碼可在 Github 瀏覽和下載。

如果具有直接連接 Docker Hub 的網絡連接,則可無需理會;否則就需要下載鏡像,並上傳至私庫。爲行文方便,這裏假設採用私庫方式,鏡像地址爲 10.211.55.5:5000/jenkins:2.7.4.5

共享存儲

因容器在集羣中的運行狀況未知,一般來說是需要爲容器化應用提供共享存儲服務的,本文中採用最簡單的 NFS 方式,當然也可以使用官方支持的其他方式,例如 GlusterFS、Flocker 以及 Ceph 等等,具體支持能力可以參看官方說明,當然,如果只是學習測試,使用缺省的 Empty 格式亦可,或者偷懶使用 HostPath 方式結合限定 Node 運行的方式也能夠完成任務。

本文中的卷掛載方式很是粗糙,目前推薦的共享存儲方式是持久卷(PV & PVC)方式,以提供更好的管控能力,中文可參考:Kubernetes 中的 Persistent Volumes

Jenkins Master

YAML

首先要爲我們的 Jenkins 鏡像編寫一個 Yaml ,用於提交到集羣中運行:

kind: ReplicationController
apiVersion: v1
metadata:
 name: jenkins
 labels:
 name: jenkins
spec:
 replicas: 1
 selector:
 name: jenkins
 template:
 metadata:
 labels:
 name: jenkins
 spec:
 containers: - name: jenkins
 image: 10.211.55.5:5000/jenkins:2.7.4.5
 ports: - containerPort: 8080
 protocol: TCP
 - containerPort: 8081
 protocol: TCP
 volumeMounts: - name: jenkins
 mountPath: /data/jenkins
 volumes: - name: jenkins
 nfs:
 server: 10.211.55.5
 path: /var/data/nfs/ci/jenkins
 readOnly: false ---
kind: Service
apiVersion: v1
metadata:
 name: jenkins
 labels:
 name: jenkins
spec:
 type: NodePort
 ports: - protocol: TCP
 nodePort: 32502
 targetPort: 8080
 port: 8080
 name: web
 - protocol: TCP
 targetPort: 8081
 port: 8081
 name: service
 selector:
 name: jenkins

上面的 YML 文件有幾點需要注意

  1. 掛載:Jenkins 的所有插件、配置和工作文件都處於環境變量 JENKINS_HOME 所示的路徑中,因此我們這裏利用 NFS 把位於 10.211.55.5 上的 /var/data/nfs/ci/jenkins 目錄映射到容器的/data/jenkins 之中,讓 Jenkins 獲得持久化存儲。
  2. 端口:Jenkins 缺省運行需要 8080 端口對外提供 Web 界面。這裏我們另外聲明瞭一個 8081 端口,爲集羣內新建的 Slave 提供通信能力,可以看到,下面的 Service 定義中,僅僅使用 NodePort 方式暴露了一個 Web 端口
  3. 時區:鏡像提供了 TIMEZONE 環境變量,這一變量將會在運行時影響容器操作系統以及 Jenkins 的 JVM 的時區設置。這一變量缺省使用 Asia/Shanghai。
  4. JENKINS_MODE:用於指示 Jenkins 的運行模式,可選值爲 MASTER 或者 SLAVE,缺省運行在MASTER 模式下。

運行和配置

接下來就可以使用 kubectl create -f jenkins.yaml 來運行鏡像了。執行之後可以刷 kubectl get pods 來查看啓動情況。

這一 RC 的啓動需要加載 NFS 卷,因此如果啓動時間過長,可以使用 kubectl get events 命令查看是否加載出了問題。

Pod 變爲 Running 狀態之後,就可以嘗試採用上面 YAML 中定義的 Node Port 來訪問 Jenkins 界面了,經過一段時間的 “Jenkins正在啓動,請稍後…..”,系統要求輸入/data/jenkins/secrets/initialAdminPassword 文件中保存的初始密碼,假設前面 get pods 命令得到的 Pod 名稱是 jenkins-7nmka,這裏就可以使用 kubectl exec jenkins-7nmka cat /data/jenkins/secrets/initialAdminPassword 來查看,獲取結果後即可複製黏貼到錄入框中繼續安裝。

接下來的插件安裝,爲節省時間直接 Select None。接下來設置管理員用戶名密碼,保存後,安裝結束。

安裝和配置 Kubernetes 插件

安裝

接下來就是進入 pluginManager/available 頁面安裝插件。

如果網絡需要代理,可以進入網址 /pluginManager/advanced,設置代理服務器。 如果可選插件頁面爲空,可以在 /pluginManager/advanced 頁面裏面點擊 “立即獲取” 按鈕進行刷新。

過濾框中輸入 “kubernetes” 會看到列表中的 “Kubernetes plugin”,選擇安裝。

配置 Jenkins

安裝成功後,進入配置頁面(/configure)。

首先爲了測試方便,我們把 “執行者數量” 設置爲 0,也就是說只使用 Jenkins Slave 進行構建。

配置 Kubernetes

可以看到,頁面下方有一個按鈕 “新增一個雲”,點擊後出現 Kubernetes 配置項目。

這裏我們用無認證的 http 方式進行連接,Kubernetes URL 中填入 API Server 的 http 地址,例如:http://10.211.55.5:8080。

Jenkins URL 中,這裏要注意我們不應該使用瀏覽器地址欄中的 Node 地址,而是應該使用集羣內部的服務地址,根據上文中 Service 的定義,這裏使用 http://jenkins:8080。

最後是 ”Add Pod Template“ 按鈕,來定義 Slave 的 Pod 模板:

  • 這裏的 “Docker Image” 項目跟上面使用的是同一個地址,也就是10.211.55.5:5000/jenkins:2.7.4.5;
  • 根據前文說道的環境變量,這裏我們新增一個環境變量:JENKINS_MODE=SLAVE,
  • “Jenkins slave root directory” 這一項填寫 /data/jenkins,
  • “Command to run slave agent ” 這裏填寫鏡像中的啓動命令 /usr/local/bin/run.sh

填寫完成後,保存。

配置端口

最後需要到安全配置頁面(/configureSecurity),TCP port for JNLP agents 一項填寫固定端口 8081。

Hello world

創建

新建一個 Free Style 項目。構建步驟中新增 “Execute shell script” 環節,並保存,內容爲

echo "Hello World"

構建

點擊該任務的 “立即構建” 按鈕,即可觸發構建動作。

因爲前面我們設置 Master 不執行構建工作,所以在構建啓動之後,會在構建執行狀態中看到有節點被動態新建,來執行我們的構建過程。這一過程中如果使用 kubectl get events 或者 kubectl get pods 命令,能看到 Jenkins Slave Pod 的創建、執行和銷燬過程。

尾聲

上面只是一個最爲基礎的構建過程,甚至都無法稱爲是一個完整過程,Kubernetes 插件還提供了很多其他選項,結合自定義的 Slave 鏡像,能夠完成更多更復雜的任務,用於配合實際的生產過程。

本文轉自中文社區-Jenkins:乘着 Kubernetes 的翅膀

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章