Devops系列五(CI篇之pipeline libraray)jenkins将gitlab helm yaml和argocd 串联,自动部署到K8S

news2024/9/22 19:34:53

一、说在前面的话

本文是CI篇的上文,因为上一篇已经作了总体设计,就不再赘述,有需要的请看前文。
我们将演示,使用CI工具–jenkins,怎么和CD工具–argocd串联,重点是在Jenkins该怎么做。准备工作和argocd等相关事项,在前文已铺垫ok。

Jenkins,我们是使用k8s来部署的一个master-slave结构的集群。
在开发环境,Jenkins和argocd都是部署在同一个k8s集群。

接下来,我们的java应用服务,也都将部署在该K8S里。

二、关键技术

  • jenkinsfile
  • global pipeline library

依赖的jenkins插件:

  • Workspace Cleanup

三、流水线步骤

在这里插入图片描述
流水线的各个步骤是有jenkinsfile来拼装,每个流水,特别是构建Docker镜像、修改helm yaml、发送IM消息,都需要封装到pipeline library里。

在详细描述每个步骤前,我们需要预定服务发版的依据,程序版本号,最好是每次打包都升级。但是,在开发环境,有时候我们会偷懒,所以就采用版本号+时间戳的方式。允许同一个版本号,提交多次代码,均触发部署。

四、详细实现

4.1、配置pipeline libraray

在这里插入图片描述
在这里插入图片描述

本次k8s容器化部署,增加了一个java-k8s.jenkinsfile文件,让程序的部署可以同时支持两种部署方式。

下面详细说一说这几个pipeline libraray.

4.1.1、tools.groovy – 读取java程序的版本号

读取程序的版本号,读取mvn package后的target目录下的classes/git.properties文件里的版本号git.build.version。

// 读取java应用的版本号
def getAppVersion(packagePath) {
    def appVersion = sh returnStdout: true,
            script: """
                    grep 'git.build.version' ${packagePath}/classes/git.properties | cut -d'=' -f2 | sed 's/\\r//'
                    """
    // trim()
    return appVersion.trim()
}

那么git.properties是依赖哪个mvn插件呢?

<plugin>
   <groupId>pl.project13.maven</groupId>
   <artifactId>git-commit-id-plugin</artifactId>
   <version>4.0.0</version>
</plugin>

考虑到java工程可以是多模块的,那就不是简单的target,而应该是${moduleName}/target了。

在mvn package后,见下图:
在这里插入图片描述
git.properties内容详情参考:

#Generated by Git-Commit-Id-Plugin
#Wed May 17 11:20:13 CST 2023
git.build.time=2023-05-17T11\:20\:13+0800
git.build.version=1.0.7
git.commit.id.abbrev=3dab776
git.commit.id.full=3dab7764afac0e8222a2bef3d78dc8b3175f8caa

4.1.2、docker.groovy – 构建镜像并推送

封装docker的几个命令,考虑到变量比较多,如果你不是很明白,对比着示例来看,具体见前文。


package com.xxtech.devops

// 保证jenkins slave节点上安装了docker
// 第一个参数是服务名称,第二个参数是端口号,第四个是xxx.jar所在的目录,都是在docker build的时候需要
// 第三个参数是docker image的版本号(一般是程序的版本号),第五个参数是dockerfile所在的位置
// 
def buildAndPushImage(appName, port, version, packagePath, dockerfileName, repoDomain = "192.168.5.6:8086") {
    def repoProject = "xxx"

    // 1、构建
    sh """
        docker build --build-arg APPNAME="${appName}" --build-arg PORT="${port}" --build-arg PACKAGE_PATH="${packagePath}" -f ${dockerfileName} -t ${repoProject}/${appName}:${version} .
       """

    // 2、登录、打标签、推送
    // 这里需要配置jenkins凭证,用户名和密码方式。具体配置,在jenkins系列文章另说。
    // 只有这样,在jenkins job控制台,才不会输出了密码字段的内容。
    withCredentials([usernamePassword(passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME', credentialsId: "e4681123-7da2-4bd5-9bc2-7dd68375c406",)]) {
        sh """
            docker login ${repoDomain} -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}

            docker tag ${repoProject}/${appName}:${version} ${repoDomain}/${repoProject}/${appName}:${version}

            docker push ${repoDomain}/${repoProject}/${appName}:${version}
           """
    }

    // 3、删除本地镜像
    sh """
        docker rmi -f ${repoProject}/${appName}:${version}
        docker rmi -f ${repoDomain}/${repoProject}/${appName}:${version}
       """
}

4.1.3、helm.groovy – 触发helm部署

有两种方式,

  • 一种是调用helm命令,helm install至k8s。-- 不是很建议,缺乏界面,而且各应用的配置不相同,维护成本高。
  • 另外一种是修改git代码并提交,利用gitops思想,去触发argocd部署。-- 本文是采用这种方式,也是本系列的设计思路。(让CI的归jenkins,让CD的归argocd,jenkins这里只是一个触发动作,当然你是手动的话,你也可以略过本步骤。但是多少有点不完美)
package com.xxtech.devops
// helm yaml所在的git工程是  http://192.168.8.28:9980/root/argocd-helm-yaml.git
// 第一个参数是git代码下的一个目录,第二个参数的image的tag值
def updateYaml(appName, imageTag, repoUrl = "192.168.8.28:9980/root/argocd-helm-yaml.git") {
    // jenkins凭证
    def gitlabCredentialsId = "12116269-430c-4921-b63b-18a490f7531c"

    // 拉取git代码
    checkout([$class           : 'GitSCM',
              branches         : [[name: '*/master']],
              extensions       : [],
              userRemoteConfigs: [[
                                          credentialsId: "${gitlabCredentialsId}",
                                          url          : "http://${repoUrl}"
                                  ]]]
    )

    // 修改values.yaml中的image.tag
    withCredentials([usernamePassword(credentialsId: "${gitlabCredentialsId}", passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
        sh """
            // 替换image.tag的值,必须和上一次的不一样,否则后面的git提交会报错
            sed -i 's/tag:.*/tag: ${imageTag}/g' ${appName}/values.yaml
            git add ${appName}/values.yaml
            
            // 在git commit前,进行全局配置
            git config --global user.name "admin"
            git config --global user.email "admin@example.com"
            
            git commit -m "modify image tag to ${imageTag}"
            // git push的时候不会让你再次输入用户名和密码
            git push http://$GIT_USERNAME:$GIT_PASSWORD@${repoUrl} HEAD:master
           """
    }
}

4.1.4、http.groovy – 发送Im消息

我们需要把jenkins job的结果告知工程的相关人员。这就属于im的范畴了,实现就是调用一个http请求,能发送http请求即可,具体处理是交由消息接收服务去发送。

有人要问,为什么不直接在jenkinsfile里发,还要多引入一个服务呢?

这里,主要的原因是,我们的需求不是简单的通过rebot机器人,把发送消息至企业微信群里。
而是会给应用打标签,根据所属标签,而企业微信会维护标签下有哪些人。

package com.xxtech.devops

def request(reqType, reqUrl, reqBody, reqFile = '', contentType = "APPLICATION_JSON_UTF8") {
    def response = httpRequest httpMode: reqType,
            contentType: contentType,
            consoleLogResponseBody: true,
            ignoreSslErrors: true,
            uploadFile: reqFile,
            requestBody: reqBody,
            url: "${reqUrl}",
            timeout: 600
    //quiet: true

    return response
}


def imNotify(projectName, result, buildEnv, message, branch, buildBy, robotKey = '') {
    def reqBody = """   {"projectName": "${projectName}",
                    "buildResult": "${result}", 
                    "branch": "${branch}", 
                    "buildBy": "${buildBy}", 
                    "env": "${buildEnv}", 
                    "reason": "${message}", 
                    "robotKey": "${robotKey}",
                    "buildUrl": "${env.BUILD_URL}" } """

    def url = "http://192.168.10.47/devops/api/jenkins/notify"

    request("POST", url, reqBody)
}

4.2、docker in docker 容器的配置

docker image的构建和推送,要求你有docker环境,而不幸的是,我们无论是jnlp还是已安装的容器都不具备。
所以,我额外引入了一个容器docker:dind
这里,着重说明下我在使用过程中,遇到的几个问题。

4.2.1、未分配伪终端

报错信息是Container docker was terminated (Exit Code: 0, Reason: Completed),导致Jenkins job直接没跑起来。

在这里插入图片描述

4.2.2、未配置volumes

// dind运行,必须配置volumes如下。
volumes: [
    hostPathVolume(hostPath: '/var/run/docker.sock', mountPath: '/var/run/docker.sock')
 ]

4.2.3、dind运行不起来

dind没有/bin/bash, 且必须增加参数–privileged

docker run -d --privileged docker:dind

docker exec -it {容器ID} sh

而jenkins containerTemplate中的容器,默认值: --privileged: true,要不然就用不了docker:dind

五、未完待续

我们把CI篇分为两篇,本文是先介绍了pipeline library,是Jenkinsfile的一个基础。
下一篇,我们将详细说明java-k8s.jenkinsfile要怎么写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/732819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++常用库函数 5.输入和输出函数

函数名&#xff1a;fclose 函数原型&#xff1a;int fclose(FILE *stream)&#xff1b; 参数&#xff1a;streamFILE 结构的指针。 所需头文件&#xff1a;<cstdio> 返回值&#xff1a;如果该流成功关闭&#xff0c;fclose 返回0。如果出错&#xff0c;则返回 EOF。 功…

AI在金融领域的应用

AI金融领域 信贷业务 个人信贷单笔数额小、数量大&#xff0c;需要大量的人力和时间投入&#xff0c;信贷审核的数据也呈现出分散化、碎片化的特点。同时传统金融机构和互联网金融公司的风控环节中&#xff0c;普遍存在信息不对称、成本高、时效性差、效率低等问题&#xff0c…

动态规划之343 整数拆分(第6道)

题目&#xff1a; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例&#xff1a; 解法&#xff1a; 其实可以从1开始遍历 j &#xff0c;然后有两种…

Mysql之视图,索引,备份与恢复

目录 一&#xff0c;视图 1.视图是什么&#xff1f; 2.视图的重要性&#xff1f; 3.那些地方使用视图&#xff1f; 4.基本语法 二&#xff0c;索引 1.索引是什么&#xff1f; 2.索引的重要性&#xff1f; 3.索引的种类&#xff1a; 4.那些地方使用索引&#xff1f; 5.…

Gateway服务集成Nacos2021.0.4错误解决

问题 gateway服务集成nacos&#xff0c;启动后报错&#xff1a; Caused by: com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information:; 版本&#xff1a; jdk:1.8 spring-b…

10_Linux中断

目录 Linux中断API函数 中断号 上半部与下半部 软中断 tasklet 工作队列 设备树中断信息节点 获取中断号 修改设备树文件 按键中断驱动程序编写 编写测试APP Linux中断API函数 先来回顾一下裸机实验里面中断的处理方法: 1.使能中断,初始化相应的寄存器。 2.注册中…

windows配置启动若依前后端项目

一、后端 1、环境准备 JDK8、Redis、Mysql、Maven【并配置镜像源】 以上工具全部使用msi/exe安装&#xff0c;并勾选添加到环境变量&#xff0c;如果没有添加到环境变量可以参考其他博主关于每种怎么配置的情况 mysql新增一个目录名为ry-vue的空数据库 2、前往若依官网下载…

MAC M1上docker rocketmq简单环境搭建和代码

工作了这么多年&#xff0c;rocketmq还没有用过&#xff0c;由于现在的工作中涉及到了&#xff0c;周六吃完午饭就开始搞&#xff0c;结果到现在3点钟才把环境弄好&#xff0c;测试代码搞起。 整个流程分成两步 安装简单的rocket环境起springboot项目测试 参考文章&#xff…

C++STL库常用库函数总结

文章目录 1.vector, 变长数组&#xff0c;倍增的思想 size() 返回元素个数empty() 返回是否为空clear() 清空front()/back() 访问第一个元素/最后一个元素push_back()/pop_back() 插入/弹出最后一个元素begin()/end() 开始元素迭代器/结尾元素迭代器[]支持…

【kafka面试题2】如何保证kafka消息的顺序性

【kafka面试题】如何保证kafka消息的顺序性 一、整体策略 如何保证kafka消息的顺序性呢&#xff0c;其实整体的策略就是&#xff1a;我们让需要有序的消息发送到同一个分区Partition。 为什么说让有序的消息发送到同一个分区Partition就行呢&#xff0c;&#xff0c;下面我们…

tidb之旅——生成列

作者&#xff1a; 有猫万事足 原文来源&#xff1a; https://tidb.net/blog/15d0fbf6 新的问题 之前弄好了TiDB集群&#xff0c;也弄好了dm集群&#xff0c;把写入流量整个切入了TiDB集群运行起来了。但是有个别比较大的日志表&#xff0c;OLAP查询的表现还是不太行。正好7…

Node中的模块引擎EJS

1.安装EJS 2.导入EJS const ejsrequire("ejs") 3.使用ejs渲染 let outer"法外狂徒" let resultejs.render(我是<%outer %>,{outer:outer}) let str我是<%outer %> let resultejs.render(str,{outer:outer}) 说明&#xff1a; 在模板中&#xf…

SpringBoot前后端分离项目,打包、部署到服务器详细图文流程

文章目录 实施步骤一、修改配置文件地址1.修改MySQL配置2.修改Redis配置3.修改日志路径和字符集配置 二、将源码压缩并上传服务器1.上传前端文件2.上传后端文件&#xff08;同上&#xff09; 三、前端项目打包1.安装依赖2.项目打包 四、后端项目打包1.项目打包&#xff08;jar包…

【软件架构设计】支持大规模系统的设计模式和原则

今天&#xff0c;即使是小型初创公司也可能不得不处理数 TB 的数据或构建支持每分钟&#xff08;甚至一秒钟&#xff01;&#xff09;数十万个事件的服务。所谓“规模”&#xff0c;通常是指系统应在短时间内处理的大量请求/数据/事件。 尝试以幼稚的方式实现需要处理大规模的服…

Linux(Ubuntu)+Qt+C++与OpenCV窗体程序使用

程序示例精选 Linux(Ubuntu)QtC与OpenCV窗体程序使用 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<Linux(Ubuntu)QtC与OpenCV窗体程序使用>>编写代码&#xff0c;代码整洁&am…

ChatGPT实战:短视频文案、脚本创作

你还在拼脑力输出视频脚本吗&#xff1f;AI时代&#xff0c;该提高提高生产力了&#xff0c;机器一天的视频出货量能赶上以往几个月的工作量&#xff0c;人力怎么可能卷的过机器&#xff1f; 使用ChatGPT创作视频脚本可以带来一些好处&#xff1a; 创意激发&#xff1a;ChatGPT…

ChatGPT爆火 但生成式AI并非全新产物

以ChatGPT、Midjourney 为代表的 AIGC 产品横空出世&#xff0c;在全球掀起新一轮的 AI 技术变革新浪潮。近二十年来&#xff0c;我们见证了从「机器学习」算法到「深度学习」&#xff0c;再到「基础模型」的发展。随着数据量大规模膨胀&#xff0c;可扩展的算力&#xff0c;再…

Android Glide预加载RecyclerViewPreloader,ViewPreloadSizeProvider,kotlin

Android Glide预加载RecyclerViewPreloader,ViewPreloadSizeProvider&#xff0c;kotlin implementation com.github.bumptech.glide:glide:4.15.1implementation ("com.github.bumptech.glide:recyclerview-integration:4.14.2") {// Excludes the support library …

Kafka的保姆级简易安装启动、关闭注意事项、简单使用

一.安装&#xff1a; 1.1Windows本机tar包安装 1.下载tar包 地址&#xff1a;Apache Download Mirrors&#xff0c;点击下面的连接先将tar包下载下来 2.解压到任意地址但自己要记得位置 3.进入到config文件找到server.properties更改信息 搜索&#xff0c;然后找到下面的地…

基于Spring Boot的广告公司业务管理平台设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的广告公司业务管理平台设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 后端&#xff1a;Java springboot框架 …