基于K8s的DevOps平台实践(二)

这篇具有很好参考价值的文章主要介绍了基于K8s的DevOps平台实践(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1. 流水线入门

工厂的流水线如下:

stage('checkout scm'),Kubernetes原理与实战,kubernetes,devops,jenkins,云原生,docker

官方文档 的流水线如下:

stage('checkout scm'),Kubernetes原理与实战,kubernetes,devops,jenkins,云原生,docker

为什么叫做流水线?其实和工厂产品的生产线类似,pipeline 是从源码到发布到线上环境。

关于流水线,需要知道的几个点:

  • 重要的功能插件,帮助 Jenkins 定义了一套工作流框架;

  • Pipeline 的实现方式是一套 Groovy DSL( 领域专用语言 ),所有的发布流程都可以表述为一段 Groovy 脚本;

  • 将 WebUI 上需要定义的任务,以脚本代码的方式表述出来;

  • 帮助jenkins实现持续集成 CI(Continue Integration)和持续部署 CD(Continue Deliver)的重要手段;

🍑 流水线基础语法

官方文档

两种语法类型:

  • Scripted Pipeline,脚本式流水线,最初支持的类型
  • Declarative Pipeline,声明式流水线,为 Pipeline plugin 在 2.5 版本之后新增的一种脚本类型,后续 Open Blue Ocean 所支持的类型。与原先的 Scripted Pipeline 一样,都可以用来编写脚本。Declarative Pipeline 是后续 Open Blue Ocean 所支持的类型,写法简单,支持内嵌 Scripted Pipeline 代码

注意:为与 BlueOcean 脚本编辑器兼容,通常建议使用 Declarative Pipeline 的方式进行编写,从 jenkins 社区的动向来看,很明显这种语法结构也会是未来的趋势。

🍑 脚本示例

json 脚本

pipeline { 
    agent {label '172.21.51.68'}
    environment { 
        PROJECT = 'myblog'
    }
    stages {
        stage('Checkout') { 
            steps { 
                checkout scm 
            }
        }
        stage('Build') { 
            steps { 
                sh 'make' 
            }
        }
        stage('Test'){
            steps {
                sh 'make check'
                junit 'reports/**/*.xml' 
            }
        }
        stage('Deploy') {
            steps {
                sh 'make publish'
            }
        }
    }
	post {
        success { 
            echo 'Congratulations!'
        }
		failure { 
            echo 'Oh no!'
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 脚本解释

  • checkout 步骤为检出代码;scm 是一个特殊变量,指示 checkout 步骤克隆触发此 Pipeline 运行的特定修订

  • agent:指明使用哪个 agent 节点来执行任务,定义于 pipeline 顶层或者 stage 内部

    • any,可以使用任意可用的 agent 来执行

    • label,在提供了标签的 Jenkins 环境中可用的代理上执行流水线或阶段。例如:agent { label 'my-defined-label' },最常见的使用方式

    • none,当在 pipeline 块的顶部没有全局代理,该参数将会被分配到整个流水线的运行中并且每个 stage 部分都需要包含他自己的 agent 部分。比如:agent none

    • docker, 使用给定的容器执行流水线或阶段。 在指定的节点中,通过运行容器来执行任务

agent {
    docker {
        image 'maven:3-alpine'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}
  • options:允许从流水线内部配置特定于流水线的选项。

    • buildDiscarder,为最近的流水线运行的特定数量保存组件和控制台输出。例如: options { buildDiscarder(logRotator(numToKeepStr: '10')) }
    • disableConcurrentBuilds,不允许同时执行流水线。 可被用来防止同时访问共享资源等。 例如: options { disableConcurrentBuilds() }
    • timeout,设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。例如: options { timeout(time: 1, unit: 'HOURS') }
    • retry,在失败时, 重新尝试整个流水线的指定次数。 For example: options { retry(3) }
  • environment:指令制定一个 键-值对序列,该序列将被定义为所有步骤的环境变量

  • stages:包含一系列一个或多个 stage 指令,stages 部分是流水线描述的大部分 “work” 的位置。 建议 stages 至少包含一个 stage 指令用于连续交付过程的每个离散部分,比如构建、测试和部署。

pipeline {
    agent any
    stages { 
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
  • steps:在给定的 stage 指令中执行的定义了一系列的一个或多个 steps。

  • post:定义一个或多个 steps ,这些阶段根据流水线或阶段的完成情况而运行 post 支持以下 post-condition 块中的其中之一: alwayschangedfailuresuccessunstableaborted

    • always,无论流水线或阶段的完成状态如何,都允许在 post 部分运行该步骤
    • changed,当前流水线或阶段的完成状态与它之前的运行不同时,才允许在 post 部分运行该步骤
    • failure,当前流水线或阶段的完成状态为 “failure”,才允许在 post 部分运行该步骤,通常 web UI 是红色
    • success,当前流水线或阶段的完成状态为 “success”,才允许在 post 部分运行该步骤,通常 web UI 是蓝色或绿色
    • unstable,当前流水线或阶段的完成状态为 “unstable”,才允许在 post 部分运行该步骤,通常由于测试失败,代码违规等造成。通常 web UI 是黄色
    • aborted,只有当前流水线或阶段的完成状态为 “aborted”,才允许在 post 部分运行该步骤,通常由于流水线被手动的aborted。通常 web UI 是灰色

创建 pipeline 示意:新建任务 -> 流水线

jenkins/pipelines/p1.yaml

pipeline {
   agent {label '172.21.51.68'}
   environment { 
      PROJECT = 'myblog'
   }
   stages {
      stage('printenv') {
         steps {
            echo 'Hello World'
            sh 'printenv'
         }
      }
      stage('check') {
         steps {
            checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-user', url: 'http://gitlab.luffy.com/root/myblog.git']]])
         }
      }
      stage('build-image') {
         steps {
            sh 'docker build . -t myblog:latest -f Dockerfile'
         }
      }
      stage('send-msg') {
         steps {
            sh """
            curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text", 
        "text": {
             "content": "我就是我, 是不一样的烟火"
        }
      }'
      """
         }
      }
   }
}

点击 “立即构建”,同样的,我们可以配置触发器,使用 webhook 的方式接收项目的 push 事件

  • 构建触发器选择 Build when a change is pushed to GitLab.
  • 生成 Secret token
  • 配置 gitlab,创建 webhook,发送 test push events 测试

🍑 Blue Ocean

官方文档

关于 Blue Ocean 我们需要知道的几点:

  • 是一个插件, 旨在为 Pipeline 提供丰富的体验 ;
  • 连续交付(CD)Pipeline 的复杂可视化,允许快速和直观地了解 Pipeline 的状态;
  • 目前支持的类型仅针对于 Pipeline,尚不能替代 Jenkins 经典版UI

思考:文章来源地址https://www.toymoban.com/news/detail-785754.html

  1. 每个项目都把大量的 pipeline 脚本写在 Jenkins 端,对于谁去维护及维护成本是一个问题
  2. 没法做版本控制

2. Jenkinsfile实践

Jenkins Pipeline 提供了一套可扩展的工具,用于将 “简单到复杂” 的交付流程实现为 “持续交付即代码”。

Jenkins Pipeline 的定义通常被写入到一个文本文件(称为 Jenkinsfile )中,该文件可以被放入项目的源代码控制库中。

🍑 演示一

演示1:使用 Jenkinsfile 管理 pipeline

  • 在项目中新建 Jenkinsfile 文件,拷贝已有 script 内容
  • 配置 pipeline 任务,流水线定义为 Pipeline Script from SCM
  • 执行 push 代码测试

Jenkinsfile:jenkins/pipelines/p2.yaml

pipeline {
   agent {label '172.21.51.68'}
   environment { 
      PROJECT = 'myblog'
   }
   stages {
      stage('printenv') {
         steps {
            echo 'Hello World'
            sh 'printenv'
         }
      }
      stage('check') {
         steps {
            checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-user', url: 'http://gitlab.luffy.com/root/myblog.git']]])
         }
      }
      stage('build-image') {
         steps {
            sh 'docker build . -t myblog:latest -f Dockerfile'
         }
      }
      stage('send-msg') {
         steps {
            sh """
            curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text", 
        "text": {
             "content": "我就是我, 是不一样的烟火"
        }
      }'
      """
         }
      }
   }
}

🍑 演示二

演示2:优化及丰富流水线内容

  • 优化代码检出阶段

    由于目前已经配置了使用 git 仓库地址,且使用 SCM 来检测项目,因此代码检出阶段完全没有必要再去指定一次

  • 构建镜像的 tag 使用 git 的 commit id

  • 增加 post 阶段的消息通知,丰富通知内容

  • 配置 webhook,实现 myblog 代码推送后,触发 Jenkinsfile 任务执行

jenkins/pipelines/p3.yaml

pipeline {
    agent { label '172.21.51.68'}

    stages {
        stage('printenv') {
            steps {
            echo 'Hello World'
            sh 'printenv'
            }
        }
        stage('check') {
            steps {
                checkout scm
            }
        }
        stage('build-image') {
            steps {
            	retry(2) { sh 'docker build . -t myblog:${GIT_COMMIT}'}
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😄👍构建成功👍😄\n 关键字:luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址:${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😖❌构建失败❌😖\n 关键字:luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址:${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 演示三

演示3:使用 k8s 部署服务

  • 新建 deploy 目录,将 k8s 所需的文件放到 deploy 目录中

  • 将镜像地址改成模板,在 pipeline 中使用新构建的镜像进行替换

  • 执行 kubectl apply -f deploy 应用更改,需要配置 kubectl 认证

$ scp -r k8s-master:/root/.kube /root

jenkins/pipelines/p4.yaml

pipeline {
    agent { label '172.21.51.68'}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/myblog"
    }

    stages {
        stage('printenv') {
            steps {
              echo 'Hello World'
              sh 'printenv'
            }
        }
        stage('check') {
            steps {
                checkout scm
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😄👍构建成功👍😄\n 关键字:myblog\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址:${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😖❌构建失败❌😖\n 关键字:luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址:${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 演示四

演示4:使用凭据管理敏感信息

上述 Jenkinsfile 中存在的问题是敏感信息使用明文,暴漏在代码中,如何管理流水线中的敏感信息(包含账号密码),之前我们在对接 gitlab 的时候,需要账号密码,已经使用过凭据来管理这类敏感信息,同样的,我们可以使用凭据来存储钉钉的 token 信息,那么,创建好凭据后,如何在 Jenkinsfile 中获取已有凭据的内容?

Jenkins 的声明式流水线语法有一个 credentials() 辅助方法(在 environment 指令中使用),它支持 secret 文本,带密码的用户名,以及 secret 文件凭据。

下面的流水线代码片段展示了如何创建一个使用带密码的用户名凭据的环境变量的流水线。

在该示例中,带密码的用户名凭据被分配了环境变量,用来使你的组织或团队以一个公用账户访问 Bitbucket 仓库;这些凭据已在 Jenkins 中配置了凭据 ID jenkins-bitbucket-common-creds

当在 environment 指令中设置凭据环境变量时:

environment {
    BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
}

这实际设置了下面的三个环境变量:

  • BITBUCKET_COMMON_CREDS - 包含一个以冒号分隔的用户名和密码,格式为 username:password
  • BITBUCKET_COMMON_CREDS_USR - 附加的一个仅包含用户名部分的变量。
  • BITBUCKET_COMMON_CREDS_PSW - 附加的一个仅包含密码部分的变量。
pipeline {
    agent {
        // 此处定义 agent 的细节
    }
    environment {
        //顶层流水线块中使用的 environment 指令将适用于流水线中的所有步骤。 
        BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
    }
    stages {
        stage('Example stage 1') {
 			//在一个 stage 中定义的 environment 指令只会将给定的环境变量应用于 stage 中的步骤。
            environment {
                BITBUCKET_COMMON_CREDS = credentials('another-credential-id')
            }
            steps {
                // 
            }
        }
        stage('Example stage 2') {
            steps {
                // 
            }
        }
    }
}

因此对 Jenkinsfile 做改造:jenkins/pipelines/p5.yaml

pipeline {
    agent { label '172.21.51.68'}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/myblog"
        DINGTALK_CREDS = credentials('dingTalk')
    }

    stages {
        stage('printenv') {
            steps {
            echo 'Hello World'
            sh 'printenv'
            }
        }
        stage('check') {
            steps {
                checkout scm
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😄👍构建成功👍😄\n 关键字:luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址:${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😖❌构建失败❌😖\n 关键字:luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址:${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 总结

上面我们已经通过 Jenkinsfile 完成了最简单的项目的构建和部署,那么我们来思考目前的方式:

目前都是在项目的单一分支下进行操作,企业内一般会使用 feature、develop、release、master 等多个分支来管理整个代码提交流程,如何根据不同的分支来做构建?

构建视图中如何区分不同的分支?

如何不配置 webhook 的方式实现构建?

如何根据不同的分支选择发布到不同的环境(开发、测试、生产)?

3. 多分支流水线实践

官方示例

我们简化一下流程,假如使用 develop 分支作为开发分支,master 分支作为集成测试分支,看一下如何使用多分支流水线来管理。

🍑 演示一

演示1:多分支流水线的使用

(1)提交develop分支:

$ git checkout -b develop
$ git push --set-upstream origin develop

(2)禁用 pipeline 项目

(3)Jenkins 端创建多分支流水线项目

  • 增加 git 分支源
  • 发现标签
  • 根据名称过滤,develop|master|v.*
  • 高级克隆,设置浅克隆

保存后,会自动检索项目中所有存在 Jenkinsfile 文件的分支和标签,若匹配我们设置的过滤正则表达式,则会添加到多分支的构建视图中。所有添加到视图中的分支和标签,会默认执行一次构建任务。

🍑 演示二

演示2:美化消息通知内容

  • 添加构建阶段记录
  • 使用 markdown 格式,添加构建分支消息

jenkins/pipelines/p6.yaml

pipeline {
    agent { label '172.21.51.68'}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/myblog"
        DINGTALK_CREDS = credentials('dingTalk')
        TAB_STR = "\n                    \n                    "
    }

    stages {
        stage('printenv') {
            steps {
                script{
                    sh "git log --oneline -n 1 > gitlog.file"
                    env.GIT_LOG = readFile("gitlog.file").trim()
                }
                sh 'printenv'
            }
        }
        stage('checkout') {
            steps {
                checkout scm
                script{
                    env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😄👍 构建成功 👍😄  \n**项目名称**:luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${GIT_BRANCH}   \n**构建地址**:${RUN_DISPLAY_URL}  \n**构建任务**:${BUILD_TASKS}"
                        }
                    }'
            """ 
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😖❌ 构建失败 ❌😖  \n**项目名称**:luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${GIT_BRANCH}  \n**构建地址**:${RUN_DISPLAY_URL}  \n**构建任务**:${BUILD_TASKS}"
                        }
                    }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 演示三

演示3:通知 gitlab 构建状态

Jenkins 端做了构建,可以通过 gitlab 通过的 api 将构建状态通知过去,作为开发人员发起 Merge Request 或者合并 Merge Request 的依据之一。

注意一定要指定 gitLabConnection('gitlab'),不然没法认证到 Gitlab 端

jenkins/pipelines/p7.yaml

pipeline {
    agent { label '172.21.51.68'}
    
    options {
		buildDiscarder(logRotator(numToKeepStr: '10'))
		disableConcurrentBuilds()
		timeout(time: 20, unit: 'MINUTES')
		gitLabConnection('gitlab')
	}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/demo/myblog"
        DINGTALK_CREDS = credentials('dingTalk')
        TAB_STR = "\n                    \n                    "
    }

    stages {
        stage('printenv') {
            steps {
                script{
                    sh "git log --oneline -n 1 > gitlog.file"
                    env.GIT_LOG = readFile("gitlog.file").trim()
                }
                sh 'printenv'
            }
        }
        stage('checkout') {
            steps {
                checkout scm
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😄👍 构建成功 👍😄  \n**项目名称**:luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${BRANCH_NAME}   \n**构建地址**:${RUN_DISPLAY_URL}  \n**构建任务**:${BUILD_TASKS}"
                        }
                    }'
            """ 
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😖❌ 构建失败 ❌😖  \n**项目名称**:luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${BRANCH_NAME}  \n**构建地址**:${RUN_DISPLAY_URL}  \n**构建任务**:${BUILD_TASKS}"
                        }
                    }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

我们可以访问 gitlab,然后找到 commit 记录,查看同步状态:

stage('checkout scm'),Kubernetes原理与实战,kubernetes,devops,jenkins,云原生,docker

提交 merge request,也可以查看到相关的任务状态,可以作为项目 owner 合并代码的依据之一:

stage('checkout scm'),Kubernetes原理与实战,kubernetes,devops,jenkins,云原生,docker

🍑 总结

优势:

  • 根据分支展示,视图人性化
  • 自动检测各分支的变更

思考:

  • Jenkins 的 slave 端,没有任务的时候处于闲置状态,slave 节点多的话造成资源浪费
  • 是否可以利用 kubernetes 的 Pod 来启动 slave,动态 slave pod 来执行构建任务

到了这里,关于基于K8s的DevOps平台实践(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于jenkins+k8s实现devops

    由于jenkins运行在k8s上能够更好的利用动态agent进行构建。所以写了个部署教程,亲测无坑 1、创建ns kubectl create namespace devops 2、kubectl apply -f jenkins.yml 注意:镜像建议使用最新版本,因为jenkin平台默认提供了最新的插件,且无法选择版本,所以如果jenkins版本过低会导致插件不

    2024年02月06日
    浏览(42)
  • DevOps基于k8s发布系统的实现

    首先,本篇文章所介绍的内容,已经有完整的实现,可以参考这里。 在微服务、DevOps和云平台流行的当下,使用一个高效的持续集成工具也是一个非常重要的事情。虽然市面上目前已经存在了比较成熟的自动化构建工具,比如jekines,还有一些商业公司推出的自动化构建工具

    2023年04月09日
    浏览(46)
  • 滴滴弹性云基于 K8S 的调度实践

    上篇文章详细介绍了弹性云混部的落地历程,弹性云是滴滴内部提供给网约车等核心服务的容器平台,其基于 k8s 实现了对海量 node 的管理和 pod 的调度。本文重点介绍弹性云的调度能力,分为以下部分: 调度链路图 :介绍当前弹性云调度体系链路,对架构体系有一个初步的

    2024年02月05日
    浏览(42)
  • DHorse v1.4.0 发布,基于 k8s 的发布平台

    新增特性 提供Fabric8客户端操作k8s(预览)的功能,可以通过指定-Dkubernetes-client=fabric8参数开启; Vue、React应用增加Pnpm、Yarn的构建方式; 支持Go、Flask、Django、Nuxt应用部署; 优化特性 副本指标数据保存为3天; 部署Nodejs应用时可以指定端口; 忽略搜索大小写匹配; 部署页面

    2024年02月07日
    浏览(38)
  • K8S+DevOps架构师实战课 | 汇总

    视频来源:B站《Dockerk8s教程天花板,绝对是B站讲的最好的,这一套学会k8s搞定Docker 全部核心知识都在这里》 一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持! 1.K8S+DevOps架构师实战课 | 认识docker_热爱编程的通信人的博客-CSDN博客 2.K8S+Dev

    2024年02月13日
    浏览(46)
  • K8s+Docker+KubeSphere+DevOps笔记

    提示:这里可以添加本文要记录的大概内容: 提示:以下是本篇文章正文内容,下面案例可供参考 云服务器ECS–实例–选区–创建–付费模式(按量付费)–服务器架构选择(包含服务器内存及数量)–镜像(操作系统)–选择实例基础存储–确认购买–选择网络(默认或

    2024年02月12日
    浏览(69)
  • Azure Devops上模版化K8s部署

    在2022年我们终于完成了主要业务系统上K8s的计划,在这里总结下我们上K8s时候的模版工程。   前提条件 本文不讨论K8s是什么,什么是容器化,为什么需要容器化,什么是微服务等这些基础内容,这些到处说的烂大街了。此类内容有兴趣可以看看微软系的介绍: 微服务体系架

    2024年02月02日
    浏览(47)
  • Flink 内容分享(十九):理想汽车基于Flink on K8s的数据集成实践

    目录 数据集成的发展与现状 数据集成的落地实践 1. 数据集成平台架构 2. 设计模型 3. 典型场景 4. 异构数据源 5. SQL 形式的过滤条件 数据集成云原生的落地实践 1. 方案选型 2. 状态判断及日志采集 3. 监控告警 4. 共享存储 未来规划 理想汽车数据集成的发展经历了四个阶段:

    2024年02月01日
    浏览(47)
  • 最后的组合:K8s 1.24 基于 Hekiti 实现 GlusterFS 动态存储管理实践

    知识点 定级: 入门级 GlusterFS 和 Heketi 简介 GlusterFS 安装部署 Heketi 安装部署 Kubernetes 命令行对接 GlusterFS 实战服务器配置(架构 1:1 复刻小规模生产环境,配置略有不同) 主机名 IP CPU 内存 系统盘 数据盘 用途 ks-master-0 192.168.9.91 2 4 50 100 KubeSphere/k8s-master ks-master-1 192.168.9.92 2 4 5

    2024年02月09日
    浏览(38)
  • DevOps搭建(十六)-Jenkins+K8s部署详细步骤

    ​ 要想从Harbor仓库中拉取镜像,首先要往主机和从机的daemon.json文件中添加Harbor的地址信息 \\\"insecure-registries\\\":[\\\"192.168.88.125:80\\\"],别忘了80端口 添加完之后,重启下docker 要拉取镜像,需要Harbor登录进行拉取,到Kuboard控制台对应的命名空间找到 密文 菜单,点击 创建Secret 。 填写

    2024年01月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包