GitLab + Jenkins + Docker 实现 CI/CD 集成发布 - Go语言中文社区

GitLab + Jenkins + Docker 实现 CI/CD 集成发布


前言

        在没有持续集成持续发布之前,传统的开发模式是项目一开始就划分模块,等到所有代码开发完成之后再集成到一起进行测试,但是随着技术的发展,业务量不断增加,软件规模也在不断的扩大,单一的划分模块的方式就会出现特别多的问题,由于代码中的很多 Bug 在项目的早期就存在,等到最后集成测试的时候才发现问题,这样会导致开发者需要在集成阶段花费大量的时间去修改代码,再加上软件的复杂性短时间内很难定位错误位置,而持续集成的出现就可以消除这个弊端,下面来讲解什么是持续集成;

一、什么是持续集成?

        持续集成(Continuous integration,简称 CI)指的是,频繁的(一天多次)将代码集成到主干,如下图,程序员会将代码提交到代码仓库中,比如:GitHub、GitLab、Gitee等,提交到代码仓库之后通过集成工具(jenkins) 来将提交的代码拉取到集成机器当中,在集成机器上使用编译工具(maven/nodejs)对代码进行编译打包,通过将打好的包(jar/war)提交到需要部署的服务器运行打好的服务包实现交付,而每一次提交代码持续集成机器会通配置 Hook 来自动拉取代码,实现持续集成。

        持续集成的目的:就是让产品可以快速迭代,同时还能保持高质量,它的核心措施是,将代码集成到主干之前,必须通过自动化测试们只要有一个测试用例失败,就不能集成;

二、持续集成的流程

        下图为整个 CI/CD 的流程图,通过程序员提交代码到代码仓库,由代码仓库来管理程序员所提交的代码,通过 jenkins 服务器来讲代码拉取到本地,并使用 maven 工具对代码进行编译打包,并将打好的包发布到部署服务器并运行服务,下面则是整个构建流程:

1、提交(commit):流程的第一步,是开发者向代码仓库提交代码,所有后面的步骤都始于本地代码的第一次提交(commit)。

2、测试(test 第一轮):代码仓库对 commit 操作配置了钩子(hook),只要提交代码或者合并进主干,就会跑自动化测试;

3、构建(build):通过第一轮测试,代码就可以合并进主干,就算可以交付了,交付后先进行构建(build),再进入第二轮测试,所谓构建就是指的就是将源码转换为可以运行的实际代码,比如安装依赖,配置各种资源(样式表、JS脚本、图片)等。

4、测试(test 第二轮):构建完成,就要进行第二轮测试,如果第一轮已经涵盖了所有测试内容,第二轮可以省略,当然构建步骤也就需要移动到第一轮测试前面;

5、部署(deploy):过了第二轮测试,当前代码就是一个可以直接部署的版本(artifact),将这个版本的所有文件打包( tar filename.tar *)存档,发到生成服务器;

6、回滚(RollBACK):一旦当前版本发生问题,就要回滚到上一个版本的构建结果,最简单的做法就是修改以下符号链接,指向上一个版本的目录;

持续集成的好处:

1、降低风险,由于持续集成不断去构建,编译和测试,可以很早期发现问题,所以修复的代价就少;

2、对系统健康持续检查,减少发布风险带来的问题;

3、减少重复性工作;

4、持续部署,提供可部署但元包;

5、持续交付可提供使用的版本;

6、增强团队信心;

三、jenkins 持续集成工具

      Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成,在与 Oracle 发生争执后,项目从 Hudson 项目复刻。Jenkins 提供了软件开发的持续集成服务。它运行在 Servlet 容器中。它支持软件配置管理工具,可以执行基于 ApacheAnt 和 ApacheMaven 的项目,以及任意的 Shell 脚本和 Windows 批处理命令。Jenkins 的主要开发者是川口耕介。Jenkins 是在 MIT 许可证下发布的自由软件。。

1、开源的 Java 语言开发持续集成工具,支持持续集成,持续部署。

2、易于安装部署配置:可通过 yum 安装,或下载 war 包以及通过 docker 容器等快速实现安装部署,可方便 web 界面配置管理。

3、消息通知及测试报告:集成 RSS/E-mail 通过 RSS 发布构建结果或当构建完成时通过 e-mail通知,生成 JUnit/TestNG 测试报告。

4、分布式构建:支持 Jenkins 能够让多台计算机一起构建/测试。

5、文件识别: Jenkins 能够跟踪哪次构建生成哪些 jar,哪次构建使用哪个版本的 jar 等。

6、丰富的插件支持:支持扩展插件,你可以开发适合自己团队使用的工具,如git,svn,maven,docker 等。

四、CICD 实现容器化发布

1、在 GitLab 代码仓库创建两个项目一个前端(frontend)一个后端(backend微服务)

2、在 jenkins 创建一个项目 backend,并配置参数

//创建一个 Pipeline 流水线项目

 

//修改配置信息,添加字符参数 branch(分支)

 

//添加 project_name 参数

//添加 imagetag 参数

//添加 HarborUrl 参数

//添加应用实例端口

//添加 HarborPorject 参数

//添加 jenkinsfile 仓库存放路径,如果是 Pipeline Script 方式则不需要指定,在 jenkinsfile 当中存放了 CICD 的具体流程;

 

3、编写 backend 项目 Pipeline 流水线语法、Dockerfile、远程 shell 脚本,构建整个 CICD 的流程;

//编写 dockerfile,发布那个服务则在那个服务中编写 DockerFile

//编写 Pipline 流水线语法

node {
    def mvnHome
    stage('拉取代码') {
      checkout([$class: 'GitSCM', branches: [[name: '${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '9b66d573-ddc6-48a5-ab1d-49dd7acef029', url: '${gitaddress}']]])
    }
    stage('编译安装公共子工程 & 编译打包微服务') {
        // 编译安装应用服务
        sh "mvn -f tensquare_common clean install"
        // 编译构建应用服务
        sh "mvn -f ${project_name} clean package dockerfile:build"
    }
    stage('镜像打标签 & push 镜像到私仓') {
        // 定义镜像名称变量
        def ImageName = "${project_name}:${imagetag}"
        // 镜像打标签(将镜像格式打成私有仓库的标准)
        sh "docker tag ${project_name} ${HarborUrl}/${HarborProject}/${ImageName}"
 
        withCredentials([usernamePassword(credentialsId: '5a3ed4a6-6a8c-43f4-819b-dca89dee287d', passwordVariable: 'password', usernameVariable: 'username')]) {
            //登录 Harbor 仓库
            sh "docker login -u ${username} -p ${password} ${HarborUrl}"
            //上传镜像
            sh "docker push ${HarborUrl}/${HarborProject}/${ImageName}"
       }
    }
    stage('部署应用') {
        sshPublisher(publishers: [sshPublisherDesc(configName: 'master_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '/opt/jenkins_shell/deploy.sh $HarborUrl $HarborProject $project_name $imagetag $port ', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
 
    }
}

// 编写节点远程部署服务脚本(发布服务节点编写)

# 创建脚本路径
mkdir /opt/jenkins_shell

# 编写脚本内容
[root@localhost ~]# vim /opt/jenkins_shell/deploy.sh
#!/bin/bash

# 利用位置变量的形式将 jenkins 中定义的参数传入脚本当中
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5


# 定义上传 harbor 中 image 的名称
imageName=$harbor_url/$harbor_project_name/$project_name:$tag
echo "$imageName"

# 检测容器是否运行,如果运行则将其杀死,因为如果容器正在运行然后 jenkins 重新发布会导致容器运行冲突

containerId=`docker ps -a | grep -w ${project_name}:${tag} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
#停掉容器
docker stop $containerId
#删除容器
docker rm $containerId
echo "成功删除容器"
fi

# 检测镜像是否存在,如果存在则删除指定镜像,因为随着不断的构建每一次发布都会生成一个镜像占用系统空间,所以需要删除清空。
imageId=`docker images | grep -w $project_name | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
#删除镜像
docker rmi -f $imageId
echo "成功删除镜像"
fi

# 登录Harbor私服
docker login -u itcast -p Itcast123 $harbor_url
# 下载镜像
docker pull $imageName
# 启动容器
docker run -di -p $port:$port $imageName

4、将代码提交到 GitLab 仓库

//将 GitLab 仓库中的 tensquare_frontend 项目中的仓库地址加入到 IDEA 中,为了上传代码;

//将 GitLab 仓库中的 tensquare_backend 项目中的仓库地址加入到 IDEA 中,为了上传代码;

//提交代码到 backend 代码仓库

 

 //查看仓库中是否上传成功

 //提交代码到 frontend

5、在 jenkins 构建项目

 

 

 //在此处在构建过程中遇到了一个错误,查看报错

 //接下来去查看 Pipeline 中的语法

 // 提交代码再次构建查看运行结果,正常构建了;

 //查看整个代码运行流程

 //查看容器运行状态,是否发布成功

学习资料: https://pan.baidu.com/s/19kgxo54Aw1YkM-XzUqsuzw  提取码:u4gk

总结:本次简单的描述了一下 CICD 的发布流程,可以推荐 《 jenkins 2 权威指南》这本书,里面详细的介绍了 Pipeline 的语法以及更多的构建细节,包括 CICD 过程中遇到的各种打包问题的解决方案。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_45710286/article/details/125570401
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2023-01-02 20:37:16
  • 阅读 ( 444 )
  • 分类:docker

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢