基於 Jenkins 和 K8s 的 CICD 學習隨筆(Kubectl)


參考:http://www.mydlq.club/article/47/

一、CICD 流程圖參考

二、必要的插件說明

  • Git: Jenkins 安裝中默認安裝 Git 插件,所以不需要單獨安裝。利用 git 工具可以將 github、gitlab 等等的地址下載源碼。
  • Docker: Jenkins 安裝中默認安裝 Docker 插件,所以不需要單獨安裝。利用 Docker 插件可以設置 Docker 環境,運行 Docker 命令,配置遠程 Docker 倉庫憑據等。
  • Kubernetes: Kubernetes 插件的目的是能夠使用 Kubernetes 集群動態配置 Jenkins 代理(使用Kubernetes調度機制來優化負載),運行單個構建,等構建完成后刪除該代理。這里我們需要用到這個插件來啟動 Jenkins Slave 代理鏡像,讓代理執行 Jenkins 要執行的 Job。
  • Kubernetes Cli: Kubernetes Cli 插件作用是在執行 Jenkins Job 時候提供 kubectl 與 Kubernetes 集群交互環境。可以在 Pipeline 或自由式項目中允許執行 kubectl 相關命令。它的主要作用是提供 kubectl 運行環境,當然也可以提供 helm 運行環境。
  • Config File Provider: Config File Provider 插件作用就是提供在 Jenkins 中存儲 properties、xml、json、settings.xml 等信息,可以在執行 Pipeline 過程中可以寫入存儲的配置。例如,存入一個 Maven 全局 Settings.xml 文件,在執行 Pipeline Job 時候引入該 Settings.xml ,這樣 Maven 編譯用的就是該全局的 Settings.xml。
  • Pipeline Utility Steps: 這是一個操作文件的插件,例如讀寫 json、yaml、pom.xml、Properties 等等。在這里主要用這個插件讀取 pom.xml 文件的參數設置,獲取變量,方便構建 Docker 鏡像。
  • Git Parameter: 能夠與 Git 插件結合使用,動態獲取 Git 項目中分支信息,在 Jenkins Job 構建前提供分支選項,來讓項目執行人員選擇拉取對應分支的代碼。

三、必要的憑據說明

選擇 <憑據->系統->全局憑據->添加憑據> 來新增 Git、Docker Hub、Kubernetes 等認證憑據。

  • Git 認證憑據

配置的參數值:

    類型:Username with password
    范圍:全局
    用戶名(Git 用戶名): 略
    密碼(Git 密碼):略
    ID:global-git-credential
    描述:全局 Git 憑據
  • Kubernetes Token 憑據

配置的參數值:

    類型:Secret text
    范圍:全局
    Secret(K8S Token 串):略
    ID:global-kubernetes-credential
    描述:全局的 K8S Token
  • Docker 倉庫認證憑據

配置的參數值:

    類型:Username with password
    范圍:全局
    用戶名(Docker 倉庫用戶名):略
    密碼(Docker 倉庫密碼):略
    ID:docker-hub-credential
    描述:Docker 倉庫認證憑據

四、Jenkins 配置 Kubernetes 插件

Kubernetes Plugin 基本配置

  • 配置連接 Kubernetes 參數

注意: 如果你的 Jenkins 也是安裝在 Kubernetes 環境中,那么可以直接使用 Kubernetes 集群內的 Kubernetes API 地址,如果 Jnekins 是在安裝在正常物理機或者虛擬機環境中,那么使用集群外的 Kubernetes API 地址。

  • 配置 Jenkins 地址

注意: 這里的 Jenkins 地址是供 Slave 節點連接 Jenkins Master 節點用的,所以這里需要配置 Jenkins Master 的 URL 地址。這里和上面一樣,也是考慮 Jenkins 是部署在 Kubernetes 集群內還是集群外。如果 Jnekins 中配置了 /jenkins 前綴,則 URL 后面加上 /jenkins,否則不加,這個地址根據自己的 Jnekins 實際情況來判斷。

Kubernetes 插件 Pod 模板配置

  • 配置 Pod 名稱和標簽列表

配置 Pod 模板的名稱和標簽列表名,Pod 模板名可用於子模板繼承,標簽列表可用於 Jenkins Job 中指定,使用此 Pod 模板來執行任務。

  • 配置 Pod 的原始 yaml

在 Pod 的原始 yaml 配置中,加入一段配置,用於改變 Kubernetes Plugin 自帶的 JNLP 鏡像,並指定 RunAsUser=0 來使容器以 Root 身份執行任務,並設置 privileged=true 來讓 Slave Pod 在 Kubernetes 中擁有特權。

yaml 內容如下:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: jenkins-slave
spec:
  securityContext:
    runAsUser: 0
    privileged: true
  containers:
  - name: jnlp
    tty: true
    workingDir: /home/jenkins/agent
    image: jenkins/agent:4.10-1-alpine

Jenkins Slave JNLP 鏡像官方地址: https://hub.docker.com/r/jenkins/agent/

Kubernetes 插件 Container 配置

  • 配置 Maven 鏡像

Maven 鏡像可以從官方 Docker Hub 下載,地址:https://hub.docker.com/_/maven

  • 配置 Docker In Docker 鏡像

這里推薦使用 dind 版本的鏡像,Docker-IN-Docker 鏡像可以從官方 Docker Hub 下載,地址:https://hub.docker.com/_/docker

  • 配置 Kubectl 鏡像

Kubectl 鏡像可以從官方 Docker Hub 下載,地址:https://hub.docker.com/r/bitnami/kubectl

Container 存儲掛載配置

由於上面配置的 Maven、Docker 等都需要掛載存儲,Maven 中是將中央倉庫下載的 Jar 存儲到共享目錄,而 Docker 則是需要將宿主機的 Docker 配置掛載到 Docker In Docker 容器內部,所以我們要對掛載進行配置。

  • 創建 Maven 存儲使用的 PVC

例如:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: maven
  namespace: cicd
spec:
  storageClassName: cephfs
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  • 配置 Maven 掛載

  • 配置 Docker 掛載

Kubernetes 中 Pod 的容器是啟動在各個節點上,每個節點就是一台宿主機,里面進行了很多 Docker 配置,所以我們這里將宿主機的 Docker 配置掛載進入 Docker 鏡像。選擇添加卷,選擇 Host Path Volume 按如下添加配置:

路徑 /usr/bin/docker:

主機路徑(宿主機目錄):/usr/bin/docker
掛載路徑(容器內的目錄):/usr/bin/docker

路徑 /var/run/docker.sock:

主機路徑(宿主機目錄):/var/run/docker.sock
掛載路徑(容器內的目錄):/var/run/docker.sock

路徑 /etc/docker:

主機路徑(宿主機目錄):/etc/docker
掛載路徑(容器內的目錄):/etc/docker

五、Jenkins 創建相關文件

之前安裝了 Config File Provider 插件,該插件功能就是可以在 Jenkins 上存儲一些配置文件,例如,我們經常使用到的 yaml、properties、Dockerfile、Maven 的 Settings.xml 等文件,都可以存儲到 Jenkins 該插件中。

打開 系統管理->Managed files ,在其中新增幾個文件:

  • Maven 配置文件: Maven 的 Settings.xml 配置文件。
  • Dockerfile 文件: Dockerfile 腳本。
  • Kubernetes 部署文件: 將應用部署到 kubernetes 的 Deployment 文件。

新增 Maven 配置文件

選擇 Add a new Config—>Global Maven settings.xml 來新增一個 Maven 全局 Settings.xml 文件:

ID: global-maven-settings
Name: MavenGlobalSettings
Comment: 全局 Maven Settings.xml 文件
Content: 內容如下

示例文件內容:

<?xml version="1.0" encoding="UTF-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <pluginGroups>
  </pluginGroups>

  <proxies>
  </proxies>

  <servers>
  </servers>
  
  <mirrors>
    <!--Aliyun Maven-->
    <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
  
  <profiles>
  </profiles>

</settings>

為了加快 jar 包的下載速度,這里將倉庫地址指向 aliyun Maven 倉庫地址。

新增 Dockerfile 文件

選擇 Add a new Config—>Custom file 來新增一個 Dockerfile 文件:

ID: global-dockerfile-file
Name: Dockerfile
Comment: 全局 Dockerfile 文件
Content: 內容如下

示例文件內容:

FROM openjdk:8u222-jre-slim
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JVM_OPTS="-Xss256k -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom"
ENV JAVA_OPTS=""
ENV APP_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JVM_OPTS $JAVA_OPTS -jar /app.jar $APP_OPTS" ]

新增 Kubernetes 部署文件

選擇 Add a new Config—>Custom file 來新增一個 Kubernetes 部署文件:

ID: global-kubernetes-deployment
Name: deployment.yaml
Comment: 全局 Kubernetes 部署文件
Content: 內容如下

示例文件內容:

apiVersion: v1
kind: Service
metadata:
  name: #APP_NAME
  labels:
    app: #APP_NAME
spec:
  type: NodePort
  ports:
  - name: server          #服務端口
    port: 8080  
    targetPort: 8080
  - name: management      #監控及監控檢查的端口 
    port: 8081
    targetPort: 8081
  selector:
    app: #APP_NAME
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: #APP_NAME
  labels:
    app: #APP_NAME
spec:
  replicas: #APP_REPLICAS
  selector:
    matchLabels:
      app: #APP_NAME
  strategy:
    type: Recreate          #設置更新策略為刪除策略
  template:
    metadata:
      labels:
        app: #APP_NAME
    spec:
      containers:
      - name: #APP_NAME
        image: #APP_IMAGE_NAME
        imagePullPolicy: Always
        ports:
        - containerPort: 8080   #服務端口
          name: server
        - containerPort: 8081   #監控及監控檢查的端口 
          name: management
        env:
        - name: "update_uuid"
          value: "#APP_UUID"    #生成的隨機值,放置執行kubectl apply時能夠執行
        resources: 
          limits:
            cpu: 2000m
            memory: 1024Mi
          requests:
            cpu: 1000m
            memory: 512Mi

為了模板能夠動態替換某些值,上面模板中設置了幾個可替換的參數,用 #變量名稱 來標記,后面我們在執行 Pipeline 時候將里面的 #xxx變量 標記替換掉。

六、流水線腳本編寫和插件使用說明

腳本中設置全局超時時間

設置任務超時時間,如果在規定時間內任務沒有完成,則進行失敗操作,格式如下:

timeout(time: 60, unit: 'SECONDS') {
    // 腳本
}

腳本中使用 Git 插件

Git 插件方法使用格式,及其部分參數:

  • changelog: 是否檢測變化日志
  • url: Git 項目地址
  • branch: Git 分支
  • credentialsId: Jenkins 保存的 Git 憑據 ID 值
git changelog: true,
    url: "http://gitlab.xxxx/xxx.git"
    branch: "master",
    credentialsId: "xxxx-xxxx-xxxx-xxxx",

腳本中使用 Kubernetes 插件

Kubernetes 插件中存在 PodTemplate 方法,在執行腳本時候,會自動在 Kubernetes 中創建 Pod Template 配置的 Slave Pod,在其中執行 podTemplate 代碼塊中的腳本。

def label = "jnlp-agent"
podTemplate(label: label,cloud: 'kubernetes' ){
    node (label) {
        print "在 Slave Pod 中執行任務"  
    }
}

podTemplate 方法參數簡介:

  • cloud: 之前 Kuberntes 插件配置的 Cloud 名稱
  • label: 之前 Kuberntes 插件配置的 Cloud 中 Pod Template 里面的 Label 標簽名稱。

腳本中使用 Docker 鏡像

在之前配置了 Kubernetes 插件的 Pod Template 配置中,配置了幾個容器,每個容器中都有特定的功能的環境,例如:

  • Maven 容器中能夠執行 mvn 命令。
  • Kubectl 容器能夠執行 kubectl 命令。
  • Docker In Docker 容器中能夠執行 Docker 命令。

既然每個容器都能提供特定的環境,那么再執行執行 Pipleline 腳本時候,就可以在不同的鏡像中使用不同的環境的命令:

Maven 鏡像

container('maven') {  
    sh "mvn install
}

Docker In Docker 鏡像

container('docker') {  
    sh "docker build -t xxxxx:1.0.0 .
}

Kubectl 鏡像

container('kubectl') {  
    sh "kubectl apply -f xxxx.yaml"
}

腳本中引入 Jenkins 中預先存儲的文件

在之前的 系統設置->File Manager 中,存儲了很多文件,例如:

  • Docker 的鏡像構建腳本文件 Dockerfile。
  • Maven 的全局設置文件 Settings.xml
  • Kubernetes 的部署文件 deployment.yaml

在使用 Pipleline 腳本時候,我們需要將這些文件文本提取出來,創建在執行任務的流程中,創建這些文件可以使用 Config File Provider 插件提供的 configFileProvider 方法,如下所示:

創建 settings.xml 文件

configFileProvider([configFile(fileId: "global-maven-settings", targetLocation: "settings.xml")]){
    sh "cat settings.xml"
}

創建 Dockerfile 文件

configFileProvider([configFile(fileId: "global-dockerfile-file", targetLocation: "Dockerfile")]){
    sh "cat Dockerfile"
}

創建 deployment.yaml 文件

configFileProvider([configFile(fileId: "global-kubernetes-deployment", targetLocation: "deployment.yaml")]){
    sh "cat deployment.yaml"
}

腳本創建文件

在使用 Groovy 寫 Pipleline 腳本時候,經常要將變量的文本生成文件,方便在執行流水線過程中操作文本文件使用,如何將文本轉換為文件,可以使用 Pipeline Utility Steps 插件的 writeFile 方法,如下:

writeFile encoding: 'UTF-8', file: './test.txt', text: "寫入文件的文本內容"

腳本中使用 Http Rrequest 插件

腳本中可以使用 HttpRequest 來對某一地址進行請求,這里簡單使用 Get 請求地址,復雜的可以查看 Jenkins 插件的官網查看使用示例。

下面是使用 Http Request 的 Get 請求示例:

result = httpRequest "http:www.baidu.com"

if ("${result.status}" == "200") {
    print "Http 請求成功"
} 

腳本中使用 Kubernetes Cli 插件

在之前說過,在 kubectl 鏡像中能夠使用 kubectl 命令,不過由於執行 Kubectl 命令一般需要在鏡像的 $HOME/.kube/ 目錄中存在連接 Kubernetes API 的 config 文件,使其 kubectl 命令有明確請求 kubernetes API 的地址和用戶權限,不過將 config 文件掛入鏡像內部是一件比較繁瑣的事情。

好在 Jenkins 提供的 Kubectl Cli 插件,只要在其中配置連接 Kubernetes 的 Token 憑據,就能夠在 Kubectl Cli 提供的 withKubeConfig 方法,擁有類似存在 config 一樣的功能,在 kubectl 鏡像中的 withKubeConfig 方法塊內執行 kubectl 就可以操作配置的 Kubectl Cli 的憑據的 K8S 集群。

container('kubectl') {
    withKubeConfig([credentialsId: "Kubernetes Token 憑據 ID",serverUrl: "https://kubernetes.default.svc.cluster.local"]) {
        sh "kubectl get nodes"
    }
}

腳本中操作字符串替換值

在使用 Groovy 語法寫 Pipleline 腳本時候,我們經常要替換先前設置好的一些文本的值,這里我們簡單示例一下,如何替換字符串。

// 測試的字符串
sourceStr = "這是要替換的值:#value1,這是要替換的值:#value2"
// 替換 #value1 與 #value2 兩個值
afterStr = deploy.replaceAll("#value1","AAA").replaceAll("#value2","BBB")
// 輸出替換后的字符串
print "${afterStr}"

腳本中讀取 pom.xml 參數

在執行 Java 項目的流水線時,我們經常要動態獲取項目中的屬性,很多屬性都配置在項目的 pom.xml 中,還好 Pipeline Utility Steps 插件提供能夠讀取 pom.xml 的方法,示例如下:

stage('讀取pom.xml參數階段'){
    // 讀取 Pom.xml 參數
    pom = readMavenPom file: './pom.xml'
    // 輸出讀取的參數
    print "${pom.artifactId}"
    print = "${pom.version}"
}

腳本中使用 Docker 插件構建與推送鏡像

在流水線腳本中,我們一般不直接使用 Docker 命令,而是使用 Docker 插件提供的 docker.withRegistry("") 方法來構建與推送鏡像,並且還能在方法中配置登錄憑據信息,來讓倉庫驗證權限,這點是非常方便的。使用示例如下:

docker.withRegistry("http://xxxx Docker 倉庫地址", "Docker 倉庫憑據 ID") {
        // 構建 Docker 鏡像
        def customImage = docker.build("${dockerImageName}")
        // 推送 Docker 鏡像
        customImage.push()
    }

七、在 Jenkins 創建模板任務

創建一個 Pipeline Job 來充當各個 Jenkins Job 的模板,方便后續創建 Job 時,直接復制模板項目,然后修改配置就能使用。所以這里我們創建一個模板 Pipeline Job,在 Job 配置中需要添加一些參數和環境變量,方便我們動態替換一些值。

創建 Pipeline 任務

配置項目構建基本參數

配置同一時間一個 Job 只能構建一個,不允許多個並發構建。另外需要設置項目構建后,包的保留時間,以防止包過多且大占用大量空間(一個包很可能占 10MB~200MB 大小)導致存儲空間不足。

配置 Git 變量

在 Job 配置的 參數化構建過程 中,添加下面參數:

Git 項目地址變量

變量名稱:GIT_PROJECT_URL
類型:String
描述:項目 Git 地址
默認值:"https://xxxxxxxxxxxx"

Git 分支變量

變量名稱:GIT_BRANCH
類型:Git Parameter
描述:選擇 Git 分支
默認值:master

Git 憑據變量

變量名稱:GIT_CREADENTIAL
類型:Credentials
描述:Git 憑據
默認值:global-git-credential

配置 Maven 變量

Maven 構建命令變量

變量名稱:MAVEN_BUILD_OPTION
類型:Choices
描述:要執行的 Maven 命令選擇
可選值:['package', 'install', 'deploy']
默認值:install

配置 Docker 變量

Docker 項目地址變量

變量名稱:DOCKER_HUB_URL
類型:String
描述:Docker 倉庫地址
默認值(默認 Docker 倉庫地址):"10.71.164.28:5000"

Docker 倉庫項目組變量

變量名稱:DOCKER_HUB_GROUP
類型:String
描述:Docker 倉庫項目組名
默認值:""

Docker 倉庫認證憑據變量

變量名稱:DOCKER_HUB_CREADENTIAL
類型:Credentials
描述:Docker 倉庫認證憑據
默認值:docker-hub-credential

Docker Dockerfile 文件 ID 變量

變量名稱:DOCKER_DOCKERFILE_ID
類型:String
描述:存於 Jenkins "Managed files" 的 Dockerfile 文件的 ID
默認值:"global-dockerfile-file"

配置 Kubernetes 變量

Kubernetes 認證憑據變量

變量名稱:KUBERNETES_CREADENTIAL
類型:Credentials
描述:Kubernetes 認證 Token
默認值:global-kubernetes-credential

Kubernetes Namespace 變量

變量名稱:KUBERNETES_NAMESPACE
類型:String
描述:Kubernetes 命名空間 Namespace
默認值:""

Kubernetes 應用實例副本數

變量名稱:KUBERNETES_APP_REPLICAS
類型:String
描述:應用實例副本數
默認值:1

Kubernetes 應用部署 yaml 文件ID

變量名稱:KUBERNETES_DEPLOYMENT_ID
類型:String
描述:存於 Jenkins "Managed files" 的 K8S 部署文件的 ID
默認值:"global-kubernetes-deployment"

配置 HTTP 變量

HTTP 健康檢查端口

變量名稱:HTTP_REQUEST_PORT
類型:String
描述:Http Request 端口(健康檢測端口)
默認值:8081

HTTP 健康檢查地址

變量名稱:HTTP_REQUEST_URL
類型:String
描述:Http Request 項目中的相對路徑(健康檢測路徑)
默認值:/actuator/health

HTTP 健康檢查次數

變量名稱:HTTP_REQUEST_NUMBER
類型:Choices
描述:Http Request 請求次數
可選值:['10', '5', '10', '15', '20', '25', '30']
默認值:10

HTTP 健康檢查時間間隔

變量名稱:HTTP_REQUEST_INTERVAL
類型:Choices
描述:Http Request 時間間隔
可選值:['10', '5', '15', '20', '25', '30']
默認值:10

八、Pipeline 腳本模板

腳本中包含多個階段,分別為 Git 拉取鏡像,Maven 編譯 Java 項目,Docker 構建與推送鏡像,Kubectl 部署應用到 Kubernetes 中,最后使用 Http 請求進行健康檢查。

def label = "jnlp-agent"
timeout(time: 900, unit: 'SECONDS') {
    podTemplate(label: label,cloud: 'kubernetes' ){
        node (label) {
            stage('Git階段'){
                // 執行 Git 命令進行 Clone 項目
                git changelog: true,
                    branch: "${params.GIT_BRANCH}",
                    credentialsId: "${params.GIT_CREADENTIAL}",
                    url: "${GIT_PROJECT_URL}"
            }
            stage('Maven階段'){
                container('maven') {  
                    // 創建 Maven 需要的 Settings.xml 文件
                    configFileProvider([configFile(fileId: "global-maven-settings", targetLocation: "settings.xml")]){
                        // 執行 Maven 命令構建項目,並且設置 Maven 配置為剛剛創建的 Settings.xml 文件
                        sh "mvn -T 1C clean ${MAVEN_BUILD_OPTION} -Dmaven.test.skip=true --settings settings.xml"
                    }
                }
            }
            stage('讀取pom.xml參數階段'){
                // 讀取 Pom.xml 參數
                pom = readMavenPom file: './pom.xml'
                // 設置 appName 和 appVersion 兩個全局參數
                appName = "${pom.artifactId}"
                appVersion = "${pom.version}"
            }
            stage('Docker階段'){
                container('docker') {
                    // 創建 Dockerfile 文件,但只能在方法塊內使用
                    configFileProvider([configFile(fileId: "${params.DOCKER_DOCKERFILE_ID}", targetLocation: "Dockerfile")]){
                        // 設置 Docker 鏡像名稱
                        dockerImageName = "${params.DOCKER_HUB_URL}/${params.DOCKER_HUB_GROUP}/${appName}:${appVersion}"
                        if ("${params.DOCKER_HUB_GROUP}" == '') {
                            dockerImageName = "${params.DOCKER_HUB_URL}/${appName}:${appVersion}"
                        }
                        // 提供 Docker 環境,使用 Docker 工具來進行 Docker 鏡像構建與推送
                        docker.withRegistry("http://${params.DOCKER_HUB_URL}", "${params.DOCKER_HUB_CREADENTIAL}") {
                            def customImage = docker.build("${dockerImageName}")
                            customImage.push()
                        }
                    }
                }
            }
            stage('Kubernetes 階段'){
                // kubectl 鏡像
                container('kubectl') {
                    // 使用 Kubectl Cli 插件的方法,提供 Kubernetes 環境,在其方法塊內部能夠執行 kubectl 命令
                    withKubeConfig([credentialsId: "${params.KUBERNETES_CREADENTIAL}",serverUrl: "https://kubernetes.default.svc.cluster.local"]) {
                        // 使用 configFile 插件,創建 Kubernetes 部署文件 deployment.yaml
                        configFileProvider([configFile(fileId: "${params.KUBERNETES_DEPLOYMENT_ID}", targetLocation: "deployment.yaml")]){
                            // 讀取 Kubernetes 部署文件
                            deploy = readFile encoding: "UTF-8", file: "deployment.yaml"
                            // 替換部署文件中的變量,並將替換后的文本賦予 deployfile 變量
                            deployfile = deploy.replaceAll("#APP_NAME","${appName}")
                                           .replaceAll("#APP_REPLICAS","${params.KUBERNETES_APP_REPLICAS}")
                                           .replaceAll("#APP_IMAGE_NAME","${dockerImageName}")
                                           .replaceAll("#APP_UUID",(new Random().nextInt(100000)).toString())
                            // 生成新的 Kubernetes 部署文件,內容為 deployfile 變量中的文本,文件名稱為 "deploy.yaml"
                            writeFile encoding: 'UTF-8', file: './deploy.yaml', text: "${deployfile}"
                            // 輸出新創建的部署 yaml 文件內容
                            sh "cat deploy.yaml"
                            // 執行 Kuberctl 命令進行部署操作
                            sh "kubectl apply -n ${params.KUBERNETES_NAMESPACE} -f deploy.yaml"
                        }
                    }
                }
            }
            stage('應用啟動檢查'){
                // 設置檢測延遲時間 10s,10s 后再開始檢測
                sleep 10
                // 健康檢查地址
                httpRequestUrl = "http://${appName}.${params.KUBERNETES_NAMESPACE}:${params.HTTP_REQUEST_PORT}${params.HTTP_REQUEST_URL}"
                // 循環使用 httpRequest 請求,檢測服務是否啟動
                for(n = 1; n <= "${params.HTTP_REQUEST_NUMBER}".toInteger(); n++){
                    try{
                        // 輸出請求信息和請求次數
                        print "訪問服務:${appName} \n" +
                              "訪問地址:${httpRequestUrl} \n" +
                              "訪問次數:${n}"
                        // 如果非第一次檢測,就睡眠一段時間,等待再次執行 httpRequest 請求
                        if(n > 1){
                            sleep "${params.HTTP_REQUEST_INTERVAL}".toInteger()
                        }
                        // 使用 HttpRequest 插件的 httpRequest 方法檢測對應地址
                        result = httpRequest "${httpRequestUrl}"
                        // 判斷是否返回 200
                        if ("${result.status}" == "200") {
                            print "Http 請求成功,流水線結束"
                            break
                        } 
                    }catch(Exception e){
                        print "監控檢測失敗,將在 ${params.HTTP_REQUEST_INTERVAL} 秒后將再次檢測。"
                        // 判斷檢測次數是否為最后一次檢測,如果是最后一次檢測,並且還失敗了,就對整個 Jenkins 任務標記為失敗
                        if (n == "${params.HTTP_REQUEST_NUMBER}".toInteger()) {
                            currentBuild.result = "FAILURE"
                        }
                    }
                }
            }
        }
    }
}

變量說明:

    GIT_BRANCH: Git 項目分支變量。
    GIT_PROJECT_URL: Git 項目 URL 變量。
    GIT_CREADENTIAL: Git 憑據 ID 變量。
    MAVEN_BUILD_OPTION: Maven 執行的構建命令,package、install 或 deploy。
    global-maven-settings: 全局 Maven 的 Settings.xml 文件的 ID 值,這里是使用 configFileProvider 插件來創建該文件。
    pom.artifactId: 從 pom.xml 文件中讀取的 artifactId 參數值。
    pom.version: 從 pom.xml 文件中讀取的 version 參數值。
    DOCKER_DOCKERFILE_ID: Dockerfile 文件的 ID。
    DOCKER_HUB_URL: Docker 倉庫 URL 地址。
    DOCKER_HUB_GROUP: Docker 倉庫項目組名。
    DOCKER_HUB_CREADENTIAL: Docker 倉庫認證憑據。
    appName: 從 pom.xml 中讀取的應用名稱。
    appVersion: 從 pom.xml 中讀取的應用版本號。
    KUBERNETES_DEPLOYMENT_ID: Kubernetes 部署文件的 ID。
    KUBERNETES_CREADENTIAL: Kubernetes API 認證憑據。
    KUBERNETES_NAMESPACE: Kubernetes 部署應用的 Namespace。
    KUBERNETES_APP_REPLICAS: Kubernetes 部署應用的副本數。
    dockerImageName: Docker 鏡像名稱。
    HTTP_REQUEST_PORT: HTTP 健康檢查端口。
    HTTP_REQUEST_URL: HTTP 健康檢查 URL 地址。
    HTTP_REQUEST_NUMBER: HTTP 健康檢查次數。
    HTTP_REQUEST_INTERVAL: HTTP 健康檢查間隔。

將該流水線代碼,配置到之前的模板 Job 的流水線腳本中,方便后續項目以此項目為模板。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM