一、Scripted Pipeline(脚本式)流水线

脚本管道和声明管道一样,是建立在底层管道子系统之上的。与Declarative不同,Scripted Pipeline实际上是一个使用Groovy构建的通用DSL。

Groovy语言提供的大多数功能都可供Scripted Pipeline的方式使用,这意味着它可以是一个非常有扩展性和灵活性的工具,可以用来编写连续交付管道。

stage('Build&Tag&Push&Deploy') {
    // 把选择的项目信息转为数组
    def selectedProjects = "${project_name}".split(',')

    for (int i = 0; i < selectedProjects.size(); i++) {
        // 取出每个项目的名称
        def currentProjectName = selectedProjects[i]
        // 定义镜像名称
        def imageName = "${currentProjectName}:${tag}"
        // 定义 newTag
        def newTag = sh(returnStdout: true, script: 'echo `date +"%Y%m%d%H%M%S"_``git describe --tags --always`').trim()
        // 编译构建本地镜像
        sh "sed -i 's#ACTIVEPROFILE#${springProfilesActive}#g' Dockerfile"
        sh "mvn clean package -Dmaven.test.skip=true dockerfile:build"
        container('docker') {
            // 给镜像打标签
            sh "docker tag ${imageName} ${harbor_url}/${harbor_project_name}/${currentProjectName}:${newTag}"
            // 登录 Harbor并上传镜像
            withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                // 登录
                sh "docker login -u ${username} -p ${password} ${harbor_url}"
                // 上传镜像
                sh "docker push ${harbor_url}/${harbor_project_name}/${currentProjectName}:${newTag}"
            }
            // 删除本地镜像
            sh "docker rmi -f ${imageName}"
            sh "docker rmi -f ${harbor_url}/${harbor_project_name}/${currentProjectName}:${newTag}"
        }
        def deploy_image_name = "${harbor_url}/${harbor_project_name}/${currentProjectName}:${newTag}"

        // 基于 Helm 的方式部署到 K8S
        container('helm3') {
            withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
                sh """
                    helm repo add --username=${username} --password=${password} aliharborrepo http://harbor-ali-test.xxxx.com:8088/chartrepo/sparkx
                """
            }
            withCredentials([file(credentialsId: 'b8fca5a2-8c91-4456-99aa-071723aae7fe', variable: 'KUBECONFIG')]) {
                sh """
                    mkdir -p /root/.kube/ && echo \$KUBECONFIG >/root/.kube/config
                    echo "Helm应用配置信息确认..."
                    helm upgrade --install --dry-run --debug ${currentProjectName} --namespace devops aliharborrepo/javaAliTest \\
                        --set replicaCount=${replicas} \\
                        --set image.repository=${deploy_image_name} \\
                        --set service.type=ClusterIP \\
                        --set springActive=${springProfilesActive} \\
                        --set ingress.enabled=${isIngress}
                    echo "应用部署..."
                    helm upgrade --install ${currentProjectName} --namespace devops aliharborrepo/javaAliTest \\
                        --set replicaCount=${replicas} \\
                        --set image.repository=${deploy_image_name} \\
                        --set service.type=ClusterIP \\
                        --set springActive=${springProfilesActive} \\
                        --set ingress.enabled=${isIngress}
                """
            }
        }
    }
}

3.4 Declarative Pipeline 和 Scripted Pipeline 的比较

共同点:

两者都是pipeline代码的持久实现,都能够使用pipeline内置的插件或者插件提供的steps,两者都可以利用共享库扩展。

区别:

两者不同之处在于语法和灵活性。

Declarative pipeline:对用户来说,语法更严格,有固定的组织结构,容易生成代码段,使其成为用户更理想的选择。

Scripted pipeline:更加灵活,因为Groovy本身只能对结构和语法进行限制,对于更复杂的pipeline来说,用户可以根据自己的业务进行灵活的实现和扩展。