DevOps——CI/CD持续集成与持续交付/部署的理解与部署
导引:什么是DevOps?
简单来说,DevOps 不是单一工具或技术,而是 “开发(Development)” 和 “运维(Operations)” 两个角色的融合,核心目标是让软件从代码编写到最终上线的整个流程更快速、更稳定、更自动化。
DevOps 的核心价值
- 打破部门壁垒:让开发和运维团队从 “各司其职” 变成 “协同工作”,减少沟通成本和责任推诿。
- 自动化流程:通过工具将代码构建、测试、部署等重复工作自动化,减少人工操作和错误。
- 快速反馈与迭代:缩短软件交付周期,让新功能或 bug 修复能更快上线,同时通过监控快速发现并解决问题。
DevOps 的关键实践
- 持续集成(CI):开发人员频繁将代码提交到共享仓库,通过工具自动构建和测试,确保代码合并后能正常运行。
- 持续部署 / 交付(CD):通过自动化流程将测试通过的代码部署到生产环境(持续部署)或准备好部署(持续交付),实现 “代码提交即上线” 的可能。
- 基础设施即代码(IaC):用代码来定义和管理服务器、网络等基础设施,替代手动配置,确保环境一致性。
- 监控与日志:实时监控软件运行状态和基础设施性能,通过日志快速定位问题,形成 “发现问题 - 解决问题 - 优化” 的闭环。
本文以下就是介绍什么CI/CD持续集成与持续交付/部署的实现与部署
一 什么是CI/CD?

CI/CD 是指持续集成(Continuous Integration)和持续部署(Continuous Deployment)或持续交付(Continuous Delivery)
1.1 持续集成(Continuous Integration)
持续集成是一种软件开发实践,团队成员频繁地将他们的工作集成到共享的代码仓库中。其主要特点包括:
- 频繁提交代码:开发人员可以每天多次提交代码,确保代码库始终保持最新状态。
- 自动化构建:每次提交后,自动触发构建过程,包括编译、测试、静态分析等。
- 快速反馈:如果构建失败或测试不通过,能够快速地向开发人员提供反馈,以便及时修复问题。
1.2 持续部署(Continuous Deployment)
持续部署是在持续集成的基础上,将通过所有测试的代码自动部署到生产环境中。其特点如下:
- 自动化流程:从代码提交到生产环境的部署完全自动化,无需人工干预。
- 高频率部署:可以实现频繁的部署,使得新功能能够快速地提供给用户。
- 风险控制:需要有强大的测试和监控体系来确保部署的稳定性和可靠性。
1.3 持续交付(Continuous Delivery)
持续交付与持续部署类似,但不一定自动部署到生产环境,而是随时可以部署。其重点在于确保软件随时处于可发布状态。
CI/CD 的好处包括:
- 提高开发效率:减少手动操作和等待时间,加快开发周期。
- 尽早发现问题:通过频繁的集成和测试,问题能够在早期被发现和解决。
- 降低风险:减少了大规模部署时可能出现的问题,提高了软件的质量和稳定性。
- 增强团队协作:促进团队成员之间的沟通和协作,提高团队的整体效率。
常见的 CI/CD 工具包括 Jenkins、GitLab CI/CD、Travis CI 等。这些工具可以帮助团队实现自动化的构建、测试和部署流程。
二 git工具使用

2.1 git简介
Git 是一个分布式版本控制系统,被广泛用于软件开发中,以管理代码的版本和变更。
主要特点:
- 分布式
- 每个开发者都有完整的代码仓库副本,这使得开发者可以在离线状态下进行工作,并且在网络出现问题时也不会影响开发。
- 即使中央服务器出现故障,开发者仍然可以在本地进行开发和查看项目历史。
- 高效的分支管理
- Git 中的分支创建和切换非常快速和简单。开发人员可以轻松地创建新的分支来进行新功能的开发或修复 bug,而不会影响主分支。
- 合并分支也相对容易,可以使用多种合并策略来满足不同的需求。
- 快速的版本回退
- 如果发现某个版本存在问题,可以快速回退到之前的版本。
- 可以查看每个版本的详细变更记录,方便了解代码的演进过程。
- 强大的提交管理
- 每个提交都有一个唯一的标识符,可以方便地引用和查看特定的提交。
- 提交可以包含详细的提交信息,描述本次提交的更改内容。
- 支持协作开发
- 开发者可以将自己的更改推送到远程仓库,供其他开发者拉取和合并。
- 可以处理多个开发者同时对同一文件进行修改的情况,通过合并冲突解决机制来确保代码的完整性。
Git必看秘籍:https://git-scm.com/book/zh/v2
2.2 git 工作流程

Git 有三种状态:已提交(committed)、已修改(modified) 和 已暂存(staged)。
- 已修改表示修改了文件,但还没保存到数据库中。
- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交表示数据已经安全地保存在本地数据库中。
这会让我们的 Git 项目拥有三个阶段:工作区、暂存区以及 Git 目录。
三 部署git
部署git有两步
第一步就是安装git,许多linux默认源都带有git包
第二步就是对目录的初始化为本地的版本控制仓库
3.1 安装git
[root@gitlab ~]# dnf install git -y#补全命令
[root@gitlab ~]# echo "source /usr/share/bash-completion/completions/git" >> ~/.bashrc
[root@gitlab ~]# source ~/.bashrc
3.2 初始化
#创建工作目录
[root@gitlab ~]# mkdir fjw
[root@gitlab ~]# cd fjw/#将一个普通的目录初始化为 Git 版本控制仓库
[root@gitlab fjw]# git init
[root@gitlab fjw]#ls -a
. .. .git
#需要配置git的全局用户信息才能提交到仓库,不然只能放在暂存区
[root@gitlab fjw]# git config --global user.name "fjw"
[root@gitlab fjw]# git config --global user.email "fjw@fjwyyy.org"

四 git的使用
4.1 常用示例
#创建未提交的文件
[root@gitlab fjw]# echo hello world > test
[root@gitlab fjw]# git status -s #-s 简要查看
?? test #?? 新建文件未添加到暂存区与版本库#添加到暂存区
[root@gitlab fjw]# git add test
[root@gitlab fjw]# git status -s
A test #A 表示被添加到暂存区#提交暂存区的数据
[root@gitlab fjw]# git commit -m "add test"
[master ba59c4f] add test1 file changed, 1 insertion(+)create mode 100644 test
[root@gitlab fjw]# git status -s #无任何显示,标识已经提交到版本库#再次修改
[root@gitlab fjw]# echo hello linux >> test
[root@gitlab fjw]# cat test
hello world
hello linux
[root@gitlab fjw]# git status -sM test #右M 表示文件在工作区被修改#撤销修改
[root@gitlab fjw]# git checkout -- test
[root@gitlab fjw]# git status -s
[root@gitlab fjw]# cat test
hello world#重新修改
[root@gitlab fjw]# echo hello linux >> test
[root@gitlab fjw]# git status -sM test
[root@gitlab fjw]# git add test
[root@gitlab fjw]# git status -s
M test #左M表示文件已经在版本库中并被跟踪#从暂存区撤销
[root@gitlab fjw]# git status -s
M test
[root@gitlab fjw]# git restore --staged test
[root@gitlab fjw]# git status -sM test #要想撤销要一步步撤销#更新
[root@gitlab fjw]# git status -sM test#先修改后,再提交就是更新
[root@gitlab fjw]# git add test
[root@gitlab fjw]# git status -s
M test
[root@gitlab fjw]# git commit -m "update v1"
[master f81a97e] update v11 file changed, 1 insertion(+)
[root@gitlab fjw]# git status -s#更新文件
[root@gitlab fjw]# echo hello redhat >> test
[root@gitlab fjw]# cat test
hello world
hello linux
hello redhat
[root@gitlab fjw]# git status -sM test
[root@gitlab fjw]# git add test
[root@gitlab fjw]# git status -s
M test
[root@gitlab fjw]# echo hello centos >> test
[root@gitlab fjw]# git status -s
MM test #MM表示有一部分在暂存区,还有一部分没有提交#如果现在提交只能提交在暂存区中的部分
[root@gitlab fjw]# git commit -m "update v2"
[master d29fbd8] update v21 file changed, 1 insertion(+)
[root@gitlab fjw]# git status -sM test #右M还在#查看已暂存和未暂存的修改变化
[root@gitlab fjw]# git diff
diff --git a/test b/test
index c7a5e25..f86806e 100644
--- a/test
+++ b/test
@@ -1,3 +1,5 @@hello worldhello linuxhello redhat
+hello centos
+hello RHCE #+表示未提交到暂存区#跳过使用暂存区,只能在提交过的在版本库中存在的文件使用如果文件状态是“??”不能用此方法
[root@gitlab fjw]# git status -sM test
[root@gitlab fjw]# git commit -a -m "update v3"
[master 5b2f010] update v31 file changed, 2 insertions(+)
[root@gitlab fjw]# git diff
[root@gitlab fjw]# git status -s #原来的右M没了直接被提交了不用先上传到暂存区#撤销工作区中的删除动作
[root@gitlab fjw]# touch fjw.txt
[root@gitlab fjw]# git add fjw.txt
[root@gitlab fjw]# git status -s
A fjw.txt
[root@gitlab fjw]# git commit -m "add fjw.txt"
[master 0ecc859] add fjw.txt1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 fjw.txt
[root@gitlab fjw]# ls
fjw.txt fy test
[root@gitlab fjw]# rm -rf fjw.txt
[root@gitlab fjw]# git status -sD fjw.txt #右D表示文件在工作区被删除
[root@gitlab fjw]# git checkout -- fjw.txt #撤销在工作区删除的文件
[root@gitlab fjw]# git status -s
[root@gitlab fjw]# ls
fjw.txt test#从版本库中删除文件
[root@gitlab fjw]# git rm fjw.txt
rm 'fjw.txt'
[root@gitlab fjw]# git status -s
D fjw.txt #左D表示文件删除动作被提交到暂存区
[root@gitlab fjw]# git commit -m "delete fjw.txt" #把从版本库删除的文件重新提交
[master c9a688c] delete fjw.txt1 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 fjw.txt
[root@gitlab fjw]# git status -s#一步步提交到版本库到撤销回工作区
[root@gitlab fjw]# touch yyy.txt
[root@gitlab fjw]# git add yyy.txt
[root@gitlab fjw]# git commit -m "add yyy.txt"
[master c52c228] add yyy.txt1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 yyy.txt
[root@gitlab fjw]# git rm yyy.txt
rm 'yyy.txt'
[root@gitlab fjw]# git status -s
D yyy.txt
[root@gitlab fjw]# git restore --staged yyy.txt
[root@gitlab fjw]# git status -sD yyy.txt
[root@gitlab fjw]# git checkout -- yyy.txt
[root@gitlab fjw]# git status -s#恢复从版本库中被删除的文件
[root@gitlab fjw]# git log #查看操作日志
[root@gitlab fjw]# git reflog #查看提交动作
c52c228 (HEAD -> master) HEAD@{0}: commit: add yyy.txt
c9a688c HEAD@{1}: commit: delete fjw.txt
0ecc859 HEAD@{2}: commit: add fjw.txt
5b2f010 HEAD@{3}: commit: update v3
d29fbd8 HEAD@{4}: commit: update v2
f81a97e HEAD@{5}: commit: update v1
ba59c4f HEAD@{6}: commit: add test
6bd2bcc HEAD@{7}: commit (initial): v1#版本回退到删除之前
[root@gitlab fjw]# git reset --hard 0ecc859
HEAD is now at 0ecc859 add fjw.txt
4.2 git对于文件如何忽略
在做软件开发时对源码编译会产生一些临时文件,我们在提交时需要忽略这些临时文件
#一般以.开头的隐藏文件
[root@gitlab fjwyyy]# vim .test
[root@gitlab fjwyyy]# git status -s
?? .test#可以编写.gitignore文件来把.开头的前缀
[root@gitlab fjwyyy]# echo ".*" > .gitignore
[root@gitlab fjwyyy]# git status -s#也可以指定文件
[root@gitlab fjwyyy]# echo ".test" > .gitignore
[root@gitlab fjwyyy]# git status -s
?? .gitignore
五 gitlab代码仓库
5.1 gitlab简介
在部署gitlab之前我们先了解gitlab是什么
- GitLab 是一个用于仓库管理系统的开源项目,使用 Git 作为代码管理工具,并在此基础上搭建起来的 web 服务。
- GitLab 具有很多功能,比如代码托管、持续集成和持续部署(CI/CD)、问题跟踪、合并请求管理等。它可以帮助开发团队更好地协作开发软件项目,提高开发效率和代码质量。
一般我们使用gitlab实现CI,CD一般搭配Jenkins下面会提到如何结合Jenkins
实际上,大家都使用过github吧,gitlab就相当于我们本地的github,把我们编写好的代码文件上传到我们的本地的github也就是gitlab
下面是gitlab的官网与获取方式
官网:https://about.gitlab.com/install/ #官方需要梯子才能正常访问
中文站点: https://gitlab.cn/install/ #中文站点广告比较多
官方包地址:https://packages.gitlab.com/gitlab/gitlab-ce
打开官方包地址

可以使用wget获取安装包下来
5.2 部署gitlab
#安装依赖性
[root@gitlab ~]# dnf install -y curl policycoreutils-python-utils openssh-server perl #安装安装包
[root@gitlab ~]# dnf install gitlab-ce-17.1.6-ce.0.el9.x86_64.rpm -y
......
It looks like GitLab has not been configured yet; skipping the upgrade script.*. *.*** ******** *****.****** *************** ********,,,,,,,,,***********,,,,,,,,,,,,,,,,,,,,*********,,,,,,,,,,,.,,,,,,,,,,,*******,,,,,,,,,,,,,,,,,,,,,*****,,,,,,,,,.,,,,,,,****,,,,,,.,,,***,,,,,*,._______ __ __ __/ ____(_) /_/ / ____ _/ /_/ / __/ / __/ / / __ `/ __ \/ /_/ / / /_/ /___/ /_/ / /_/ /\____/_/\__/_____/\__,_/_.___/Thank you for installing GitLab!
......
#安装成功会显示这个图案
5.3 配置gitlab
[root@gitlab fjwyyy]# cd /etc/gitlab/
[root@gitlab gitlab]# ls
gitlab.rb
[root@gitlab gitlab]# vim gitlab.rb
32 external_url 'http://172.25.254.50' #修改访问gitlab的网址,原本是解析#修改配置文件后需利用gitlab-crt来生效
[root@gitlab gitlab]# gitlab-ctl reconfigure#执行命令成功后会把所有组件全部启动起来
5.4 登录gitlab
#查看原始密码
[root@gitlab gitlab]# cat /etc/gitlab/initial_root_password
# WARNING: This value is valid only in the following conditions
# 1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
# 2. Password hasn't been changed manually, either via UI or via command line.
#
# If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.Password: 80ntNg1tgqkf3wiPIdEFeTMvQAEz3d5EyTbYUZJQ7WA= #密码# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours. #处于安全原因,密码会24小时更改一次
#登录

[!CAUTION]
注意:出于安全原因,24 小时后,
/etc/gitlab/initial_root_password会被第一次gitlab-ctl reconfigure自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码。
#登录后修改密码
先设置语言


更改密码


修改完密码后会要求重新登录
5.5 在gitlab中新建项目
在浏览器访问主机IP





#生成sshd密钥
[root@gitlab ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:fkBvkP3mEMqgG+1y7jmuFeg9FaXkSRY+FlszD8Yek2g root@gitlab.fy.org
The key's randomart image is:
+---[RSA 3072]----+
| *+B. |
| *E@== |
| ..&.oo. |
| + = *.o |
| + o S + o |
| . = + o + |
| + * . . . |
| =.o . |
| .+=. |
+----[SHA256]-----+
[root@gitlab ~]# cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC/9wRDJF7fuuIELe7LrQDramGsBcuD7Nt7hl9UZWDMRZ3F4DmuSDZHklhc3OhyXZn/686NVCLXBLaH0IBz/BIWMw5OM81OT2/GqF7YwUR1M+nV4oEmA4Y0QB8lpHz4LABtQSnpMKJ2bIza8B/uSDdQFhThQgJWOxRIePnGbQ9vC6i/mzThL6x+0hbb4m2igelr6x+1Ybmcb8tChNgtANNYOrNox5G44wnDaAAfBFx9NGBHPMR5ZgI440HTxeg1unD2AQOh0MrYbz4seTWPCQNYw8uUfTAM2Pe3R5gQ+A+z1rcybUGdIQUhq2xAeItua82hJnwnV5GFBSeDYAEfiztJg4oadadAV6UHdaxdIf87o7+OMgHNPr6B/bVu+UrXgr5uw7lRJFzeMFlMYI750cB5pOnsgEZzR28fZK8h+avP6+PGicgIMPLSw0bQjAPfOC6KUHxkuaidSA2H8vLocniI++PTDsAoi6mafJwhoO9D2rODDwQyLQuehZKEdMX2Xi0= root@gitlab.fy.org
#上传公钥到gitlab中,不然不能推送或拉取镜像

#下载项目
[root@gitlab mnt]# git clone git@172.25.254.50:root/fjwyyy.git
Cloning into 'fjwyyy'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (3/3), done.#提交项目到gitlab中
[root@gitlab mnt]# ls
fjwyyy
[root@gitlab mnt]# cd fjwyyy/
[root@gitlab fjwyyy]#
[root@gitlab fjwyyy]# echo hello world > test
[root@gitlab fjwyyy]# git add test
[root@gitlab fjwyyy]# git status -s
A test
[root@gitlab fjwyyy]# git commit -m "add test"
[main 98637f2] add test1 file changed, 1 insertion(+)create mode 100644 test
[root@gitlab fjwyyy]# git push -u origin main
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 271 bytes | 271.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To 172.25.254.50:root/fjwyyy.git552f973..98637f2 main -> main
branch 'main' set up to track 'origin/main'.#更新项目再次推送
[root@gitlab fjwyyy]# echo hello linux >> test
[root@gitlab fjwyyy]# git status -sM test
[root@gitlab fjwyyy]# git commit -a -m "update v1"
[main 8c36b72] update v11 file changed, 1 insertion(+)
[root@gitlab fjwyyy]# git push -u origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 282 bytes | 282.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To 172.25.254.50:root/fjwyyy.git98637f2..8c36b72 main -> main
branch 'main' set up to track 'origin/main'.
#查看提交到仓库的项目

六 Jenkins
6.1 Jenkins简介

- Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要。
- Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行
CI(Continuous integration持续集成)持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。

CD(Continuous Delivery持续交付) 是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中

6.2 部署Jenkins
软件下载:https://www.jenkins.io/download/
- 安装jenkins与依赖包
#安装依赖包
#由于Jenkins是由java开发的
[root@jenkins ~]# dnf install fontconfig java-21-openjdk -y#安装jenkins
[root@jenkins ~]# dnf install jenkins-2.476-1.1.noarch.rpm
- 查看Jenkins的登录密码并安装插件
#启动Jenkins
[root@jenkins mnt]# systemctl enable --now jenkins.service
[root@jenkins mnt]# netstat -antlupe | grep java #开启的是8080端口
tcp6 0 0 :::8080 :::* LISTEN 980 59978 32984/java#查看密码
[root@jenkins mnt]# cat /var/lib/jenkins/secrets/initialAdminPassword
6292e45a05ab4c819a419614666c1315
- 打开浏览器访问





到这里就部署成功啦

建议修改admin的密码,在admin的设置中修改即可
6.3 Jenkins与gitlab整合



#Jenkins主机也要下载git工具
[root@jenkins jenkins]# dnf install git -y

设置密钥免询问yes/no


#在Jenkins上生成免密公钥私钥
[root@jenkins jenkins]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:kfEMA9IfmeOB8i5q5QuuI79wauIhYhfn92Px/EcibaM root@jenkins.fjwyyy.org
The key's randomart image is:
+---[RSA 3072]----+
| ...o+o |
| ..o *B |
| o oo+o |
| . o. |
| . o S . |
| * . . . = . |
|+oo= o . + + + |
|B*=.. . .o E . |
|B*+... ... ... |
+----[SHA256]-----+
如何查看生成的公钥与私钥


然后在Jenkins上添加私钥凭证来解gitlab的公钥






可以每分钟查看构建情况或者手动构建


6.4 Jenkins中gitlab触发器部署
在 Jenkins 中配置 GitLab 触发器可以实现代码提交或合并请求时自动触发 Jenkins 流水线
这样就不用等1分钟一次或者更长时间,也不用手动去构建,当代码提交后就会自动构建
6.4.1 安装插件
如果需要使用gitlab触发器需要安装gitlab插件。目前使用官方源下载比较吃力,可以直接本地部署插件即可


如果网络条件允许可以下载,不行的话就使用本地部署

本地部署


6.4.2 部署自动触发

点击后再点击高级生成凭证

复制令牌去gitlab添加网络钩子






6.4.3 测试自动触发
[root@gitlab ~]# cd /mnt/fjwyyy/
[root@gitlab fjwyyy]# echo hello test > test
[root@gitlab fjwyyy]# git commit -a -m 'testfile v1'
[root@gitlab fjwyyy]# git push -u origin main

