Jenkins配置CI/CD开发环境(理论到实践的完整流程)

目录

一、对于CI/CD的理解

CI/CD 是 Continuous Integration(持续集成)和 Continuous Delivery(持续交付)或 Continuous Deployment(持续部署)的缩写。这两者都是现代软件开发实践中的重要组成部分,主要用于提高软件开发的速度和质量。

1.1、什么是CI(持续集成)

持续集成(Continuous Integration, CI) 是指开发人员将代码频繁地(如每天多次)合并到共享的代码仓库中。每次代码合并后,都会通过自动化构建和测试,以确保新代码与现有代码的兼容性。

1.2、CI 的主要特点:

  • 代码合并频繁:开发人员将自己的修改合并到主分支时,立即进行自动化的构建和测试。
  • 自动化测试:每次代码变更后,都会自动运行单元测试和集成测试,确保新代码不会破坏已有功能。
  • 快速反馈:当新代码引入了错误,CI 系统会及时通知开发人员,从而使他们能够迅速修复问题。
  • 减少集成风险:通过频繁的小规模集成,减少了在发布时进行大规模集成的风险。

1.3、CI 的优势:

  • 提高代码质量:通过自动化测试和代码审查工具,提升代码质量和稳定性。
  • 降低合并冲突:开发人员频繁提交代码,降低了大规模合并时出现冲突的风险
实际开发中的场景举例:

例如:项目A有个test分支

开发小王:从master生产分支切一个bug_123分支,来修改bug,修改完成后合并到test分支。

开发小李:也从master生产分支切一个bug_456分支,来修改bug,修改完成后合并到test分支。

此时小王和小李都需要把test分支的代码部署到测试环境,让测试人员进行测试。

传统的操作:

小王和小李沟通谁去打包test分支,把包上传服务器,启动服务。

使用持续集成后:

开发只需要关注代码开发,并提交代码到test分支,后续的打包、上传、启动服务都可以交由持续集成系统来完成。

自动构建一般情况下有两种触发方式:

第一种是某个代码分支设置钩子,一旦检测到该分支有新的提交,持续集成系统就自动拉取最新代码进行打包部署。(这种情况从预发环境到生产环境的自动构建部署用的比较多)

第二种情况,在持续集成系统中配置一个任务,当需要部署的时候,直接一键构建并部署。(这种情况测试环境用的比较多)

1.4、什么是 CD(持续交付和持续部署)

持续交付(Continuous Delivery, CD) 和 持续部署(Continuous Deployment, CD) 是基于 CI 之上的进一步扩展,用于自动化软件的交付和发布。

1.5、持续交付(Continuous Delivery)

持续交付 是指在代码通过自动化测试后,能够自动构建并准备好随时部署到生产环境。虽然交付过程是自动化的,但最终是否部署到生产环境通常是由人工决定的。

自动化发布流程:持续交付确保每次代码变更都经过构建、测试和打包,并可以通过人工触发快速地部署到生产环境。

可控发布:可以选择何时将经过验证的代码发布到生产环境中。

目的是保持代码随时可发布:持续交付的目标是确保主分支始终处于可部署状态,以便快速响应业务需求。

1.6、持续部署(Continuous Deployment)

持续部署 是持续交付的进一步发展,指的是在通过所有自动化测试后,代码会自动部署到生产环境中,无需人工干预。

完全自动化:从代码提交、测试到生产环境的发布全部自动化。

快速迭代:每次代码变更都能够直接交付给最终用户,使新功能和修复迅速上线。

高要求:持续部署需要非常高的自动化测试覆盖率和质量,确保每次变更都不会引入问题。

1.7、CI/CD 流程示意

一个典型的 CI/CD 流程可以包含以下几个步骤:

  • 1、代码提交(Commit):开发人员将新代码提交到版本控制系统(如 Git)。

  • 2、持续集成(CI):

    代码构建(Build):CI 工具(如 Jenkins、GitLab CI、GitHub Actions 等)自动触发构建脚本,将代码打包成可执行文件。

    自动化测试(Test):运行单元测试、集成测试、静态代码分析等。

    反馈结果(Feedback):如果构建或测试失败,CI 工具会立即通知开发人员。

  • 3、持续交付/持续部署(CD):

    自动化部署(Deploy):在测试通过后,将构建的产物部署到测试环境或预生产环境。

    人工确认(在持续交付时):人工确认后部署到生产环境。

    自动化发布(在持续部署时):自动将变更部署到生产环境中。

1.8、总结:

CI/CD 的核心理念在于"自动化"与"频繁交付",它帮助开发团队在保证质量的前提下,快速迭代和发布软件。CI 通过自动化测试确保每次代码变更的稳定性,而 CD 则让代码随时可部署甚至自动部署到生产环境,最终实现快速响应业务需求和用户反馈。

CI/CD能减少了手动测试和部署的时间,使开发人员能够专注于编写代码。提高团队的项目交付效率。

提高代码质量和稳定性:自动化测试和代码审查能够在早期阶段发现问题,降低了缺陷进入生产环境的风险。

缩短交付周期:通过自动化的构建和部署流程,可以更快地将新功能或修复交付给用户。

降低发布风险:每次发布的改动量较小,即使出现问题,回滚也更加简单和安全。

大部分小公司可能开发和运维工作都是同一个人完成,这种情况下CI/CD的好处就更加明显了,可以大幅减轻开发人员的工作量(当然前期配置CI/CD环境对于开发人员来说也是个不小的挑战)。

二、CI/CD 工具

2.1、一些常见的 CI/CD 工具包括:

  • Jenkins:一个流行的开源自动化服务器,支持各种插件,用于构建、测试、和部署。
  • GitLab CI/CD:与 GitLab 深度集成的 CI/CD 工具,适用于 DevOps 流程。
  • GitHub Actions:GitHub 提供的 CI/CD 服务,便于在 GitHub 项目中构建自动化工作流。
  • CircleCI、Travis CI、Azure DevOps、Bamboo 等也是一些常见的 CI/CD 工具。

三、Jenkins 能做什么,可以带来哪些好处?

3.1、Jenkins 能做什么:

  • ①、自动化构建和编译

    代码构建:Jenkins 可以在开发人员提交代码后,自动执行构建脚本,编译代码并打包成可执行文件(如 JAR、WAR、Docker 镜像等)。

    多语言支持:支持 Java、Python、Node.js、Go 等多种编程语言的构建。

  • ②、自动化测试

    单元测试:自动运行单元测试,确保代码基本功能的正确性。

    集成测试:在代码合并到主分支之前运行集成测试,验证不同模块间的协作是否正常。

    UI 和功能测试:结合 Selenium 等工具,自动执行前端 UI 测试和 API 测试,确保用户功能的正确性。

  • ③、持续集成与持续交付(CI/CD)

    持续集成:在开发人员提交代码后,自动触发构建和测试,确保代码在合并之前稳定可靠。

    持续交付/部署:Jenkins 可以将构建后的产物自动部署到测试环境、预生产环境,甚至生产环境中,实现快速发布。

  • ④、配置管理与基础设施自动化

    基础设施即代码(IaC,Infrastructure as Code):通过集成 Terraform、Ansible 等工具,Jenkins 可以自动化管理云端资源的配置与部署。

    环境配置:自动化管理应用所需的环境配置,如数据库迁移、服务启动等。

  • ⑤、监控和通知

    监控构建状态:通过 Web 界面实时查看构建、测试和部署的状态,并生成报告。

    通知集成:支持将构建结果通过邮件、Slack、钉钉等渠道通知到相关人员,确保团队对项目状态及时知悉。

  • ⑥、自定义插件支持

    丰富的插件生态:Jenkins 拥有大量插件,支持与各种版本控制系统(如 Git、SVN)、云服务(如 AWS、Azure)、构建工具(如 Maven、Gradle)、容器(如 Docker、Kubernetes)等集成。

    扩展性:可以根据团队的特定需求开发自定义插件,以满足特殊的自动化流程。

3.2、Jenkins 带来的好处:

  • ①、提高开发效率

    自动化流程:通过自动化代码构建、测试和部署,开发人员不再需要手动执行这些重复性操作,能够专注于编写和优化代码。

    快速反馈:Jenkins 可以在每次代码提交后自动运行测试,并即时反馈测试结果,帮助开发人员尽早发现问题并进行修复。

  • ②、提高代码质量和稳定性

    自动化测试保障质量:Jenkins 通过自动化测试,能够在每次构建时验证代码的功能和性能,降低缺陷进入生产环境的风险。

    持续集成减少集成风险:频繁的小规模集成能够减少开发人员之间的冲突,使代码合并变得更顺畅。

  • ③、 加快交付速度

    持续交付和部署:通过自动化的部署流水线,可以更快地将新功能、修复或优化版本交付到生产环境中。

    支持多环境发布:可以轻松地部署到开发环境、测试环境和生产环境,从而加快测试和上线流程。

  • ④、 提高透明度和协作性

    可视化构建过程:Jenkins 的控制台和报告功能让团队可以直观地看到每个阶段的状态,构建失败的原因、测试报告等。

    团队协作:通过自动化通知和报告,团队成员可以更快地了解项目进展情况,促进协作和沟通。

  • ⑤、 降低发布风险

    蓝绿发布和回滚:通过与 Kubernetes 等容器编排工具的集成,可以实现蓝绿发布、金丝雀发布等部署策略,从而在发布时确保系统的稳定性。

    自动化回滚:在遇到问题时,可以自动执行回滚流程,将服务恢复到先前的稳定状态。

⑥、 支持多平台部署

跨平台兼容性:Jenkins 支持在 Windows、Linux 和 macOS 上运行,因此可以方便地在不同操作系统上进行构建和部署。

容器化支持:与 Docker、Kubernetes 等工具的深度集成,使得 Jenkins 在构建容器镜像、管理容器编排方面也得心应手。

3.3、总结

Jenkins 作为自动化服务器,不仅能够简化开发流程,还能显著提高代码的质量和交付速度。它通过自动化构建、测试、部署等环节,使团队能够更高效地开发和发布软件,减少手动操作和人为错误。同时,Jenkins 丰富的插件生态和强大的自定义能力,使其能够适应各种规模和复杂度的项目需求,是现代 DevOps 实践中不可或缺的工具之一。

============ 下面进入实践部分 ===============

四、安装Jenkins和所需插件

安装环境Linux:

shell 复制代码
# 查看操作系统
cat /etc/os-release
# 查看处理器架构
uname -m

我自己装的虚拟机:

操作系统:CentOS7

处理器: x86-64架构

生产环境:

操作系统:Red Hat Enterprise Linux 8.10

处理器: x86-64架构

还包括CentOS8 都可以用下面的方式部署。

4.1、列出下面所需软件和下载地址

这里统一放网盘里了,方便一键下载。

基本都是tar.gz格式压缩包,直接使用 tar -zxvf 压缩包名称 解压即可。

下面也都给出了官方的下载地址。

shell 复制代码
yum install -y git
  • ⑤、NVM+Node
    NVM直接从Github下载解压即可(使用的版本0.38.0)
shell 复制代码
wget https://github.com/nvm-sh/nvm/archive/refs/tags/v0.38.0.tar.gz

nvm解压后,运行下这个命令使nvm生效 source ~/.bashrc

Node直接使用NVM下载管理:

下面简单列出几个nvm使用的命令

shell 复制代码
# 列出可用的Node版本
nvm ls available

# 安装14.21.3版本(我这个是比较老的依赖Node.js打包的前端项目,所以用的这个版本的Node)
nvm install 14.21.3

# 使用 某个版本的Node
nvm use 14.21.3

# 列出已下载的Node
nvm ls

推荐把Node包管理器的下载地址修改为淘宝的镜像,这样执行npm install命令的时候下载的比较快。

shell 复制代码
# 设置Node包管理器的包下载地址镜像为最新的淘宝镜像
npm config set registry https://registry.npmmirror.com

# 查看镜像地址
npm config get registry

到这基本上所需的软件都准备好了。

安装都比较简单,直接解压即可。都不用配置环境变量。

因为Jenkins中我们会配置maven和Git的安装目录。

JDK11在启动Jenkins的war包时也会指定JDK11安装目录中的jdk命令。

(这样做的目的是为了节省资源,因为这台机器已经安装了JDK8的环境,并且配置了环境变量,我们再安装一个JDK11仅仅是为了运行Jenkins的war包,我们通过Jenkins构建完成的jar或者war还在本机的JDK8环境下运行)。

这里启动Jenkins的命令如下:

shell 复制代码
# JDK11 解压目录是/web   
# Jenkins的war包位置是/web/jenkins2.432/  
# Jenkins日志位置  /web/jenkins2.432/log/info.log
nohup /web/jdk11/bin/java -jar /web/jenkins2.432/jenkins.war  --prefix=/jenkins  > /web/jenkins2.432/log/info.log 2>&1 &

查看Jenkins启动日志

shell 复制代码
tail -200f /web/jenkins2.432/log/info.log 2>&1 &

上面启动命令加了--prefix=/jenkins 配置了上下文访问路径/jenkins ,这样方便后期配Nginx代理。

建议上面的软件都安装在统一的目录下。

浏览器输入http://ip:8080/jenkins

上面的ip替换成你部署jenkins的实际机器ip。

Jenkins第一次启动的时候 会在日志里打印一个字符串用于第一次进入系统时输入验证。

这个在启动日志里面有。

查看Jenkins启动日志(按照上面的启动命令启动)

shell 复制代码
tail -200f /web/jenkins2.432/log/info.log 2>&1 &

然后保证你的Jenkins机器能联外网。直接选安装推荐的插件。(我安装的这个版本Jenkins,目前不会出现插件版本不兼容的问题)

等待插件安装完毕。(按道理来说应该没问题,这个版本算是比较新的不会有插件不兼容的问题)

如果插件安装失败,可以重试几次。

如果仍然失败,可以修改插件下载地址的镜像。重新安装尝试。

再不行就去官网下载插件上传安装(有时候一个插件依赖很多个插件,所以这种方式会比较麻烦)。
再不行可以参考这篇文章

4.2、配置Jenkins

4.2前提是 4.1中的软件都安装完毕。

下面开始配置 Maven、JDK、Git

注意这里配置的JDK是给Jenkins执行构建任务使用的,我们上面下载的JDK11是给Jenkins启动使用的。

①、配置Maven

如果你的插件都安装成功,会有一个汉化插件的,如果没有也可以手动去安装汉化插件。

去系统管理->插件管理 搜索 Chinese 安装即可。

下面配置Maven

进入全局工具配置:

Maven很简单,就配置Maven的settings文件路径和Maven的安装路径即可,setting文件里面配置远程Maven仓库地址,和本地仓库目录地址(这个根据自己项目需求配置)

我的Maven安装在 /web/maven 目录下 就配这个目录

②、配置JDK

上面我们安装的JDK11只是给jenkins启动用的, 我机器中还有一个JDK8,这里打包和运行构建的应用使用的JDK我配置的是JDK8

也很简单 直接配置JDK8的安装目录

③、配置Git

上面我的Git是使用yum安装的,看下目录在哪

shell 复制代码
whereis git

输出 /usr/bin/git

那么Git 就配置这个地址 /usr/bin/git

配置到这就ok了。

五、新增自动构建任务

5.1、新增自动构建任务-后端

任务:自动构建并部署Springboot后端项目

先列好需要让Jenkins做的事情:

①、Jenkins本身运行在 A机器,让Jenkins从我们指定的Git地址上拉取代码,切换到指定的分支。

②、使用Maven进行打包,这里我打的是jar包(你也可以打war包或者构建docker镜像,视项目需求而定)

③、将构建好的jar,复制到机器B

④、在机器B执行脚本,停止正在运行的jar,启动新的jar。

大致上就上面4步。

现在一步一步来操作:

①、

新建一个freestyle类型的任务

写个描述

然后选择丢弃旧的构建。这样节省空间,如果空间充足或者在生产环境使用,建议设置保留一周。

②、

配置构建步骤

这里构建的是一个结构比较简单的Maven项目,

如果是父子项目结构,这里的目标 需要输入的指令要再复杂些。

简单的Maven项目直接输入 clean package -DskipTests 即可

表示 先clean 再 跳过测试 直接打包 如果maven本地仓库已经全了 也可以再加一个 -o参数 表示离线打包这样更快

clean package -DskipTests -o

备注:配置Linux机器间的免密复制,免密登录

③、如何把构建好的jar包从机器A,传到机器B呢?

这里提供两个思路

思路一、机器A使用NFS共享jenkins的工作目录,机器B挂载 机器A的jenkins工作目录。

思路二、配置远程免密登录、使用scp 远程复制命令

由于第四步还要远程执行脚本,所以这里就利用思路二实现。

对思路一感兴趣的可以参考 我的这篇文章 Linux系统使用NFS挂载共享目录

现在按照思路二,配置免密登录:

这里用服务器A,和服务器B举例:

先看下服务器A scp输入密码远程复制行不行:

先使用scp命令看下

shell 复制代码
scp a.txt  root@192.168.220.220:/root/a.txt

下面221和220是我在本地演示配置免密登录 克隆的两个虚拟机。

可以看到现在是需要输入密码的,输入密码后可以成功copy

如果你输入密码也不能成功copy,就需要在B服务器开启一个配置

shell 复制代码
vi /etc/ssh/sshd_config
# 配置 PasswordAuthentication yes

保存

然后重启 sshd服务

shell 复制代码
service sshd restart

当验证好了scp命令可用之后在进行下列配置。

我就直接用root用户生成密钥对了

先在A机器生生密钥对

shell 复制代码
# -P "" 表示不设置密码
ssh-keygen -t rsa -P ""

会让你选择在哪里生成,就用默认的就好,直接回车

A机器的密钥对就生成好了。

上面生成的.ssh目录是隐藏 ,需要使用cd /root/.ssh 进入后 才能看到里面的密钥对

shell 复制代码
cd /root/.ssh
ll

其中id_rsa 是私钥,id_rsa.pub是公钥。

把公钥id_rsa.pub copy到服务器B上,也就是右边的服务器

这里我就使用scp 输入密码的方式copy了,你也可以先下载下来,再登录服务器B的FTP服务上传。

shell 复制代码
scp id_rsa.pub  root@192.168.220.220:/root/id_rsa.pub

然后进入服务器B的 /root目录下

可以看到刚才复制的服务器A的公钥

下面在服务器B也生成密钥对:

shell 复制代码
# -P "" 表示不设置密码
ssh-keygen -t rsa -P ""

此时把刚刚复制过来的A服务器的公钥里面的内容 追加到 服务器B 的 /root/.ssh/authorized_keys 文件中

shell 复制代码
cd /root
cat id_rsa.pub >> /root/.ssh/authorized_keys

看下服务器B 的authorized_keys的内容:

shell 复制代码
cat .ssh/authorized_keys

这个时候在A机器上 再用scp复制一个文件到B机器看看

shell 复制代码
cd ~
touch b.txt
scp b.txt  root@192.168.220.220:/root/b.txt


可以看到不用输入密码就复制成功了。

也可以在A机器 使用ssh 命令 直接登录B机器

shell 复制代码
ssh 192.168.220.220
ip a

至此 免密复制scp 和免密登录 ssh 都配置好了

如果还有其他机器需要配置参照上面配置即可,例如机器C也想免密登录机器B,把机器C的公钥追加到机器B的 authorized_keys文件后面即可。

④、下面我们再配置构建完成后的脚本就行了

shell 复制代码
#!/bin/bash
echo '复制MyApp.jar到192.168.222.222'
scp /root/.jenkins/workspace/app/target/MyApp.jar  root@192.168.222.222:/root/app/MyApp.jar
echo '复制MyApp.jar到192.168.222.222 完成'

# 使用 ssh 远程执行一系列命令
echo '启动MyApp.jar'
ssh root@192.168.222.222 << EOF
mv /root/app/MyApp.jar /service/nacos-jar/
pkill -9 -f MyApp.jar
nohup java -Xms2g -Xmx2g -Xmn1g -jar /service/nacos-jar/MyApp.jar --spring.config.additional-location=file:/service/nacos-jar/bootstrap.properties  > /data/nacos-jar/logs/MyApp/info.log 2>&1 &
echo '启动完成,等待应用启动...'
# 轮询检查日志文件中是否包含"Started IbmpApplication"
LOG_FILE="/data/nacos-jar/logs/MyApp/info.log"
while ! grep -q "Started MyApp" \$LOG_FILE; do
  sleep 5
  echo '应用正在启动...'
done

echo '应用启动成功,查看进程'
ps aux | grep MyApp
EOF

echo 'Jenkins 构建任务完成'

脚本内ip、和应用名称已做处理。

大概解释下上面的脚本,把Jenkins构建完成的jar包远程复制到服务器192.168.222.222的/root/app/MyApp.jar位置。

使用ssh免密登录192.168.222.222,在192.168.222.222机器上执行脚本,杀掉MyApp进程,把新的jar替换,重启新的jar

然后每5秒查询一下jar的日志中启动完成的标记。检查到启动完成后,该任务执行完毕。

上面就是一个最简单的后端构建任务。

5.2、新增自动构建任务-前端

前提,Node环境已配置好。

整体比后端还要简单些。

先列好需要让Jenkins做的事情:

①、Jenkins本身运行在 A机器,让Jenkins从我们指定的Git地址上拉取代码,切换到指定的分支。

②、使用Node进行打包

③、将构建好的前端文件,复制到Nginx所在机器指定目录,覆盖原文件即可

新建freestyle任务

写个描述、勾上丢弃旧的构建

配置Git地址、用户名密码(或者秘钥)、指定分支。

直接在Build Steps里面 配置脚本,进行前端的构建 然后删除原前端文件,复制新打包的文件。

脚本

shell 复制代码
echo  '开始构建'
cd /root/.jenkins/workspace/MyApp前端/ui/web
npm install
npm run package:MyApp-prod
rm -rf /service/MyApp-saas/saas-gateway-ui/MyApp/*
cp -r /root/.jenkins/workspace/MyApp前端/ui/web/dist/*  /service/MyApp-saas/saas-gateway-ui/MyApp/

由于Nginx和Jenkins部署在同一台机器,这里的删除和复制就没有使用远程ssh 在另一台机器执行脚本了。

所以这个前端的脚本搞得比较简单。

上面就是最简单的前端自动构建配置。

备注:Nginx配置Jenkins的反向代理

上面说了Jenkins启动的时候加了上下文访问路径 --prefix=/jenkins ,假如部署jenkins的机器ip是 192.168.220.220

那么我们就可以使用http://192.168.220.220:8080/jenkins 来访问了。

如果不想每次都输入8080端口,就可以使用nginx做反向代理。

shell 复制代码
location /jenkins/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

还是建议启动服务的时候配一下上下文访问路径,这样配置nginx反向代理比较简单,不会出那么多坑,否则配置反向代理很可能出现静态资源无法加载的情况。

配置好后,reload一下nginx的配置文件即可,然后就可以使用http://192.168.220.220/jenkins来访问了,前提nginx要监听80端口。

六、总结

有了Jenkins的安装配置基础、Linux远程操作的基础之后,再去配置各种复杂的构建就有头绪了,当然Jenkins还有很多强大的功能值得探索,由于篇幅有限,后续再另写博客进行学习。

希望对你配置CI/CD环境有所帮助。

相关推荐
传而习乎26 分钟前
Linux:CentOS 7 解压 7zip 压缩的文件
linux·运维·centos
soulteary28 分钟前
突破内存限制:Mac Mini M2 服务器化实践指南
运维·服务器·redis·macos·arm·pika
运维&陈同学2 小时前
【zookeeper01】消息队列与微服务之zookeeper工作原理
运维·分布式·微服务·zookeeper·云原生·架构·消息队列
是阿建吖!2 小时前
【Linux】进程状态
linux·运维
明明跟你说过2 小时前
Linux中的【tcpdump】:深入介绍与实战使用
linux·运维·测试工具·tcpdump
Mr_Xuhhh3 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
朝九晚五ฺ11 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
Kkooe12 小时前
GitLab|数据迁移
运维·服务器·git
久醉不在酒12 小时前
MySQL数据库运维及集群搭建
运维·数据库·mysql
虚拟网络工程师14 小时前
【网络系统管理】Centos7——配置主从mariadb服务器案例(下半部分)
运维·服务器·网络·数据库·mariadb