1. 程式人生 > >Jenkins:乘著 Kubernetes 的翅膀_Kubernetes中文社群

Jenkins:乘著 Kubernetes 的翅膀_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 執行的方式也能夠完成任務。

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 映象,能夠完成更多更復雜的任務,用於配合實際的生產過程。