Jenkins-Pipeline Vue自动化打包部署到 k8s

一、 发布流程分析

  1. 拉取代码
  2. NPM编译打包
  3. 代码质量检查 
  4. 容器镜像封装
  5. 推送镜像到镜像仓库
  6. 发布到k8s集群平台

二、 Jenkins 配置如下:

三、 Pipeline1 脚本如下 

pipeline {
    agent { 
        label 'master' 
    }
    
    // 构建参数
    parameters {
        gitParameter(branchFilter: 'origin.*/(.*)', name: 'BRANCH_TAG', defaultValue: 'develop',selectedValue: 'DEFAULT', type: 'PT_BRANCH_TAG', listSize: '15', quickFilterEnabled: true, requiredParameter: true)
        choice(name: '请选择操作', choices: [ "拉取代码-编译",'-----' ,"拉取代码-编译-单元测试", '-----',"重启服务",'-----' ,"停止服务",'-----',"扩容服务",'-----',"回滚服务"])
        // string(name: 'version_id', defaultValue: '1', description: '构建生产历史版本号,1表示回滚到上一个版本,2表示回滚上两个版本')
        string(name: 'pod_num', defaultValue: '2', description: '默认pod数据数量2,输入扩容副本数量')
    }

    environment {
        // 项目名称 
        PROJECT_NAME= "cnh"
        // 指定代码所在GitLab仓库地址
        GITLAB_URL = "ssh://git@gitlab.iotcloud.wl:2222/xxx.git"
        // 指定GitLab仓库的分支
        GITLAB_BRANCH = "develop"
        // GitLab拉取代码的用户认证文件ID
        GITLAB_SERCET = "11d180dd-1afc-4e40-952a-d0d9db29ffde"
        // docker镜像仓库地址
        DOCKER_REGISTRY_URL = "172.16.4.39:5000" 
        DOCKER_LOCAL_REGISTRY_URL = "172.16.4.39:8090"
        DOCKER_REGISTRY_LOGIN_USER = "docker"
        DOCKER_REGISTRY_LOGIN_PASSWORD= "123456"
        DOCKER_BASE_IMAGE = "${DOCKER_LOCAL_REGISTRY_URL}/nginx:time"
        NPM_REGISTRY_URL = "http://172.16.4.39:8081/repository/npm-group/"
        // NPM_REGISTRY_URL = "https://registry.npmmirror.com"

        // 把构建docker镜像的名称
        DOCKER_IMAGE_NAME = "${DOCKER_REGISTRY_URL}/${PROJECT_NAME}/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}"
        DOCKER_DEPLOY_IMAGE_NAME = "${DOCKER_LOCAL_REGISTRY_URL}/${PROJECT_NAME}/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}"
        // // 指定Dockerfile文件所在路径
        DOCKER_BUILD_FILE = "Dockerfile"
        // // 指定构建Docker容器时所在路径
        DOCKER_BUILD_PATH = "."
        // K8S命令的路径
        K8S_COMMAND_PATH = "${JENKINS_HOME}/tools/kubectl"
        // NPM_COMMAND = "${JENKINS_HOME}/node-v14.15.0-linux-x64/bin/npm"
        // MVN_COMMAND = "/var/jenkins_home/maven"
        // 配置K8S执行命令的环境
        K8S_CONFIG_SERCET = "k8s-jenkins-test"
        // 配置K8S服务开放容器的端口
        K8S_PORT = "80"
        // K8s 名称空间 
        K8S_NAMESPACE_NAME = "cnh"
        // 创建服务的复本数量
        K8S_POD_NUM = 2
        // RELEASE 发布标签
        // K8S_RELEASE = 'dev'
        // SonarQube Scanner
        scannerHome = "${JENKINS_HOME}/tools/sonar-scanner-4.3.0.2102"

    }
        
    // pipeline选项
    options {
        // 保存最近历史构建记录数量
        buildDiscarder(logRotator(numToKeepStr: '10'))
        // 禁止pipeline同时执行
        disableConcurrentBuilds()
        // 失败时重试总次数
        // retry(2)
        // pipeline执行时间过长,超过timeout时间就停止掉pipeline
        timeout(time: 30, unit: 'MINUTES') 
    }
    tools {
        nodejs "nodejs20"
    }
   stages {

        stage("清理工作空间") {
            steps {
                deleteDir() // 清理工作空间
            }
        }
        
        stage('GitLab代码拉取') {
            steps {
                script {
                // git branch: env.GITLAB_BRANCH, credentialsId: env.GITLAB_SERCET, url: env.GITLAB_URL
                checkout([$class: 'GitSCM', 
                    branches: [[name: "${params.BRANCH_TAG}"]], 
                    doGenerateSubmoduleConfigurations: false, 
                    extensions: [], submoduleCfg: [], 
                    userRemoteConfigs: [[credentialsId: env.GITLAB_SERCET, url: env.GITLAB_URL]]])  
                }

            }
        }

        stage('NPM代码编译打包') { 


          steps {

            sh '''
            rm -rf ../dist
            rm -rf ../node_modules
            pnpm config set registry ${NPM_REGISTRY_URL} 
            pnpm install  --no-frozen-lockfile
            pnpm install chalk
            pnpm run build

            '''
          }
        }

        stage('代码检查') {


            steps {
                echo "启动sonar代码分析......"
                withSonarQubeEnv('sonar7.9') {
                    //注意这里withSonarQubeEnv()中的参数要与之前SonarQube servers中Name的配置相同

                    // nodejs
                    sh """
                        ${scannerHome}/bin/sonar-scanner \
                        -Dsonar.projectKey=${JOB_BASE_NAME} \
                        -Dsonar.projectName=${JOB_BASE_NAME} \
                        -Dsonar.sources=. \
                        -Dsonar.sources=src \
                        -Dsonar.exclusions=node_modules/** \
                        -Dsonar.js.file.suffixes=.js,.jsx,.ts,.tsx 

                    """

                    // sh """
                    //   cd cnh-iconnect-system/${JOB_BASE_NAME}
                    //   ${scannerHome}/bin/sonar-scanner \
                    //         -Dsonar.projectKey=${JOB_BASE_NAME} \
                    //         -Dsonar.projectName=${JOB_BASE_NAME} \
                    //         -Dsonar.projectBaseDir=./ \
                    //         -Dproject.settings=../../sonar-project.properties
                                                        
                    // """
                    // sh """
                    //     cd ${JOB_BASE_NAME}
                    //     mvn clean verify sonar:sonar 
                    // """    
                    // sh """
                    //     cd ${JOB_BASE_NAME}
                    //     mvn clean verify sonar:sonar \
                    //     -Dsonar.core.codeCoveragePlugin=jacoco \
                    //     -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco-merged-test-coverage-report/jacoco.xml
                    // """
                    //指定了maven插件,如果不指定使用最新的
                    //   sh 'cd ${JOB_BASE_NAME}'
                    //   sh "mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar "
                    // sh """
                    //   cd cnh-api-gateway/${JOB_BASE_NAME}
                    //   ${scannerHome}/bin/sonar-scanner \
                    //         -Dsonar.projectKey=${JOB_BASE_NAME} \
                    //         -Dsonar.projectName=${JOB_BASE_NAME} \
                    //         -Dsonar.sources=. \
                    //         -Dsonar.sources=src \
                    //         -Dsonar.exclusions=**/bean/**,**/vo/**,**/dto/**,**/po/**,**/test/**,**/**/*Test \
                    //         -Dsonar.java.binaries=./target/classes \
                    //         -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml \
                    //         -Dsonar.issue.ignore.multicriteria.e1.ruleKey=java:S482 \
                    //         -Dsonar.issue.ignore.multicriteria.e1.resourceKey=**/** \
                    //         -Dsonar.issue.ignore.multicriteria.e2.ruleKey=java:S1214 \
                    //         -Dsonar.issue.ignore.multicriteria.e2.resourceKey=**/** \
                    //         -Dsonar.issue.ignore.multicriteria.e3.ruleKey=java:S125 \
                    //         -Dsonar.issue.ignore.multicriteria.e3.resourceKey=**/** \
                    //         -Dsonar.issue.ignore.multicriteria.e4.ruleKey=java:S1488 \
                    //         -Dsonar.issue.ignore.multicriteria.e4.resourceKey=**/** 
                            
                    // """
                        
                }    
            }
        }


        stage('Docker镜像构建') {
             steps {
                 sh """
                 echo "FROM ${DOCKER_BASE_IMAGE}" >Dockerfile
                 echo "COPY dist /usr/share/nginx/html" >>Dockerfile
                 """

                 sh """
                  docker buildx build -t ${DOCKER_IMAGE_NAME}  --file=${DOCKER_BUILD_FILE} ${DOCKER_BUILD_PATH}
                """
             }
         }


        stage('推送Docker镜像到镜像仓库') {
            
             steps {
                 sh """
                 docker login -u${DOCKER_REGISTRY_LOGIN_USER} -p${DOCKER_REGISTRY_LOGIN_PASSWORD} ${DOCKER_REGISTRY_URL} 
                 docker push ${DOCKER_IMAGE_NAME}
                 docker rmi ${DOCKER_IMAGE_NAME}
                 """
             }
         }


        stage('微服务部署到K8S') {
            steps {
                script {
                    withKubeConfig([credentialsId: env.K8S_CONFIG_SERCET, serverUrl: '']) {
                        def RETURN_VALUME = sh(script: '${K8S_COMMAND_PATH} --namespace ${K8S_NAMESPACE_NAME} get deployments -l app=${JOB_BASE_NAME} --ignore-not-found=true --no-headers', returnStdout: true).trim()
                        env.RETURN_VALUME = "$RETURN_VALUME"
                        if (env.RETURN_VALUME == ''){
                            sh '${JENKINS_HOME}/yaml/k8s_build  ${JENKINS_HOME}/yaml/deployment_template-cms.yaml ${JOB_BASE_NAME} --namespace ${K8S_NAMESPACE_NAME} --replicas=${K8S_POD_NUM}  --image-name ${PROJECT_NAME}/${JOB_BASE_NAME}:${BUILD_TIMESTAMP} --docker-registry ${DOCKER_LOCAL_REGISTRY_URL} --limit_memory 2Gi'
                            sh '${K8S_COMMAND_PATH} apply -f ${JOB_BASE_NAME}-dep.yaml'
                            // HPA
                            //sh '${JENKINS_HOME}/yaml/k8s_build  ${JENKINS_HOME}/yaml/template_autoscale.yaml ${JOB_BASE_NAME} --type hpa  --memory_scale 80 --min_replica 1 --max_replica 3'
                            //sh '${K8S_COMMAND_PATH} apply -f ${JOB_BASE_NAME}-hpa.yaml'
                            
                            // sh '''
                            //     ${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} run ${JOB_BASE_NAME}-${VERSION_NUM} --image=${DOCKER_IMAGE_NAME} --replicas=${K8S_POD_NUM} --labels="app=${JOB_BASE_NAME},version=${VERSION_NUM}" --overrides='{"spec": {"minReadySeconds": 120, "strategy": {"type": "RollingUpdate", "rollingUpdate": {"maxSurge": 1, "maxUnavailable": 0}}}}'
                            // '''
                        } else {
                          sh '${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} set image deployment ${JOB_BASE_NAME} ${JOB_BASE_NAME}=${DOCKER_DEPLOY_IMAGE_NAME}'
                          sh '${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} scale --replicas=${K8S_POD_NUM} deployment ${JOB_BASE_NAME}'
                        }
                        
                        def SVC_STATUS = sh(script: '${K8S_COMMAND_PATH} --namespace ${K8S_NAMESPACE_NAME} get service ${JOB_BASE_NAME} --ignore-not-found=true --no-headers', returnStdout: true).trim()
                        env.SVC_STATUS = "$SVC_STATUS"
                        if (env.SVC_STATUS == ''){
                            sh '${JENKINS_HOME}/yaml/k8s_build  ${JENKINS_HOME}/yaml/service_template.yaml ${JOB_BASE_NAME} --namespace ${K8S_NAMESPACE_NAME}  --type=service --port=${K8S_PORT} '
                            sh '${K8S_COMMAND_PATH} apply -f ${JOB_BASE_NAME}-svc.yaml'
                        //    sh '${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} create service clusterip ${JOB_BASE_NAME} --tcp=${K8S_PORT1}:${K8S_PORT1} --tcp=${K8S_PORT2}:${K8S_PORT2}'
                        }
                    }
                }
            }
        }

    }
}

 Pipeline 2

pipeline {
    agent { 
        label 'master' 
    }

    // 构建参数
    parameters {
        gitParameter(branchFilter: 'origin.*/(.*)', name: 'BRANCH_TAG', defaultValue: 'master',selectedValue: 'DEFAULT', type: 'PT_BRANCH_TAG', listSize: '15', quickFilterEnabled: true, requiredParameter: true)
        choice(name: '请选择操作', choices: [ "拉取代码-编译",'-----' ,"拉取代码-编译-单元测试", '-----',"重启服务",'-----' ,"停止服务",'-----',"扩容服务",'-----',"回滚服务"])
        // string(name: 'version_id', defaultValue: '1', description: '构建生产历史版本号,1表示回滚到上一个版本,2表示回滚上两个版本')
        string(name: 'pod_num', defaultValue: '2', description: '默认pod数据数量2,输入扩容副本数量')
    }
 
    environment {

        // 参数选项
        ACTION = "${params.请选择操作}"

        // 项目名称 
        PROJECT_NAME= "cnh"
        // 指定代码所在GitLab仓库地址
        GITLAB_URL = "https://gitlab.xxx.com:19090/xxx.git"

        // 指定GitLab仓库的分支
        GITLAB_BRANCH = "master"
        
        // GitLab拉取代码的用户认证文件ID
        // GITLAB_SERCET = "11d180dd-1afc-4e40-952a-d0d9db29ffde"
        GITLAB_SERCET = "f07ce25c-490b-475f-adce-1dd19d13149f"
        // docker镜像仓库地址
        // DOCKER_REGISTRY_URL = "172.16.0.100:5000" 
        // DOCKER_LOCAL_REGISTRY_URL = "172.16.0.100:8090"
        // DOCKER_REGISTRY_LOGIN_USER = "docker"
        // DOCKER_REGISTRY_LOGIN_PASSWORD= "CNH@Docker2025"
        DOCKER_REGISTRY_URL = "registry.iotcloud.wl" 
        DOCKER_LOCAL_REGISTRY_URL = "registry.iotcloud.wl"
        DOCKER_REGISTRY_LOGIN_USER = "docker"
        DOCKER_REGISTRY_LOGIN_PASSWORD= "CNH@Docker2025"
        DOCKER_BASE_IMAGE = "${DOCKER_LOCAL_REGISTRY_URL}/cnmirrors/nginx:time"
        NPM_REGISTRY_URL = "http://172.16.0.100:8081/repository/npm-group/"
        // 把构建docker镜像的名称
        // DOCKER_IMAGE_NAME = "${DOCKER_REGISTRY_URL}/${PROJECT_NAME}/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}"
        // DOCKER_DEPLOY_IMAGE_NAME = "${DOCKER_LOCAL_REGISTRY_URL}/${PROJECT_NAME}/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}"
        // // 指定Dockerfile文件所在路径
        DOCKER_BUILD_FILE = "Dockerfile"
        // // 指定构建Docker容器时所在路径
        DOCKER_BUILD_PATH = "."
        // K8S命令的路径
        K8S_COMMAND_PATH = "${JENKINS_HOME}/tools/kubectl"
        // NPM_COMMAND = "${JENKINS_HOME}/node-v14.15.0-linux-x64/bin/npm"
        // MVN_COMMAND = "/var/jenkins_home/maven"
        // 配置K8S执行命令的环境
        K8S_CONFIG_SERCET = "k8s-jenkins-prod"
        // 配置K8S服务开放容器的端口
        K8S_PORT = "80"
        // K8s 名称空间 
        K8S_NAMESPACE_NAME = "cnh"
        // 创建服务的复本数量
        K8S_POD_NUM = 2
        // 显示选择镜像版本号的数量
        DOCKER_NUM = 10
        // SonarQube Scanner
        scannerHome = "${JENKINS_HOME}/tools/sonar-scanner-4.3.0.2102"
      
    }
        
    // pipeline选项
    options {
        // 保存最近历史构建记录数量
        buildDiscarder(logRotator(numToKeepStr: '10'))
        // 禁止pipeline同时执行
        disableConcurrentBuilds()
        // 失败时重试总次数
        // retry(2)
        // pipeline执行时间过长,超过timeout时间就停止掉pipeline
        timeout(time: 30, unit: 'MINUTES') 
    }
    tools {
        nodejs "nodejs20"
    }
   stages {

        stage("清理工作空间") {
            steps {
                deleteDir() // 清理工作空间
            }
        }
        
         stage('GitLab代码拉取') {
            
            
            steps {
                script {
                // git branch: env.GITLAB_BRANCH, credentialsId: env.GITLAB_SERCET, url: env.GITLAB_URL
                checkout([$class: 'GitSCM', 
                    branches: [[name: "${params.BRANCH_TAG}"]], 
                    doGenerateSubmoduleConfigurations: false, 
                    extensions: [], submoduleCfg: [], 
                    userRemoteConfigs: [[credentialsId: env.GITLAB_SERCET, url: env.GITLAB_URL]]])  

                    // 获取最新的标签
                    // def VERSION = sh(script: 'git rev-parse --abbrev-ref HEAD', returnStdout: true).trim()"
                    // def VERSION = sh(script: 'git tag | sort -V | tail -n 1', returnStdout: true).trim()
                    // 获取当前分支的最近一次提交的哈希值
                    def commitHash = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
                    // // 获取当前分支的名称
                    // // def branchName = sh(script: 'git rev-parse --abbrev-ref HEAD', returnStdout: true).trim()
                    def branchName = "${params.BRANCH_TAG}"
                    echo "${params.BRANCH_TAG}"
      
                    // 将这些值设置为环境变量,以便在后续步骤中使用
                    env.COMMIT_HASH = commitHash
                    env.BRANCH_NAME = branchName
                    env.VERSION = "${COMMIT_HASH}"
                    // 根据分支名称设置不同的标签版本
                    def TAG_VERSION
                    if (branchName == 'master') {
                        TAG_VERSION = "stable-${VERSION}"
                    } else if (branchName ==~ /feature.+/) {
                        TAG_VERSION = "feature-${VERSION}"
                    } else if (branchName ==~ /hotfix.+/) {
                        TAG_VERSION = "hotfix-${VERSION}"
                    } else if (branchName ==~ /release.+/) {
                        TAG_VERSION = "release-${VERSION}"
                    } else {
                        TAG_VERSION = "custom-${VERSION}"
                    }
                    env.TAG_VERSION = TAG_VERSION

                    // 构建完整的版本号
                    def BUILD_NUMBER = env.BUILD_NUMBER
                    def BUILD_TIMESTAMP = sh(script: 'date "+%Y%m%d%H%M"', returnStdout: true).trim()
                    def FULL_VERSION = "${TAG_VERSION}-${BUILD_NUMBER}-${BUILD_TIMESTAMP}"

                    // 设置 Docker 镜像名称
                    DOCKER_IMAGE_NAME = "${DOCKER_REGISTRY_URL}/${PROJECT_NAME}/${JOB_BASE_NAME}:${FULL_VERSION}"
                    DOCKER_DEPLOY_IMAGE_NAME = "${DOCKER_LOCAL_REGISTRY_URL}/${PROJECT_NAME}/${JOB_BASE_NAME}:${FULL_VERSION}"
                    env.DOCKER_IMAGE_NAME = DOCKER_IMAGE_NAME
                    env.DOCKER_DEPLOY_IMAGE_NAME = DOCKER_DEPLOY_IMAGE_NAME

                    // 打印信息
                    // echo "Latest tag: ${env.TAG_VERSION}"
                    // echo "Commit hash: ${env.COMMIT_HASH}"
                    // echo "Branch name: ${env.BRANCH_NAME}"
                    echo "DEPLOY IMAGES NAME : ${DOCKER_DEPLOY_IMAGE_NAME}"
                }
            }
        }

        stage('NPM代码编译打包') { 


          steps {

            sh '''
            rm -rf ../dist
            rm -rf ../node_modules
            pnpm config set registry ${NPM_REGISTRY_URL} 
            pnpm install  --no-frozen-lockfile
            pnpm install chalk
            pnpm run build

            '''
          }
        }

        // stage('代码检查') {


        //     steps {
        //         echo "启动sonar代码分析......"
        //         withSonarQubeEnv('sonar7.9') {
        //             //注意这里withSonarQubeEnv()中的参数要与之前SonarQube servers中Name的配置相同

        //             // nodejs
        //             sh """
        //                 ${scannerHome}/bin/sonar-scanner \
        //                 -Dsonar.projectKey=${JOB_BASE_NAME} \
        //                 -Dsonar.projectName=${JOB_BASE_NAME} \
        //                 -Dsonar.sources=. \
        //                 -Dsonar.sources=src \
        //                 -Dsonar.exclusions=node_modules/** \
        //                 -Dsonar.js.file.suffixes=.js,.jsx,.ts,.tsx 

        //             """

        //             // sh """
        //             //   cd cnh-iconnect-system/${JOB_BASE_NAME}
        //             //   ${scannerHome}/bin/sonar-scanner \
        //             //         -Dsonar.projectKey=${JOB_BASE_NAME} \
        //             //         -Dsonar.projectName=${JOB_BASE_NAME} \
        //             //         -Dsonar.projectBaseDir=./ \
        //             //         -Dproject.settings=../../sonar-project.properties
                                                        
        //             // """
        //             // sh """
        //             //     cd ${JOB_BASE_NAME}
        //             //     mvn clean verify sonar:sonar 
        //             // """    
        //             // sh """
        //             //     cd ${JOB_BASE_NAME}
        //             //     mvn clean verify sonar:sonar \
        //             //     -Dsonar.core.codeCoveragePlugin=jacoco \
        //             //     -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco-merged-test-coverage-report/jacoco.xml
        //             // """
        //             //指定了maven插件,如果不指定使用最新的
        //             //   sh 'cd ${JOB_BASE_NAME}'
        //             //   sh "mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar "
        //             // sh """
        //             //   cd cnh-api-gateway/${JOB_BASE_NAME}
        //             //   ${scannerHome}/bin/sonar-scanner \
        //             //         -Dsonar.projectKey=${JOB_BASE_NAME} \
        //             //         -Dsonar.projectName=${JOB_BASE_NAME} \
        //             //         -Dsonar.sources=. \
        //             //         -Dsonar.sources=src \
        //             //         -Dsonar.exclusions=**/bean/**,**/vo/**,**/dto/**,**/po/**,**/test/**,**/**/*Test \
        //             //         -Dsonar.java.binaries=./target/classes \
        //             //         -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml \
        //             //         -Dsonar.issue.ignore.multicriteria.e1.ruleKey=java:S482 \
        //             //         -Dsonar.issue.ignore.multicriteria.e1.resourceKey=**/** \
        //             //         -Dsonar.issue.ignore.multicriteria.e2.ruleKey=java:S1214 \
        //             //         -Dsonar.issue.ignore.multicriteria.e2.resourceKey=**/** \
        //             //         -Dsonar.issue.ignore.multicriteria.e3.ruleKey=java:S125 \
        //             //         -Dsonar.issue.ignore.multicriteria.e3.resourceKey=**/** \
        //             //         -Dsonar.issue.ignore.multicriteria.e4.ruleKey=java:S1488 \
        //             //         -Dsonar.issue.ignore.multicriteria.e4.resourceKey=**/** 
                            
        //             // """
                        
        //         }    
        //     }
        // }


        stage('Docker镜像构建') {
             steps {
                 sh """
                 echo "FROM ${DOCKER_BASE_IMAGE}" >Dockerfile
                 echo "COPY dist /usr/share/nginx/html" >>Dockerfile
                 """

                 sh """
                  docker buildx build -t ${DOCKER_IMAGE_NAME}  --file=${DOCKER_BUILD_FILE} ${DOCKER_BUILD_PATH}
                """
             }
         }


        stage('推送Docker镜像到镜像仓库') {
            
             steps {
                 sh """
                 docker login -u${DOCKER_REGISTRY_LOGIN_USER} -p${DOCKER_REGISTRY_LOGIN_PASSWORD} ${DOCKER_REGISTRY_URL} 
                 docker push ${DOCKER_IMAGE_NAME}
                 docker rmi ${DOCKER_IMAGE_NAME}
                 """
             }
         }


        stage('微服务部署到K8S') {
            steps {
                script {
                    withKubeConfig([credentialsId: env.K8S_CONFIG_SERCET, serverUrl: '']) {
                        def RETURN_VALUME = sh(script: '${K8S_COMMAND_PATH} --namespace ${K8S_NAMESPACE_NAME} get deployments -l app=${JOB_BASE_NAME} --ignore-not-found=true --no-headers', returnStdout: true).trim()
                        env.RETURN_VALUME = "$RETURN_VALUME"
                        if (env.RETURN_VALUME == ''){
                            sh '${JENKINS_HOME}/yaml/k8s_build  ${JENKINS_HOME}/yaml/deployment_template-cms.yaml ${JOB_BASE_NAME} --namespace ${K8S_NAMESPACE_NAME} --replicas=${K8S_POD_NUM}  --image-name ${PROJECT_NAME}/${JOB_BASE_NAME}:${BUILD_TIMESTAMP} --docker-registry ${DOCKER_LOCAL_REGISTRY_URL} --limit_memory 2Gi'
                            sh '${K8S_COMMAND_PATH} apply -f ${JOB_BASE_NAME}-dep.yaml'
                            // HPA
                            //sh '${JENKINS_HOME}/yaml/k8s_build  ${JENKINS_HOME}/yaml/template_autoscale.yaml ${JOB_BASE_NAME} --type hpa  --memory_scale 80 --min_replica 1 --max_replica 3'
                            //sh '${K8S_COMMAND_PATH} apply -f ${JOB_BASE_NAME}-hpa.yaml'
                            
                            // sh '''
                            //     ${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} run ${JOB_BASE_NAME}-${VERSION_NUM} --image=${DOCKER_IMAGE_NAME} --replicas=${K8S_POD_NUM} --labels="app=${JOB_BASE_NAME},version=${VERSION_NUM}" --overrides='{"spec": {"minReadySeconds": 120, "strategy": {"type": "RollingUpdate", "rollingUpdate": {"maxSurge": 1, "maxUnavailable": 0}}}}'
                            // '''
                        } else {
                          sh '${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} set image deployment ${JOB_BASE_NAME} ${JOB_BASE_NAME}=${DOCKER_DEPLOY_IMAGE_NAME}'
                          sh '${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} scale --replicas=${K8S_POD_NUM} deployment ${JOB_BASE_NAME}'
                        }
                        
                        def SVC_STATUS = sh(script: '${K8S_COMMAND_PATH} --namespace ${K8S_NAMESPACE_NAME} get service ${JOB_BASE_NAME} --ignore-not-found=true --no-headers', returnStdout: true).trim()
                        env.SVC_STATUS = "$SVC_STATUS"
                        if (env.SVC_STATUS == ''){
                            sh '${JENKINS_HOME}/yaml/k8s_build  ${JENKINS_HOME}/yaml/service_template.yaml ${JOB_BASE_NAME} --namespace ${K8S_NAMESPACE_NAME}  --type=service --port=${K8S_PORT} '
                            sh '${K8S_COMMAND_PATH} apply -f ${JOB_BASE_NAME}-svc.yaml'
                        //    sh '${K8S_COMMAND_PATH} --namespace=${K8S_NAMESPACE_NAME} create service clusterip ${JOB_BASE_NAME} --tcp=${K8S_PORT1}:${K8S_PORT1} --tcp=${K8S_PORT2}:${K8S_PORT2}'
                        }
                    }
                }
            }
        }

    }
}

四、 验证功能

 

在使用KubernetesK8s)和Jenkins构建Vue项目时,可以按照以下步骤进行操作: 1. 首先,创建一个Git仓库来管理Vue项目的源代码,并将其与Jenkins关联。可以选择在Jenkins中创建一个新的项目或使用现有的项目。 2.Jenkins中创建一个Pipeline或一个自由风格项目,并配置相关参数。比如,指定GIT仓库的URL、凭证、构建触发器等。 3.Jenkins Pipeline脚本或构建过程中,配置Kubernetes插件以与K8s集群通信。这个插件使Jenkins能够在K8s集群上创建和管理Pod、容器等资源。 4. 在构建过程中,可以通过执行一系列步骤来构建Vue项目。例如,可以通过运行npm install安装项目所需的依赖项,然后执行npm run build命令来构建Vue项目。 5. 构建完成后,可以使用Kubernetes插件将构建生成的静态文件打包为容器镜像,并将其推送到K8s的镜像仓库中。 6.Jenkins中配置Kubernetes插件,以便创建部署文件(Deployment)和服务(Service)等K8s资源。这些资源将使用前面构建的镜像来部署Vue应用程序。 7. 配置Kubernetes插件以在K8s集群上创建一个新的Pod,并将前面创建的K8s资源应用到该Pod上。 8. 最后,确认应用程序在K8s集群中成功部署并运行。可以通过访问指定的服务URL来查看Vue应用程序的界面。 这里只是简要地介绍了使用K8sJenkins构建Vue项目的基本步骤和操作。具体的实施会因环境、涉及的组件等因素而有所差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liao wen xiu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值