jenkins流水線部署springboot應用到k8s叢集(k3s+jenkins+gitee+maven+docker)(2)

2022-09-14 12:02:12

前言:上篇已介紹了jenkins在k3s環境部署,本篇繼續上篇講述流水線構建部署流程

1、從gitlab上拉取程式碼步驟

  • 在jenkins中,新建一個憑證;Manage Jenkins -> Manage Credentials

  • 點選jenkins -> 全域性憑據 -> 新增憑據;選擇使用者名稱和密碼型別,輸入使用者名稱和密碼,點選建立

  • 編寫pipeline script指令碼,拉取程式碼

  • 選擇git程式碼倉庫還有憑證等資訊,點選「生成流水線指令碼」,即幫我們生成了拉取程式碼的指令碼

  • 複製指令碼,貼上到流水線拷貝程式碼段中

  • 執行構建專案,發現拉取程式碼成功,且已返回程式碼最後提交的tag

    程式碼塊:

      stage('Clone') {
          echo "1.Clone Stage"
          git url: "https://gitee.com/xujk-27400861/springboot-dubbo.git"
          script {
              build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
          }
          echo "${build_tag}"
        }
    

2、maven構建springboot程式碼專案

  • 編寫指令碼,因為我們要編譯構建專案的子專案,所以需要跳轉到子目錄去構建
      stage('執行構建') {
            container('maven')
            {
                sh "mvn --version"
                sh 'pwd'
                sh '''cd provider/ 
                mvn clean package -DskipTests'''
                //sh 'mvn package'
                echo '構建完成'
            }
       }
    
  • provider/為專案子目錄,我們要編譯的專案;-DskipTests引數,表示跳過程式碼測試

3、構建docker映象

  • 編寫指令碼,構建docker映象;
      stage('Build') {
          echo "3.Build Stage"
          container('docker') {
              sh "docker -v"
              sh 'pwd'
              sh """cd /home/jenkins/agent/workspace/linetest/provider/ 
              ls
              docker -H tcp://192.168.231.132:2375 build -t xjk27400861/springbootapp:${build_tag} ."""        
        }
      }
    
  • 我這裡通過呼叫單機節點獨立的docker進行映象打包,jenkins內部新構建的docker無法打包,因許可權問題

4、推播docker映象到docker hub上,以備後續部署應用時使用

  • 編寫指令碼,推播docker映象;
      stage('Push') {
      echo "4.Push Docker Image Stage"
      container('docker') {
          sh "docker -H tcp://192.168.231.132:2375 login --username=xjk27400861 -p xujingkun@123"
          sh "docker -H tcp://192.168.231.132:2375 push xjk27400861/springbootapp:${build_tag}"
         }
      }
    
  • docker login登入到docker hub上,然後使用docker push命令推播;- H 使用其他節點的docker
  • Ubuntu開啟Docker遠端存取

    輸入命令:

       sudo gedit /lib/systemd/system/docker.service
    

    找到ExecStart段,修改為

      ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock -H fd:// --containerd=/run/containerd/containerd.sock
    

    儲存並退出編輯後,過載守護行程以及重啟Docker

      sudo systemctl daemon-reload
      sudo service docker restart
    

    可通過執行命令檢視是否開放了遠端存取埠

      sudo systemctl status docker.service
    

5、拉取docker映象,部署到k8s環境中

  • 編寫指令碼,部署應用
      stage('Deploy') {
      echo "5. Deploy Stage"
      container('kubectl') {
        sh "kubectl version"
        def namespace="jenkinsdemo"//springboot2node
      sh """cd /home/jenkins/agent/workspace/linetest/provider/ 
            ls
            sed -i 's/<BUILD_TAG>/${build_tag}/' k8s.yaml
            sed -i 's/<BUILD_NAMESPACE>/${namespace}/' k8s.yaml
            kubectl delete -f .
            kubectl apply -f k8s.yaml --record
            """
      }
    }
    
  • 部署成功後,通過k8s主機節點+埠,存取應用

6、完整pipeline指令碼

def label = "jnlp"
podTemplate (label: label,cloud: 'kubernetes',containers: [
//image: 'datorresf/jenkins-agent-mvn',
//image: 'maven:latest', 
containerTemplate(
    name: 'maven', 
    image: 'maven:3.8.1-ibmjava-8', 
    alwaysPullImage: false, 
    ttyEnabled: true,
    command:'cat'
    ),//docker:19.03.8
    containerTemplate( 
        name: 'docker',
        image: "docker:stable",
        ttyEnabled: true,
        command: 'cat',
    ),
    containerTemplate(name: 'kubectl', image: 'bibinwilson/docker-kubectl:latest', command: 'cat', ttyEnabled: true)
],serviceAccount: 'jenkinsbuild',//jenkinsbuild
volumes: [
    hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
    hostPathVolume(mountPath: '/root/.m2', hostPath: '/root/.m2'),
    hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'),
    hostPathVolume(mountPath: '/etc/kubernetes/pki', hostPath: '/etc/kubernetes/pki'),
])
{    
node('jnlp') {
  stage('Clone') {
    echo "1.Clone Stage"
    git credentialsId: '56cc9ad2-aafa-41f3-bc6b-2d7d66c52f32', url: "https://gitee.com/xujk-27400861/springboot-dubbo.git"
    script {
      build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
    }
   echo "${build_tag}"
  }
  stage('Test') {
    echo "2.Test Stage"
  }
  stage('執行構建') {
  container('maven')
  {
      sh "mvn --version"
      sh 'pwd'
      sh '''cd provider/ 
            mvn clean package -DskipTests'''
      //sh 'mvn package'
      echo '構建完成'
  }
 }
 stage('Build') {
  echo "3.Build Stage"
  container('docker') {
      sh "docker -v"
      sh 'pwd'
      sh """cd /home/jenkins/agent/workspace/linetest/provider/ 
      ls
      docker -H tcp://192.168.231.132:2375 build -t xjk27400861/springbootapp:${build_tag} ."""
    }
  }
  stage('Push') {
  echo "4.Push Docker Image Stage"
  container('docker') {
      sh "docker -H tcp://192.168.231.132:2375 login --username=xjk27400861 -p xujingkun@123"
      sh "docker -H tcp://192.168.231.132:2375 push xjk27400861/springbootapp:${build_tag}"
     }
  }
  stage('Deploy') {
    echo "5. Deploy Stage"
    container('kubectl') {
        sh "kubectl version"
        def namespace="jenkinsdemo"//springboot2node
        sh """cd /home/jenkins/agent/workspace/linetest/provider/ 
        ls
        sed -i 's/<BUILD_TAG>/${build_tag}/' k8s.yaml
        sed -i 's/<BUILD_NAMESPACE>/${namespace}/' k8s.yaml
        kubectl delete -f .
        kubectl apply -f k8s.yaml --record
        """
      }
   }
 }
}

7、完整pipeline指令碼說明

  • 建立一個pod,裡面包含構建有三個docker容器,maven,docker與kubectl,分別進行程式碼maven構建,docker打包映象,kubectl部署應用到k8s環境
  • 程式碼段:serviceAccount: 'jenkinsbuild';指定操作k8s環境的賬戶;這個是rancher2.6.3部署jenkins的時候,自動建立的賬戶(service account)

  • 程式碼段:docker -H tcp://192.168.231.132:2375;操控單節點docker進行映象打包及推播操作
  • 部署應用的時候,可能會提示使用者jenkinsbuild沒有構建pod或者services的許可權,可以通過rancher的rbac編輯使用者許可權(Roles&RoleBindings)

    Roles設定

    編輯設定

    RoleBindings無需修改,後面如果有需要其他使用者操作k8s的話,可以通過建立Role與RoleBindings,賦予其他賬戶對應的許可權來操作k8s環境

  • jenkins的k8s連通環境設定

    Manage Jenkins -> Manage nodes and clouds 依次點選,進入設定頁面

    點選:Configure Clouds;名稱預設:kubernetes,我們的指令碼裡用cloud屬性指定的k8s叢集

    由於我使用的是rancher通過應用市場安裝的,此處的kubernetes設定的都是預設值,無需修改

  • 設定連線叢集外的k8s叢集方法

    修改k8s叢集的地址(https://192.168.231.133:6443

    連線k8s叢集的認證方式,我這裡設定了3種,使用者名稱密碼&祕鑰文字&kube.config檔案

    使用者名稱密碼方式,就直接輸入我們k8s叢集的存取使用者名稱和密碼,在jenkins建立全域性憑證,設定時選中即可

    祕鑰文字方式,我們通過rancher,下載k8s的組態檔

    開啟組態檔,把下圖圈起來的資料,在jenkins建立憑據,secret text型別

    使用k8s的組態檔,建立secret file型別的憑證,上傳我們的組態檔,測試;由於檔案裡設定的是k8s叢集的存取域名,所以提示失敗,如果域名可通的話,也是可以的

  • 流水線指令碼設定maven映象檔案的時候,要注意與你springboot專案中使用的版本保持一致,否則會出現編譯構建錯誤

  • 關於serviceAccount: 'jenkinsbuild',這段,需要設定存取k8s叢集的使用者名稱,同時需要設定role與rolebindings賦予使用者應有的許可權,否則會提示許可權錯誤
  • 本文使用的程式碼見倉庫,含有k8s部署檔案,https://gitee.com/xujk-27400861/springboot-dubbo/tree/master/provider
  • 同時,也可以通過jenkinsfile構建,在專案中相應目錄建立jenkinsfile,裡面參考流水線指令碼,也是可以實現構建釋出的,此處不詳述

好的,本篇到此為止