前言
小编在实习过程中接触了 CI/CD 的知识,出于对这个知识点的极大的兴趣,小编想要进一步地学习一下这方面地知识点,所以想写一篇博客总结一下个人的学习心得。本文提供了 CI/CD 的相关概念 以及 GitLab CI/CD 的操作介绍,并分享了一些使用 GitLab 进行 CI/CD 进行实践的经验。如有描述不当地地方,还请留下您地高见,以免小编地文章给初学者带来误导。
什么是 CI/CD ?
CI/CD 代表一种软件开发和交付的实践方法, 是持续集成(Continuous Integration, CI) 、 持续交付(Continuous Delivery, CD)和 持续部署(Continuous Deployment, CD)的缩写。这些实践的核心思想是通过自动化和持续化的流程,确保代码的频繁集成、测试和部署,从而提高软件开发的效率和质量。
持续集成(Continuous Integration, CI)
定义:持续集成是一种开发实践,要求开发人员频繁地将代码集成到共享仓库中,并自动进行构建和测试,确保代码的正确性和稳定性。
目标:
- 尽早发现和解决问题,减少集成风险。
- 提高代码质量,确保代码的正确性和稳定性。
- 减少手动操作,提高开发效率。
持续交付(Continuous Delivery, CD)
定义:持续交付是在持续集成的基础上,自动将代码部署到生产环境或测试环境,确保代码可以随时发布。
目标:
- 确保代码可以随时发布,减少发布风险。
- 提高软件交付的速度和质量。
- 减少手动操作,提高开发效率。
持续部署(Continuous Deployment, CD)
定义:持续部署是在持续交付的基础上,自动将代码部署到生产环境,实现自动化的发布流程。
目标:
- 实现自动化的发布流程,减少发布风险。
- 提高软件交付的速度和质量。
- 减少手动操作,提高开发效率。
以下是官网的解释:
Why GitLab CI/CD ?
如今的 CI/CD 工具还是挺多的,不过小编在本文选择的是 GitLab 的 CI/CD 实现(小编实习公司内部也是使用的这个哈哈),主要有以下几方面的好处:
- 集成度高:GitLab CI/CD 是 GitLab 平台的一部分,与 GitLab 的代码管理、问题跟踪、代码审查等功能无缝集成,提供了一站式的 DevOps 解决方案。
- 易于使用:GitLab CI/CD 的配置简单,使用
.gitlab-ci.yml文件定义 CI/CD 流水线,易于理解和维护。 - 强大的功能:GitLab CI/CD 提供了丰富的功能,包括自动化构建、测试、部署、环境管理、缓存和依赖管理等。
- 灵活性:GitLab CI/CD 支持多种编程语言和平台,可以根据项目的需求灵活配置 CI/CD 流水线。
- 社区支持:GitLab 有一个活跃的社区,提供了大量的文档、教程和社区支持,方便用户学习和解决问题。
- 开源和免费:GitLab CI/CD 是开源的,可以免费使用,适合各种规模的团队和项目。
另外,小编对比总结了常用的几款 CI/CD 的工具,如下:
| 特性 | GitLab CI/CD | Jenkins | Travis CI | CircleCI | GitHub Actions |
|---|---|---|---|---|---|
| 集成度 | 与 GitLab 平台无缝集成 | 需要插件和自定义配置 | 与 GitHub 集成较好 | 与 GitHub 集成较好 | 与 GitHub 平台无缝集成 |
| 易用性 | 配置简单,使用 .gitlab-ci.yml 文件定义流水线 | 配置复杂,需要插件和自定义配置 | 配置简单,使用 .travis.yml 文件定义流水线 | 配置简单,使用 config.yml 文件定义流水线 | 配置简单,使用 workflow 文件定义流水线 |
| 功能 | 提供丰富的功能,包括自动化构建、测试、部署、环境管理等 | 功能强大,但需要插件和自定义配置 | 功能较为简单,适合开源项目 | 功能较为简单,适合开源项目 | 功能较为简单,适合开源项目 |
| 灵活性 | 支持多种编程语言和平台 | 支持多种编程语言和平台,但需要插件和自定义配置 | 支持多种编程语言和平台 | 支持多种编程语言和平台 | 支持多种编程语言和平台 |
| 社区支持 | 社区活跃,文档和教程丰富 | 社区非常活跃,文档和教程丰富 | 社区较为活跃,文档和教程较为丰富 | 社区较为活跃,文档和教程较为丰富 | 社区较为活跃,文档和教程较为丰富 |
| 开源和免费 | 开源和免费 | 开源和免费,但需要自托管 | 免费使用,但需要付费使用私有仓库 | 免费使用,但需要付费使用私有仓库 | 免费使用,但需要付费使用私有仓库 |
| 适用场景 | 适用于需要完整 DevOps 平台的团队 | 适用于需要高度自定义和灵活性的团队 | 适用于开源项目和简单的 CI/CD 需求 | 适用于开源项目和简单的 CI/CD 需求 | 适用于开源项目和简单的 CI/CD 需求 |
waht is GitLab CI/CD ?
那么, GitLab CI/CD 是什么呢?
GitLab CI/CD 是 GitLab 平台的一部分,提供了一站式的 DevOps 解决方案。以下是 GitLab CI/CD 的基本概念和详细说明:
1. 流水线(Pipeline)
定义:流水线是 GitLab CI/CD 的核心概念,表示一次完整的 CI/CD 流程。流水线由多个阶段(Stage)组成,每个阶段包含多个作业(Job)。
目标:流水线的目标是自动化构建、测试和部署代码,确保代码的正确性和稳定性。
关键步骤:
- 触发:流水线可以由代码提交、合并请求、定时任务等触发。
- 阶段:流水线由多个阶段组成,每个阶段包含多个作业。
- 作业:每个作业表示一个具体的任务,如构建、测试、部署等。
- 执行:流水线按照定义的顺序执行各个阶段的作业。
示例:
stages:
- build
- test
- deploy
build:
stage: build
script:
- npm install
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- npm install
- npm run test:unit
deploy:
stage: deploy
script:
- ssh user@your-server-ip "mkdir -p /var/www/html/cicd-test-demo"
- scp -r dist/* user@your-server-ip:/var/www/html/cicd-test-demo
environment:
name: production
url: http://your-domain.com
only:
- master
2. 阶段(Stage)
定义:阶段是流水线的一部分,表示一组相关的作业。流水线按照定义的顺序执行各个阶段。
目标:阶段的目标是将相关的作业分组,确保流水线的执行顺序和逻辑。
关键步骤:
- 定义阶段:在
.gitlab-ci.yml文件中定义阶段。 - 分组作业:将相关的作业分组到同一个阶段。
- 顺序执行:流水线按照定义的顺序执行各个阶段的作业。
示例:
stages:
- build
- test
- deploy
3. 作业(Job)
定义:作业是流水线的最小执行单元,表示一个具体的任务,如构建、测试、部署等。
目标:作业的目标是执行具体的任务,确保代码的正确性和稳定性。
关键步骤:
- 定义作业:在
.gitlab-ci.yml文件中定义作业。 - 指定阶段:指定作业所属的阶段。
- 定义脚本:定义作业的执行脚本。
- 指定触发条件:指定作业的触发条件,如分支、标签等。
示例:
build:
stage: build
script:
- npm install
- npm run build
artifacts:
paths:
- dist/
4. 触发器(Trigger)
定义:触发器是触发流水线的条件,如代码提交、合并请求、定时任务等。
目标:触发器的目标是自动触发流水线,确保代码的频繁集成和自动化测试。
关键步骤:
- 定义触发器:在
.gitlab-ci.yml文件中定义触发器。 - 指定触发条件:指定触发流水线的条件,如分支、标签等。
示例:
deploy:
stage: deploy
script:
- ssh user@your-server-ip "mkdir -p /var/www/html/cicd-test-demo"
- scp -r dist/* user@your-server-ip:/var/www/html/cicd-test-demo
environment:
name: production
url: http://your-domain.com
only:
- master
5. 环境(Environment)
定义:环境是作业部署的目标环境,如生产环境、测试环境等。
目标:环境的目标是确保代码部署到正确的环境中,减少部署风险。
关键步骤:
- 定义环境:在
.gitlab-ci.yml文件中定义环境。 - 指定环境名称:指定环境的名称。
- 指定环境 URL:指定环境的访问 URL。
示例:
deploy:
stage: deploy
script:
- ssh user@your-server-ip "mkdir -p /var/www/html/cicd-test-demo"
- scp -r dist/* user@your-server-ip:/var/www/html/cicd-test-demo
environment:
name: production
url: http://your-domain.com
6. 缓存(Cache)
定义:缓存是用于存储和重用构建和测试过程中生成的文件和依赖包的机制。
目标:缓存的目标是减少重复下载和构建的时间,提高 CI/CD 流水线的效率。
关键步骤:
- 定义缓存:在
.gitlab-ci.yml文件中定义缓存。 - 指定缓存路径:指定需要缓存的文件和目录路径。
示例:
cache:
paths:
- node_modules/
7. 制品(Artifacts)
定义:制品是作业生成的文件和目录,可以在后续的作业中使用。
目标:制品的目标是确保作业生成的文件和目录可以在后续的作业中使用,提高 CI/CD 流水线的效率。
关键步骤:
- 定义制品:在
.gitlab-ci.yml文件中定义制品。 - 指定制品路径:指定需要保存的文件和目录路径。
示例:
build:
stage: build
script:
- npm install
- npm run build
artifacts:
paths:
- dist/
制品可以简单理解为构建后的产物,比如下面的示例,下载产物之后可以直接运行,小编所在的实习公司有时候如果项目不是自动部署(CD)的话,必须要使用这个经过构建后的产物去通知运维部署,别问我为什么知道呜呜呜(被狠狠 diss 过了)...
8. 依赖(Dependencies)
定义:依赖是作业之间的依赖关系,确保作业按照定义的顺序执行。
目标:依赖的目标是确保作业按照定义的顺序执行,减少手动操作和等待时间。
关键步骤:
- 定义依赖:在
.gitlab-ci.yml文件中定义依赖。 - 指定依赖作业:指定依赖的作业名称。
示例:
deploy:
stage: deploy
script:
- ssh user@your-server-ip "mkdir -p /var/www/html/cicd-test-demo"
- scp -r dist/* user@your-server-ip:/var/www/html/cicd-test-demo
dependencies:
- build
总的来说,GitLab CI/CD 的基本概念包括流水线、阶段、作业、触发器、环境、缓存、制品和依赖等等。通过定义这些概念,可以配置自动化构建、测试和部署流水线,确保代码的正确性和稳定性,提高软件开发的效率和质量。每个概念都有其特定的目标和关键步骤,通过合理配置和使用这些概念,可以实现高效的 CI/CD 流程。
GitLab CI/CD 实践
准备条件:小编在这里使用的是阿里云的服务器,并且使用的是 FinalShell 连接的这个服务器,服务器的操作系统为 CentOS 7.6 64位, CPU&内存为 2核 4 GiB,
安装 gitlab-ce:
在服务器上配置 GitLab CI/CD 时,需要先安装 GitLab CE(GitLab Community Edition),因为 GitLab CE 是 GitLab CI/CD 的基础平台。GitLab CE 提供了代码管理、问题跟踪、代码审查等功能,而 GitLab CI/CD 是 GitLab CE 的一部分,用于自动化构建、测试和部署代码。
// 在FinalShell 终端一次执行如下命令即可
# 安装依赖包
yum -y install policycoreutils openssh-server openssh-clients postfix
# 安装 SELinux 管理工具
yum install policycoreutils-python
# 启动并启用 SSH 服务
systemctl enable sshd && sudo systemctl start sshd
# 启动并启用 Postfix 服务
systemctl enable postfix && systemctl start postfix
# 关闭防火墙
systemctl stop firewalld.service
# 安装 GitLab CE
wget --content-disposition https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-15.2.2-ce.0.el7.x86_64.rpm/download.rpm
# 将 RPM 包下载到本地,直接安装即可
yum install -y gitlab-ce-15.2.2-ce.0.el7.x86_64.rpm
修改默认端口(下面两张图标示了修改点):
cd /etc/gitlab
vi gitlab.rb
小编的服务器公网地址查看和服务器的配置:
重启配置:
gitlab-ctl reconfigure
gitlab-ctl restart
输入你的服务器地址加上刚刚配置的端口号即可访问:
GitLab初次安装后,初次登录GitLab网页的管理员账号和密码是什么?
大家参考这篇博客即可: GitLab初次安装后,登录GitLab网页的管理员账号和密码各是什么?
关键在于这个目录:
vi /etc/gitlab/initial_root_password
登录成功之后建议修改密码(因为密码有效期仅为24小时),点击右上角的 Edit profile选项再进行如下操作:
接着可以在上面关联一个你自己的项目仓库以供测试:
gitlab-runner 安装:
我们服务器是CentOS
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
安装:
sudo yum install gitlab-ci-multi-runner
gitlab-runner 注册:
获取gitlab-ci的Token: 项目主页 -> Sttings -> CI/CD -> Runners Expand
执行指令:按照提示输入上面的内容即可
gitlab-runner register
检查Run untagged jobs是否开启
以下是小编的一个配置:
由于小编要使用docker拉取node镜像,所以还需要安装docker并执行:
// 后续docker拉取镜像太慢的话可以更换源
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
接下来就是在我们关联的这个项目的根目录配置 .gitlab-ci.yml ,以下是小编的一个配置:
variables:
IMAGE_NODE: 'node:18.20.3' # 定义一个变量 IMAGE_NODE,值为 node:18.20.3 Docker 镜像
GIT_DEPTH: 100 # 定义一个变量 GIT_DEPTH,值为 100,用于设置 Git 克隆的深度
cache:
paths:
- ./node_modules # 缓存 node_modules 目录,以便在后续的 CI/CD 任务中重用依赖包
stages: # 定义 CI/CD 流水线的阶段
- build # 构建阶段
- deploy # 部署阶段
build-job: # 定义一个名为 build-job 的任务
tags:
- docker # 指定任务使用的 Runner 标签为 docker
stage: build # 指定任务的阶段为 build
image: node:latest # 使用 node 的最新版本 Docker 镜像
script:
- echo "Building the project..." # 打印构建信息
- npm install # 安装项目依赖
- npm run build # 执行打包命令
artifacts:
paths:
- dist/ # 将 dist 目录作为构建产物,保存到 artifacts 中
deploy-job: # 定义一个名为 deploy-job 的任务
tags:
- docker # 指定任务使用的 Runner 标签为 docker
stage: deploy # 指定任务的阶段为 deploy
image: alpine:latest # 使用 Alpine Linux 的最新版本 Docker 镜像
before_script: # 在执行 script 之前运行的脚本
- apk add --no-cache openssh-client # 安装 openssh-client 包
- eval $(ssh-agent -s) # 启动 ssh-agent
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - # 将 SSH 私钥添加到 ssh-agent
- mkdir -p ~/.ssh # 创建 ~/.ssh 目录
- chmod 700 ~/.ssh # 设置 ~/.ssh 目录的权限为 700
- ssh-keyscan 8.134.205.32 >> ~/.ssh/known_hosts # 将服务器的 SSH 公钥添加到 known_hosts
- chmod 644 ~/.ssh/known_hosts # 设置 known_hosts 文件的权限为 644
script:
- echo "Deploying the project..." # 打印部署信息
- ssh root@8.134.205.32 "mkdir -p /var/www/html/cicd-test" # 在服务器上创建目标目录
- scp -r dist/* root@8.134.205.32:/var/www/html/cicd-test # 将 dist 目录中的文件拷贝到服务器
dependencies:
- build-job # 指定 deploy-job 依赖于 build-job 的构建产物
only:
- master # 只在 master 分支有更改时触发部署
由于小编的流水线脚本使用了密钥,所以需要配置密钥,上面的流水线中的$SSH_PRIVATE_KEY其实是变量,具体可以参考:官方文档
ssh-keygen -t rsa -b 4096
//将以下输出的值作为下面第一张图的值,key为 SSH_PRIVATE_KEY,
// 导航到 `Settings` -> `CI/CD` -> `Variables`,添加 `SSH_PRIVATE_KEY` 变量
cat ~/.ssh/id_rsa
ps aux | grep ssh-agent
chmod 600 ~/.ssh/id_rsa
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
确保目标服务器的 SSH 配置允许使用公钥认证,
/etc/ssh/sshd_config
进去后修改(参考下面第二张图):
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
本地可以修改一下代码测试流水线,小编上面的 .gitlab-ci.yml 文件指定了只有master分支上才会触发流水线,可以根据需要进行配置,里面所有的配置都可以按照需求配置:
安装一个静态服务器,用来展示web页面
yum install httpd
httpd -v
因为gitlab已经占用了80端口
修改httpd配置文件的路径是/etc/httpd/conf/httpd.conf
所以这个httpd要改他的默认端口80为8000 (因为上面配置的gitlab-ce占用了80端口,同时确保服务器开放了8000端口)
启动http服务
service httpd start
yum install sshpass
配置 Apache 虚拟主机
sudo vi /etc/httpd/conf.d/cicd-test.conf
在文件中添加以下内容:
<VirtualHost *:8000>
ServerAdmin webmaster@example.com
DocumentRoot /var/www/html/cicd-test
ErrorLog /var/log/httpd/cicd-test-error.log
CustomLog /var/log/httpd/cicd-test-access.log combined
<Directory /var/www/html/cicd-test>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
vim /etc/ssh/ssh_config
修改以下两项配置
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
// 重启 `httpd` 服务
sudo systemctl restart httpd
接着输入你的服务器公网ip加上对应的端口号(小编上面使用的是8000)就可以直接访问了,到此就跑通这个流程了,以后每次更改后,合并到master再上传就会走CI/CD流程,是不是感觉挺方便的呢
结语
CI/CD 通过自动化和持续的流程,显著提高了软件开发的效率、质量和交付速度。它不仅减少了开发和部署过程中的错误和风险,还促进了团队协作和知识共享,最终提高了客户满意度。在现代软件开发中,CI/CD 已经成为不可或缺的一部分,帮助团队更快、更可靠地交付高质量的软件产品。
注:小编是在配置好之后再总结自己的实现过程,实践过程如有哪里不正确的话可以自行查阅资料,给您带来的不便之处尽请谅解谢谢
感谢您的阅读!!!