1. 程式人生 > 其它 >jenkins在k8s中的CICD(第二版)

jenkins在k8s中的CICD(第二版)

  早在二年前,公司專案上線使用aws一系列產品時,記錄過一篇 《jenkins在aws eks中的CI/CD及slave》,這篇文章更多詳細的記錄了非常詳細的安裝和使用過程;今日,由於公司使用騰訊雲,且使用的也是雲k8s,本篇文章更多記錄CI/CD的一些升級的做法,簡單的外掛安裝等這裡就不做介紹。

  所以最大的變化是,k8s專案叢集的配置檔案變更為git管理,jenkinsfile做了小小的改動,其餘的變化不大。

1.檔案目錄

/k8s/config
└── h5-infra
    ├── environments
    │   ├── dev
    │   │   └── gcc-mh1
    │   │       ├── backend
    │   │       │   ├── jenkins
    │   │       │   │   └── gcc
-mh1-backend.groovy │ │ │ └── tke │ │ │ ├── default.conf │ │ │ ├── gcc-mh1-backend-configmap.yaml │ │ │ ├── gcc-mh1-backend-deployment.yaml │ │ │ ├── gcc-mh1-backend-ingress.yaml │ │ │ ├── gcc-mh1-backend-service.yaml │ │ │ └── kustomization.yaml │ │ └── frontend │ │ ├── jenkins │ │ │ └── gcc
-mh1-frontend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── gcc-mh1-frontend-deployment.yaml │ │ ├── gcc-mh1-frontend-ingress.yaml │ │ ├── gcc-mh1-frontend-service.yaml │ │ └── kustomization.yaml │ └── prod │ └── gcc
-mh1 │ ├── backend │ │ ├── jenkins │ │ │ └── gcc-mh1-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── gcc-mh1-backend-configmap.yaml │ │ ├── gcc-mh1-backend-deployment.yaml │ │ ├── gcc-mh1-backend-ingress.yaml │ │ ├── gcc-mh1-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── gcc-mh1-frontend.groovy │ └── tke │ ├── default.conf │ ├── gcc-mh1-frontend-deployment.yaml │ ├── gcc-mh1-frontend-ingress.yaml │ ├── gcc-mh1-frontend-service.yaml │ └── kustomization.yaml ├── scripts │ ├── create_project.sh │ ├── create_project_web.sh │ └── git_update.sh └── template ├── h5-web-template-dev │ ├── backend │ │ ├── jenkins │ │ │ └── h5-web-template-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── h5-web-template-backend-configmap.yaml │ │ ├── h5-web-template-backend-deployment.yaml │ │ ├── h5-web-template-backend-ingress.yaml │ │ ├── h5-web-template-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── h5-web-template-frontend.groovy │ └── tke │ ├── default.conf │ ├── h5-web-template-frontend-deployment.yaml │ ├── h5-web-template-frontend-ingress.yaml │ ├── h5-web-template-frontend-service.yaml │ └── kustomization.yaml ├── h5-web-template-prod │ ├── backend │ │ ├── jenkins │ │ │ └── h5-web-template-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── h5-web-template-backend-configmap.yaml │ │ ├── h5-web-template-backend-deployment.yaml │ │ ├── h5-web-template-backend-ingress.yaml │ │ ├── h5-web-template-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── h5-web-template-frontend.groovy │ └── tke │ ├── default.conf │ ├── h5-web-template-frontend-deployment.yaml │ ├── h5-web-template-frontend-ingress.yaml │ ├── h5-web-template-frontend-service.yaml │ └── kustomization.yaml ├── h5-web-template-web-dev │ └── frontend │ ├── jenkins │ │ └── h5-web-template-frontend.groovy │ └── tke │ ├── default.conf │ ├── h5-web-template-frontend-deployment.yaml │ ├── h5-web-template-frontend-ingress.yaml │ ├── h5-web-template-frontend-service.yaml │ └── kustomization.yaml └── h5-web-template-web-prod └── frontend ├── jenkins │ └── h5-web-template-frontend.groovy └── tke ├── default.conf ├── h5-web-template-frontend-deployment.yaml ├── h5-web-template-frontend-ingress.yaml ├── h5-web-template-frontend-service.yaml └── kustomization.yaml
檔案模版目錄樹

  可以看到,k8s檔案目錄主要分為environments、scritps、template,其中:

    • environments裡面存放的檔案為專案檔案的jenkinsfile以及k8s的deploy檔案。
    • scripts為k8s的deploy的生成指令碼,本篇文章不會講解。
    • template為生成environments裡的專案時的固定模板,裡面的字串都是固定的,為了指令碼操作時方便。

  最主要的當然是environments,另外三個資料夾也是輔助他的存在,專案的重要檔案全部在裡面。

2.environments講解

  這是整個流程中最重要的目錄,所以拿出來單獨講解。

    ├── environments
    │   ├── dev
    │   │   └── gcc-mh1
    │   │       ├── backend
    │   │       │   ├── jenkins
    │   │       │   │   └── gcc-mh1-backend.groovy
    │   │       │   └── tke
    │   │       │       ├── default.conf
    │   │       │       ├── gcc-mh1-backend-configmap.yaml
    │   │       │       ├── gcc-mh1-backend-deployment.yaml
    │   │       │       ├── gcc-mh1-backend-ingress.yaml
    │   │       │       ├── gcc-mh1-backend-service.yaml
    │   │       │       └── kustomization.yaml
    │   │       └── frontend
    │   │           ├── jenkins
    │   │           │   └── gcc-mh1-frontend.groovy
    │   │           └── tke
    │   │               ├── default.conf
    │   │               ├── gcc-mh1-frontend-deployment.yaml
    │   │               ├── gcc-mh1-frontend-ingress.yaml
    │   │               ├── gcc-mh1-frontend-service.yaml
    │   │               └── kustomization.yaml
    │   └── prod
    │       └── gcc-mh1
    │           ├── backend
    │           │   ├── jenkins
    │           │   │   └── gcc-mh1-backend.groovy
    │           │   └── tke
    │           │       ├── default.conf
    │           │       ├── gcc-mh1-backend-configmap.yaml
    │           │       ├── gcc-mh1-backend-deployment.yaml
    │           │       ├── gcc-mh1-backend-ingress.yaml
    │           │       ├── gcc-mh1-backend-service.yaml
    │           │       └── kustomization.yaml
    │           └── frontend
    │               ├── jenkins
    │               │   └── gcc-mh1-frontend.groovy
    │               └── tke
    │                   ├── default.conf
    │                   ├── gcc-mh1-frontend-deployment.yaml
    │                   ├── gcc-mh1-frontend-ingress.yaml
    │                   ├── gcc-mh1-frontend-service.yaml
    │                   └── kustomization.yaml
  
environments詳細目錄檔案

可以看出路徑為environments/dev/gcc-mh1/backend和frontend,最下面分為jenkins以及tke檔案。

  其中jenkins中是jenkinsfile檔案,tke則是k8s的相關檔案。

  後面通過指令碼的更改,將各檔案的內容替換掉。整個jenkins都可以圍繞整個資料夾為中心。

3.持續部署持續交付

  具體細節這裡就不做過多講解,可以參考本人2年前的部落格。

  1.建立一個”流水線專案”,首先進入引數化構建過程.

  釋出與回滾需要用到引數化構建過程中3個選項引數,一個執行時引數.(引數值最好不要用“-”,否則pipeline讀取變數時無法識別)

  分支引數

  Git使用這個的變數來判斷拉取哪個分支的程式碼.

  名稱空間

  用這個控制服務部署在k8s的哪個名稱空間下

  在之前的專案中,jenkins寫在了jenkins的pipeline裡,這樣不好管理,也比較繁瑣,這裡,直接將任何專案的jenkinsfile放在了git上

  2.流水線語法

  這裡改動不是很大,所以,這裡就不詳細解釋語法用法,最新版本的jenkinsfile甚至取消了回滾功能,但是本篇文章主要講解專案檔案的規範管理方式,如果有需要增加回滾等功能,在上面拓展即可。

  注意:這裡frontend以及backend的jenkinsfile也有稍微的改動,但是這裡就不做對比了,具體的檔案參考本人的專案檔案留檔。

[root@k8s-lizexiong jenkins]# cat gcc-mh1-frontend.groovy 
// 公共
def REGISTRY= "denadocker.tencentcloudcr.com"
def GIT_ADDRESS = "https://私有git/h5-development/gcc-mh1.git"
def GIT_INFRA_ADDRESS = "http://私有git/devops_web/h5-infra.git"
def PROJECT_NAME ="gcc"
def ACTIVITY_NAME = "mh1"
//def CDN_DIR= "${PROJECT_NAME}/(ACTIVITY_NAME.replaceAll('/','-'))"
def CDN_DIR= "${PROJECT_NAME}"+ "/" + "${ACTIVITY_NAME}".replaceAll('-','/')
def POJECT_TYPE = "frontend"


// 專案
def REGISTRY_NAMESPACE = "h5-web"
def BRANCH_STR= (branch.replaceAll('/','-'))
def IMAGE_NAME= "${REGISTRY}/${REGISTRY_NAMESPACE}/${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}:${BRANCH_STR}-${BUILD_NUMBER}"
def SERVICE_DIR = "h5"
def INFRA_DIR = "h5-infra"
// 認證
def TCR_AUTH = "973589fa-7ae2-4a08-9002-b139ea04c61c"
def GIT_AUTH = "93766ad8-ffee-42f4-ac01-afa590157c3b"
def K8S_AUTH = "h5web-k8s-test"

//def ENVIRONMENT=""
//def branch=""
node() {
    stage('checkout service code') {
        checkout([$class: 'GitSCM', branches: [[name: "${branch}"]], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: "${SERVICE_DIR}"],[$class: 'CleanBeforeCheckout']], userRemoteConfigs: [[credentialsId: "${GIT_AUTH}", url: "${GIT_ADDRESS}"]]])
    }
    stage('compile code') {
        withDockerContainer(image: "node:14") {
            sh """
            echo ${CDN_DIR}
            cd ${SERVICE_DIR}/frontend
            npm install && npm run build
            """
        }
    }
    stage('build and push image') {
        withCredentials([usernamePassword(credentialsId: "${TCR_AUTH}", passwordVariable: 'TCR_PASSWORD', usernameVariable: 'TCR_USERNAME')]) {
            sh """
                # login to TCR
                echo "Login to TCR"
                echo ${TCR_PASSWORD} | docker login --password-stdin -u ${TCR_USERNAME} https://${REGISTRY}
                echo "docker build & push"
                cd ${SERVICE_DIR}/frontend
                echo '
                FROM denadocker.tencentcloudcr.com/h5-web/nginx:1.19.10-logformat-v1
                ADD ./dist/*.html  /usr/share/nginx/html/
                EXPOSE 80
                ' > Dockerfile
                echo "docker build & push"
                docker build  -f ./Dockerfile  -t ${IMAGE_NAME} .
                docker push ${IMAGE_NAME} 
            """
        }
    }
    stage('upload resources to the CDN'){
        sh "ossutil64 cp -rf ${SERVICE_DIR}/frontend/dist/static/ oss://cn-op-web/cdn/h5/${CDN_DIR}/static/"
        //sh "ossutil64 cp -rf ${SERVICE_DIR}/frontend/dist/static/ oss://cn-op-web/cdn/h5/${PROJECT_NAME}/${ACTIVITY_NAME}/static/"
    }

    stage('checkout infra code') {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: "${INFRA_DIR}"],[$class: 'CleanBeforeCheckout']], userRemoteConfigs: [[credentialsId: "${GIT_AUTH}", url: "${GIT_INFRA_ADDRESS}"]]])
    }

    stage('deploy'){
        sh """
            echo deploy service
            cd ./${INFRA_DIR}/environments/${ENVIRONMENT}/${PROJECT_NAME}-${ACTIVITY_NAME}/${POJECT_TYPE}/tke
            sed -i 's#\$IMAGE_NAME#${IMAGE_NAME}#' ${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}-deployment.yaml
            cd -
            kustomize build --load_restrictor none ./${INFRA_DIR}/environments/${ENVIRONMENT}/${PROJECT_NAME}-${ACTIVITY_NAME}/${POJECT_TYPE}/tke >${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}.yaml
          """
        kubernetesDeploy configs: "${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}.yaml", kubeconfigId: "${K8S_AUTH}"
    }
}

可以看出2年前版本的jenkinsfile比較明顯的改變就是npm編譯直接使用docker容器,而不是本地安裝,在最後CD的過程錢使用了kustomize來校對管理k8s的配置檔案。

4.總結

  整篇文件沒有兩年前的安裝和解釋那麼詳細,但是給人了一種檔案規範管理的思路,這樣,即使跳板機更改和一些其它情況,配置檔案都能規範同步,規範管理。

  如果對安裝以及版本流程不太清楚的,可以參考本人兩年前的jenkins部落格:https://www.cnblogs.com/lizexiong/p/14863602.html

作者:小家電維修

相見有時,後會無期。