流水线与k8s的持续集成落地分享


本次线上技术分享我将分享和介绍:

  • 合理收集需求,设计ci/cd落地方案

  • 自建pipeline结合k8s实现ci

    • jenkins连接k8s集群的多种姿势
    • 常用应用maven+jar、ant+tomcat、php+nginx的ci实现
    • 与sharelibrary结合、简化流水线
  • 自建jenkins pipeline结合k8s实现cd

    • 线上环境pipeline实现
    • pipeline+k8s回滚该怎么做
  • 未尽事宜,和大家共同学习交流

4赞

以下是pipeline大致内容

#!/usr/bin/env groovy
// 项目全局配置信息
def ProjectName = "test-ssgeek"
// 项目下的应用名称
def AppName = "test-ssgeek"
// 项目的域名
def WebDomainName = "www.ssgeek.com"
// 项目基于域名的访问路径
def ProjectPath = "/"
// 项目的git仓库地址
def GitAddress = "git@git.ssgeek.com:java/demo.git"
// 项目代码工程类型,可选参数"ant", "maven", "php"
def CodeType = "ant"

// ----------我----------是----------隔----------离----------线----------
// ----------下-----面-----内-----容-----请-----勿-----修-----改----------

@Library('pipelinesharelibrary') _

def buildinfo = new org.devops.buildinfo()
def codecheckout = new org.devops.codecheckout()
def codecompile = new org.devops.codecompile()
def docker = new org.devops.docker()
def deploy2k8s = new org.devops.deploy2k8s()
def dingmes = new org.devops.dingmes()

// 流水线内容
pipeline {
    agent {
        kubernetes{
            cloud 'kubernetes'
            label "jenkins-slave-${UUID.randomUUID().toString()}"
            activeDeadlineSeconds '30'
            yaml """
apiVersion: v1
kind: Pod
metadata:
  name: jenkins-slave
  labels:
    jenkins: slave
spec:
  containers:
  - name: jnlp
    image: hub.ssgeek.com/jenkins_slave/jdk_8u191-ant_1.9.14:v1.0
    imagePullPolicy: Always
    tty: false
    volumeMounts:
      - name: m2
        mountPath: /root/.m2
        readonly: false
      - name: docker
        mountPath: /usr/bin/docker
        readonly: false
      - name: dockersock
        mountPath: /var/run/docker.sock
        readonly: false
...
  restartPolicy: Never
  volumes:
    - name: m2
      hostPath:
        path: /var/run/m2
        type: DirectoryOrCreate
    - name: docker
      hostPath:
        path: /usr/bin/docker
        type: File
    - name: dockersock
      hostPath:
        path: /var/run/docker.sock
        type: Socket
...
            """
        }
    }
    environment{
        // 镜像仓库地址
        DockerRegistry = "hub.ssgeek.com"
        // 认证凭据
        ImageSecret = "registry-pull-secret"
        DockerRegistryAuth = "harborauth"
...
    }
    options{
        // 保留20次构建历史
        buildDiscarder(logRotator(numToKeepStr: '20'))
...
    }
    parameters{
        gitParameter(
            branch: '', 
            branchFilter: 'origin/(.*)', 
            defaultValue: 'master', 
            description: '<h3>部署的分支或者tag</h3>', 
            name: 'BranchOrTag', 
            quickFilterEnabled: true, 
            selectedValue: 'NONE', 
            sortMode: 'ASCENDING_SMART', 
            tagFilter: '*', 
            type: 'PT_BRANCH_TAG'
        )
        string(
            name: 'JavaJvm',
            defaultValue: '-server -Xms256M...',
            description: '<h3>Java JVM参数</h3>'
        )
        choice(
            name: 'LimitMemory', 
            choices: ['2Gi', '4Gi', '8Gi'], 
            description: '<h3>容器限制的最大内存</h3>'
        )
...
    }
    stages {
        stage('Build Info'){
            steps{
                script {
                    buildinfo.BuildInfo(BranchOrTag)
                }
            }
        }
        stage('Git Checkout'){
            steps{
                script{
                    (ImageTag,ImageName) = codecheckout.GetCode(GitAddress,BranchOrTag...)                   
                }
            }
        }
        stage('Compile Code'){
            steps{
                script{
                    codecompile.CodeCompile(CodeType)
                }
            }
        }
        stage('Build and Push Docker Image'){
            steps{
                script{
                    try {
                        docker.Docker(CodeType,ProjectPath...)
                    }
                    catch (exc) {
                        echo "打包和推送镜像失败 - ${currentBuild.fullDisplayName}"
                        CatchInfo = "打包和推送镜像失败"
                        throw(exc)
                    }
                }
            }
        }
        stage('Deploy to Kubernetes'){
            steps{
                script{
                    deploy2k8s.Deploy2k8s(CodeType,ProjectName...)
                }
            }
        }
    }
    post{
        success{
            script{
                dingmes.HttpReq(AppName,ImageTag,"构建成功")
            }
        }
        failure{
            script{
                dingmes.HttpReq(AppName,ImageTag,"构建失败",CatchInfo)
            }
        }
        unstable{
            script{
                dingmes.HttpReq(AppName,ImageTag,"构建失败","不稳定异常")
            }
        }
        aborted{
            script{
                dingmes.HttpReq(AppName,ImageTag,"构建失败","暂停或中断")
            }
        }
    }
}
3赞

欢迎大家与我共同交流学习 :grinning: :grinning: :grinning:

你好,请问你的个人 blog 链接是 https://www.ssgeek.com/ 这个对吗?

是的 :blush:

:handshake: 多交流多指导哈。