­

雲原生之旅 – 10)手把手教你安裝 Jenkins on Kubernetes

前言

談到持續集成工具就離不開眾所周知的Jenkins,本文帶你了解如何在 Kubernetes 上安裝 Jenkins,後續文章會帶你深入了解如何使用k8s pod 作為 Jenkins的build agents。

 

準備

需要一個running的 Kubernetes Cluster, 可以參考我前面的文章 雲原生之旅 – 4)基礎設施即代碼 使用 Terraform 創建 Kubernetes

 

安裝

Step 1: 創建Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: jenkins

namespace.yaml

kubectl apply -f namespace.yaml

  

Step 2: 創建 k8s service account and RBAC 權限

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: jenkins-admin
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["*"]

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-admin
  namespace: jenkins

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins-admin
subjects:
- kind: ServiceAccount
  name: jenkins-admin
  namespace: jenkins

serviceAccount.yaml

kubectl apply -f serviceAccount.yaml

 

Step 3: 創建 StorageClass 和 PersistentVolumeClaim(我的例子是在GCP上面,其它雲提供商類似)

---
## if not create StorageClass, default to use standard StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: jenkins-sc
  namespace: jenkins
provisioner: kubernetes.io/gce-pd
volumeBindingMode: Immediate
allowVolumeExpansion: true
reclaimPolicy: Delete
parameters:
  type: pd-standard
  fstype: ext4
  replication-type: none

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-storage
  namespace: jenkins
spec:
  storageClassName: jenkins-sc
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

volume.yaml

  • Create a storage class
  • Provision a Persistent volume using the storage class.
kubectl apply -f volume.yaml

 檢查綁定結果

kubectl get pvc -n jenkins

NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
jenkins-storage   Bound    pvc-27efe7b9-c963-4366-b100-a3b01bb25666   20Gi       RWO            jenkins-sc     23s

 

Step 4: 創建 Deployment

Jenkins home 目錄需要mount,不然 Jenkins pod 一旦重啟的話,數據會丟失。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins-server
  template:
    metadata:
      labels:
        app: jenkins-server
    spec:
      securityContext:
            fsGroup: 1000 
            runAsUser: 1000
      serviceAccountName: jenkins-admin
      containers:
        - name: jenkins
          image: jenkins/jenkins:lts
          resources:
            limits:
              memory: "2Gi"
              cpu: "1000m"
            requests:
              memory: "500Mi"
              cpu: "500m"
          ports:
            - name: httpport
              containerPort: 8080
            - name: jnlpport
              containerPort: 50000
          livenessProbe:
            httpGet:
              path: "/login"
              port: 8080
            initialDelaySeconds: 90
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 5
          readinessProbe:
            httpGet:
              path: "/login"
              port: 8080
            initialDelaySeconds: 60
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3
          volumeMounts:
            - name: jenkins-data
              mountPath: /var/jenkins_home         
      volumes:
        - name: jenkins-data
          persistentVolumeClaim:
              claimName: jenkins-storage

deployment.yaml

kubectl apply -f deployment.yaml

檢查部署結果

kubectl get deploy -n jenkins

NAME      READY   UP-TO-DATE   AVAILABLE   AGE
jenkins   1/1     1            1           89s

 

Step 5: Create Service

---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-service
  namespace: jenkins
spec:
  selector: 
    app: jenkins-server
  type: NodePort  
  ports:
    - port: 8080
      targetPort: 8080
      nodePort: 32000

---
kind: Service
apiVersion: v1
metadata:
  name: jenkins-agent
  namespace: jenkins
spec:
  selector:
    app: jenkins-server
  ports:
    - protocol: TCP
      port: 50000
      targetPort: 50000

service.yaml

kubectl apply -f service.yaml

### 本文首發於 //www.cnblogs.com/wade-xu/p/16863933.html

 

訪問 Jenkins Dashboard

Option 1: 用  Kube Proxy

kubectl -n jenkins port-forward service/jenkins-service 8010:8080
然後打開本地瀏覽器訪問 Jenkins dashboard ==》 //127.0.0.1:8010

 

Option 2:  推薦使用Gateway 

1. Ingress-Nginx 可以參考 雲原生之旅 – 8)雲原生時代的網關 Ingress Nginx

2. Emissary Ingress 可以參考雲原生之旅 – 9)雲原生時代網關的後起之秀Envoy Proxy 和基於Envoy 的 Emissary Ingress

 

第一次訪問Jenkins Dashboard 會提示需要初始密碼,通過如下訪問獲取初始密碼。
kubectl get pods -n jenkins

kubectl logs jenkins-998474795-7n6ls -n jenkins

 日誌結果

*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

xxxxxxxxxxxxxx

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

輸入 password 然後會提示 install the suggested plugin 和創建一個 admin user.

### 本文首發於 //www.cnblogs.com/wade-xu/p/16863933.html

 

High Availability 高可用

  • Jenkins active/passive setup — 只有企業版Jenkins才有此功能。
  • 本文介紹的 Jenkins running on Kubernetes, 一旦 Jenkins master pod 掛了,另一個新的 Jenkins master pod 會自動起來,並將存儲卷掛載至新創建的容器,保證數據不會丟失,從而實現集群高可用。

 

參考

//github.com/scriptcamp/kubernetes-jenkins/blob/main/deployment.yaml
//www.jenkins.io/doc/book/installing/kubernetes/
 
感謝閱讀,如果您覺得本文的內容對您的學習有所幫助,您可以打賞和推薦,您的鼓勵是我創作的動力