目录

CICD-jenkins使用pipeline部署应用实践

jenkins 使用 pipeline 流水线进行 CICD .

动机

最近进了新公司,新公司之前一直没运维,部署服务还是传统的手工部署,打完 jar 包,scp 到服务器上去部署,在这里的运维体系基本就是从零开始重构,于是我们早期打算 jenkins 结合 k8s 来完成第一阶段的重构。

pipeline

流水线的核心步骤:

  • 拉取代码

  • maven 构建

  • 打成 docker 镜像包

  • 推送镜像

  • 部署到 k8s 里面

  • 部署消息推送

下面是本次重构 jenkins 的 pipeline 样本。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
pipeline{
    agent any
    environment { 
        NAMESPACE = "sit"
        DOCKER_TAG = "xxx.cn-shenzhen.cr.aliyuncs.com/sit"
        APP_NAME = "api-xxx"
        BUILD_TIME = sh(script: 'date  +"%Y-%m-%d %H:%M:%S"', returnStdout: true).trim()
        CURRENT_DATE = sh(script: 'date  +"%Y%m%d%H%M%S"', returnStdout: true).trim()
    }
    stages{
        stage("git pull"){
            steps {
                git branch: '${BRANCH}', credentialsId: '5ec0c4ff-d992-4f38-91fa-becde27c567a', url: 'https://xxx.com/zlsk/xxx.git'
            }
        }
        stage("project build"){
            tools {
                jdk "jdk1.8"
            }
            steps {
                sh '''
                    /usr/local/maven/apache-maven-3.9.9/bin/mvn clean package -Dmaven.test.skip=true
                    '''
            }
        }
        stage("docker build"){
            steps {
                sh '''
                    cd api/api_biz
                    docker build -t ${DOCKER_TAG}/${APP_NAME}:${BRANCH}-${CURRENT_DATE} .
                    '''
            }
        }
        stage("docker push"){
            steps {
                sh '''
                docker push ${DOCKER_TAG}/${APP_NAME}:${BRANCH}-${CURRENT_DATE}
                '''
            }
        }
        stage("deploy"){
            steps {
                withKubeConfig([credentialsId: 'ced577d0-cf92-xxx']) {
                    sh 'kubectl set image deployment/${APP_NAME} ${APP_NAME}=${DOCKER_TAG}/${APP_NAME}:${BRANCH}-${CURRENT_DATE} -n ${NAMESPACE}'
                    sh 'timeout 7m kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE}'
                }
            }
        }
    }
    post{
        success{
            dingtalk(
                // 指定Jenkins中配置钉钉的ID信息。
                robot: 'sit-notifications',
                // 指定通知文本的类型为markdown。
                type: 'MARKDOWN',
                // 配置任务的标题,如果要引用变量,则需要使用双引号。
                title: "${env.JOB_NAME} 构建成功😄",
                // 定义文本推送的内容,其中${currentBuild.durationString}在流水线语法中"全局变量参考"有记录。
                text: [
                    "<font color='green'>【 ${env.JOB_NAME} 】构建成功😄</font> \n",
                    "> 构建时间: ${BUILD_TIME} \n", 
                    "> 构建分支: ${env.branch} \n", 
                    "> 持续时间: ${currentBuild.durationString.split("and counting")[0]} \n", 
                    "> 执行人: ${currentBuild.buildCauses.shortDescription} \n", 
                    "> [查看控制台](${env.BUILD_URL}console)"
                ]
            )
        }
        failure{
            dingtalk(
                // 指定Jenkins中配置钉钉的ID信息。
                robot: 'sit-notifications',
                // 指定通知文本的类型为markdown。
                type: 'MARKDOWN',
                // 配置任务的标题,如果要引用变量,则需要使用双引号。
                title: "${env.JOB_NAME} 构建失败😭",
                // 定义文本推送的内容,其中${currentBuild.durationString}在流水线语法中"全局变量参考"有记录。
                text: [
                    "<font color='red'>【 ${env.JOB_NAME} 】构建失败😭</font> \n", 
                    "> 构建时间: ${BUILD_TIME} \n",
                    "> 构建分支: ${env.branch} \n", 
                    "> 持续时间: ${currentBuild.durationString.split("and counting")[0]} \n", 
                    "> 执行人: ${currentBuild.buildCauses.shortDescription} \n", 
                    "> [查看控制台](${env.BUILD_URL}console)"
                ]
            )
        }
    }
}

plugins

消息推送的前提是需要安装 DingTalk 这个插件。

安装完以后在 系统配置 –> 钉钉 –> 配置钉钉机器人,上面 robot 是引用的钉钉机器人的 id 。

最后

很久没有搞 jenkins 了,很多东西基本都是从头又摸了一遍。