• 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

    作者:小家电维修

    相见有时,后会无期。

  • 相关阅读:
    DPDK ring简单说明
    DPDK初始化流程
    从《雪白血红》说起(2)
    从《雪白血红》说起(1)
    苏联印象(1)-过往与想象
    DPDK ip分片与重组的设计实现
    linux协议栈分析-序
    DPDK与QoS(服务质量)
    DPDK LPM路由存储与查找
    《教父》曾说
  • 原文地址:https://www.cnblogs.com/lizexiong/p/15576519.html
Copyright © 2020-2023  润新知