持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚

目录

一、实验

1.环境

2. GitLab 共享库新建HELM CI流水线

3.Jenkins新建HELM CI流水线

5.Jenkins构建前端项目

6.GitLab 共享库新建HELM CD流水线

7.Jenkins新建HELM CD流水线

8.HELM完成前端项目应用发布与回滚

9.Jenkins再次构建前端项目

10.HELM再次完成前端项目应用发布与回滚

二、问题

1. HELM CD流水线报错


一、实验

1.环境

(1)主机

表1  主机

主机 架构 版本 IP 备注
master1 K8S master节点 1.20.6 192.168.204.180

jenkins slave

(从节点)

helm 3.6.0
git 1.8.3.1
node1 K8S node节点 1.20.6 192.168.204.181
node2 K8S node节点 1.20.6 192.168.204.182
jenkins

 jenkins主节点      

2.414.2 192.168.204.15:8080

 gitlab runner

(从节点)

harbor私有仓库 1.2.2 192.168.204.15
gitlab gitlab 主节点      12.10.14 192.168.204.8:82

jenkins slave

(从节点)

sonarqube 9.6 192.168.204.8:9000

2. GitLab 共享库新建HELM CI流水线

(1)共享库新建CI流水线

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第1张图片

(2)修改k8scihelm.jenkinsfile

@Library("mylib@master") _
import org.devops.*


def checkout = new Checkout()
def build = new Build()
def unittest = new UnitTest()
def sonar = new Sonar()
def gitlabutil = new Gitlab()


pipeline {
    agent { label "build"}

    options {
        skipDefaultCheckout true
    }
    stages{
        stage("Checkout"){
            steps{
                script {
                    println("GetCode")
                    checkout.GetCode("${env.srcUrl}","${env.branchName}")
                }
            }
        }
        stage("build"){
            steps{
                script{
                    println("Build")
                    build.CodeBuild("${env.buildTool}")
                }
            }

        }

        stage("UnitTest"){
            steps{
                script{
                    println("Test")
                    unittest.CodeTest("${env.buildTool}")
                }
            }

        }
        stage("SonarScan"){
            steps {
                script {
                    groupName = "${JOB_NAME}".split("/")[0]
                    projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]
                    sonar.CodeSonar("${env.buildTool}",projectName,groupName)
                }

            }

        }
        stage("PushImage"){
            steps {
                script {
                    repoName = "${JOB_NAME}".split("/")[0]
                    projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]
                    env.registry = "192.168.204.15"
                    env.imageName = "${env.registry}/${repoName}/${projectName}:${env.branchName}"
                    withCredentials([usernamePassword(credentialsId: '8c662308-4991-4576-9826-74a5417de685', passwordVariable: 'DOCKER_PASSWD', usernameVariable: 'DOCKER_USER')]) {
                        sh """
                            #重写HTML首页
                            echo "${env.imageName}" > dist/index.html 
    
                            #构建镜像
                            docker build -t ${env.imageName} .
                           
                            #登录镜像仓库
                            docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWD} ${env.registry}
                            
                            #上传镜像
                            docker push  ${env.imageName}
    
                            #删除镜像
                            sleep 2
                            docker rmi ${env.imageName}
                        """
                    }


                }

            }

        }

        stage("ReleaseFile"){
            steps{
                script{
                    env.namespace = "${JOB_NAME}".split("/")[0]
                    env.appName ="${JOB_NAME}".split("/")[-1].split("_")[0]
                    // 获取values.yaml文件
                    fileData = gitlabutil.GetRepoFile(23,"${env.appName}%2fvalues.yaml", "master")
                    yamlData = readYaml text: fileData

                    // 替换模板文件内容
                    yamlData.image.tag  = "${env.imageName}".split(":")[-1]
                    yamlData.image.repository = "${env.registry}/${env.namespace}/${env.appName}"


                    //保存yaml文件
                    sh "rm -fr values.yaml"
                    writeYaml  charset: 'UTF-8', file: 'values.yaml', data: yamlData

                    // 上传替换后的版本文件(新建文件或者更新文件)
                    newYaml = sh returnStdout: true, script: 'cat values.yaml'
                    println(newYaml)
                    
                    //更新gitlab文件内容
                    base64Content = newYaml.bytes.encodeBase64().toString()

                    // 会有并行问题,同时更新报错
                    try {
                        gitlabutil.UpdateRepoFile(23,"${env.appName}%2fvalues.yaml",base64Content, "master")
                    } catch(e){
                        gitlabutil.CreateRepoFile(23,"${env.appName}%2fvalues.yaml",base64Content, "master")
                    }
                }
            }
        }
    }

}


 

3.Jenkins新建HELM CI流水线

(1)新建CI流水线

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第2张图片

(2)修改脚本路径

(3)新建视图

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第3张图片

(4)列表添加持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第4张图片

(5)查看视图

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第5张图片

5.Jenkins构建前端项目

(1)Jenkins构建前端项目 CI流水线,指定版本为RELEASE-1.1.6

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第6张图片

(2)完成

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第7张图片

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第8张图片

(3)GitLab HELM项目显示更新了文件values.yaml

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第9张图片

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第10张图片

更新前:

更新后:

6.GitLab 共享库新建HELM CD流水线

(1)共享库新建CD流水线

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第11张图片

(2)修改k8scdhelm.jenkinsfile

@Library("mylib@master") _
import org.devops.*


def checkout = new Checkout()
def gitlabbutil = new Gitlab()
env.groupName = "${JOB_NAME}".split("/")[0]
env.projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]


pipeline {
    agent { label "k8s"}

    options {
        skipDefaultCheckout true
    }
    stages{
        stage("GetChartRepo"){
            steps{
                script {
                    println("GetCode")
                    checkout.GetCode("${env.srcUrl}","${env.branchName}")
                }
            }
        }

        stage("DeployAPP"){
            steps{
                script{
                    env.namespace = "${env.groupName}"
                    env.appName = "${env.projectName}"

                    // HELM 发布
                    sh """
                        helm package "${env.appName}/"
                        helm upgrade --install --create-namespace  "${env.appName}" ./"${env.appName}"-*.tgz -n ${env.namespace}
                        helm history "${env.appName}"  -n ${env.namespace}
                    """

                    //获取release的历史版本
                    env.revision = sh returnStdout: true, script: """helm history ${env.appName} -n ${env.namespace} | grep -v 'REVISION' | awk '{print \$1}' """
                    println("${env.revision}")
                    println("${env.revision.split('\n').toString()}")
                    env.REVISION = "${env.revision.split('\n').toString()}"
                    println("${env.REVISION}")

                    // 获取应用状态
                    5.times{
                        sh "sleep 2; kubectl -n ${env.namespace} get pod | grep ${env.appName}"
                    }


                }
            }
        }

        stage("RollOut"){
            steps{
                script{
                    //获取release的历史版本
                    env.revision = sh returnStdout: true, script: """helm history ${env.appName} -n ${env.namespace} | grep -v 'REVISION' | awk '{print \$1}' """
                    //println("${env.revision}")
                    //println("${env.revision.split('\n').toString()}")
                    env.REVISION = "${env.revision.split('\n').toString()}"
                    println("${env.REVISION}")
                    def result = input message: 'RollBack?',
                                       ok: 'submit',
                                       parameters: [choice(choices: "${env.REVISION}", description: '', name: 'revision')]
                    env.result = result - "\n"

                    echo "Actions is  ${env.result}, doing......."
                    if ( "${env.result}" != ""){
                        sh """ helm rollback ${env.appName} ${env.result} -n ${env.namespace}  """
                    } else {
                        println("Skip rollback .....")
                    }

                }
            }
        }
    }
}

(3)查看共享库目录

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第12张图片

7.Jenkins新建HELM CD流水线

 (1)新建CD流水线

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第13张图片

(2)修改脚本路径

(3)复制Clone项目地址

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第14张图片

(4)添加字符参数

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第15张图片

(5)新建并查看视图

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第16张图片

8.HELM完成前端项目应用发布与回滚

(1)K8S master节点另开一个终端用watch命令观察pod变化

# watch -n 1 "kubectl get pod -n devops03"

(2)外部测试访问(当前版本为1.1.6)

# curl http://devops03-devops-ui.devops.com:31291

(3)Jenkins构建前端项目CD 流水线,指定分支为master

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第17张图片

(4)选择回滚 1 版本

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第18张图片

相当于选择1 版本

# helm rollback devops03-devops-ui 1 -n devops03

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第19张图片

(5)完成

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第20张图片

(6)观察pod变化

9.Jenkins再次构建前端项目

(1)Jenkins构建前端项目 CI流水线,指定版本为RELEASE-1.1.7

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第21张图片

(2)完成

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第22张图片持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第23张图片

(3)GitLab HELM项目显示更新了文件values.yaml

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第24张图片

更新前:

更新后:

10.HELM再次完成前端项目应用发布与回滚

(1)Jenkins构建前端项目CD 流水线,指定分支为master

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第25张图片

(2)观察pod变化持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第26张图片持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第27张图片

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第28张图片

(3)外部测试访问(当前版本为1.1.7)

# curl http://devops03-devops-ui.devops.com:31291

(4)选择回滚 6 版本

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第29张图片

相当于选择6 版本

# helm rollback devops03-devops-ui 1 -n devops03

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第30张图片

(5)完成

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第31张图片

(6)观察pod变化

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第32张图片持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第33张图片持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第34张图片持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第35张图片

(7)外部测试访问(当前版本为1.1.6)

# curl http://devops03-devops-ui.devops.com:31291

(8)查看历史版本

# helm history devops03-devops-ui -n devops03

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第36张图片

二、问题

1. HELM CD流水线报错

(1) 报错

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第37张图片

(2)原因分析

GitLab HELM项目只有master分支

(3)解决方法

分支名输入master.

修改:

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第38张图片

成功:

持续集成交付CICD:HELM 自动化完成前端项目应用发布与回滚_第39张图片

你可能感兴趣的:(持续集成交付CICD,ci/cd,自动化,运维)