GitLab CI/CD 入门与实践

1,191 阅读16分钟

前言

小编在实习过程中接触了 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)

定义:持续部署是在持续交付的基础上,自动将代码部署到生产环境,实现自动化的发布流程

目标

  • 实现自动化的发布流程,减少发布风险。
  • 提高软件交付的速度和质量。
  • 减少手动操作,提高开发效率。

以下是官网的解释:

微信图片_20241021203135.png

Why GitLab CI/CD ?

如今的 CI/CD 工具还是挺多的,不过小编在本文选择的是 GitLab 的 CI/CD 实现(小编实习公司内部也是使用的这个哈哈),主要有以下几方面的好处:

  1. 集成度高:GitLab CI/CD 是 GitLab 平台的一部分,与 GitLab 的代码管理、问题跟踪、代码审查等功能无缝集成,提供了一站式的 DevOps 解决方案。
  2. 易于使用:GitLab CI/CD 的配置简单,使用 .gitlab-ci.yml 文件定义 CI/CD 流水线,易于理解和维护。
  3. 强大的功能:GitLab CI/CD 提供了丰富的功能,包括自动化构建、测试、部署、环境管理、缓存和依赖管理等。
  4. 灵活性:GitLab CI/CD 支持多种编程语言和平台,可以根据项目的需求灵活配置 CI/CD 流水线。
  5. 社区支持:GitLab 有一个活跃的社区,提供了大量的文档、教程和社区支持,方便用户学习和解决问题。
  6. 开源和免费:GitLab CI/CD 是开源的,可以免费使用,适合各种规模的团队和项目。

另外,小编对比总结了常用的几款 CI/CD 的工具,如下:

特性GitLab CI/CDJenkinsTravis CICircleCIGitHub 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)

目标流水线的目标是自动化构建、测试和部署代码,确保代码的正确性和稳定性

关键步骤

  1. 触发:流水线可以由代码提交、合并请求、定时任务等触发。
  2. 阶段:流水线由多个阶段组成,每个阶段包含多个作业。
  3. 作业:每个作业表示一个具体的任务,如构建、测试、部署等。
  4. 执行:流水线按照定义的顺序执行各个阶段的作业。

示例

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)

定义:阶段是流水线的一部分,表示一组相关的作业。流水线按照定义的顺序执行各个阶段。

目标阶段的目标是将相关的作业分组,确保流水线的执行顺序和逻辑

关键步骤

  1. 定义阶段:在 .gitlab-ci.yml 文件中定义阶段。
  2. 分组作业:将相关的作业分组到同一个阶段。
  3. 顺序执行:流水线按照定义的顺序执行各个阶段的作业。

示例

stages:
  - build
  - test
  - deploy

3. 作业(Job)

定义作业是流水线的最小执行单元,表示一个具体的任务,如构建、测试、部署等。

目标:作业的目标是执行具体的任务,确保代码的正确性和稳定性。

关键步骤

  1. 定义作业:在 .gitlab-ci.yml 文件中定义作业。
  2. 指定阶段:指定作业所属的阶段。
  3. 定义脚本:定义作业的执行脚本。
  4. 指定触发条件:指定作业的触发条件,如分支、标签等。

示例

build:
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/

4. 触发器(Trigger)

定义触发器是触发流水线的条件,如代码提交、合并请求、定时任务等

目标:触发器的目标是自动触发流水线,确保代码的频繁集成和自动化测试。

关键步骤

  1. 定义触发器:在 .gitlab-ci.yml 文件中定义触发器。
  2. 指定触发条件:指定触发流水线的条件,如分支、标签等。

示例

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)

定义环境是作业部署的目标环境,如生产环境、测试环境等

目标:环境的目标是确保代码部署到正确的环境中,减少部署风险。

关键步骤

  1. 定义环境:在 .gitlab-ci.yml 文件中定义环境。
  2. 指定环境名称:指定环境的名称。
  3. 指定环境 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 流水线的效率

关键步骤

  1. 定义缓存:在 .gitlab-ci.yml 文件中定义缓存。
  2. 指定缓存路径:指定需要缓存的文件和目录路径。

示例

cache:
  paths:
    - node_modules/

7. 制品(Artifacts)

定义:制品是作业生成的文件和目录,可以在后续的作业中使用。

目标:制品的目标是确保作业生成的文件和目录可以在后续的作业中使用,提高 CI/CD 流水线的效率。

关键步骤

  1. 定义制品:在 .gitlab-ci.yml 文件中定义制品。
  2. 指定制品路径:指定需要保存的文件和目录路径。

示例

build:
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/

制品可以简单理解为构建后的产物,比如下面的示例,下载产物之后可以直接运行,小编所在的实习公司有时候如果项目不是自动部署(CD)的话,必须要使用这个经过构建后的产物去通知运维部署,别问我为什么知道呜呜呜(被狠狠 diss 过了)...

微信图片_20241021205952.png

8. 依赖(Dependencies)

定义:依赖是作业之间的依赖关系,确保作业按照定义的顺序执行。

目标:依赖的目标是确保作业按照定义的顺序执行,减少手动操作和等待时间。

关键步骤

  1. 定义依赖:在 .gitlab-ci.yml 文件中定义依赖。
  2. 指定依赖作业:指定依赖的作业名称。

示例

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

微信图片_20241021212529.png

微信图片_20241021213048.png

小编的服务器公网地址查看和服务器的配置:

微信图片_20241021212838.png

重启配置:

gitlab-ctl reconfigure
gitlab-ctl restart

输入你的服务器地址加上刚刚配置的端口号即可访问:

微信图片_20241021213839.png

GitLab初次安装后,初次登录GitLab网页的管理员账号和密码是什么?

大家参考这篇博客即可: GitLab初次安装后,登录GitLab网页的管理员账号和密码各是什么?

关键在于这个目录:

vi /etc/gitlab/initial_root_password

微信图片_20241021214342.png

登录成功之后建议修改密码(因为密码有效期仅为24小时),点击右上角的 Edit profile选项再进行如下操作:

微信图片_20241021214552.png

接着可以在上面关联一个你自己的项目仓库以供测试:

微信图片_20241021220301.png

gitlab-runner 安装:

参考 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

微信图片_20241021221026.png

执行指令:按照提示输入上面的内容即可
gitlab-runner register

参考:Gitlab-ci:从零开始的前端自动化部署

微信图片_20241021221822.png

检查Run untagged jobs是否开启

微信图片_20241021222428.png

微信图片_20241021222432.png

以下是小编的一个配置:

微信图片_20241021224652.png

由于小编要使用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

微信图片_20241021232054.png

微信图片_20241021232108.png

本地可以修改一下代码测试流水线,小编上面的 .gitlab-ci.yml 文件指定了只有master分支上才会触发流水线,可以根据需要进行配置,里面所有的配置都可以按照需求配置:

微信图片_20241021234827.png

安装一个静态服务器,用来展示web页面

yum install httpd
httpd -v

因为gitlab已经占用了80端口
修改httpd配置文件的路径是/etc/httpd/conf/httpd.conf
所以这个httpd要改他的默认端口808000 (因为上面配置的gitlab-ce占用了80端口,同时确保服务器开放了8000端口)

启动http服务
service httpd start
yum install sshpass

微信图片_20241021235638.png

配置 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 已经成为不可或缺的一部分,帮助团队更快、更可靠地交付高质量的软件产品。

注:小编是在配置好之后再总结自己的实现过程,实践过程如有哪里不正确的话可以自行查阅资料,给您带来的不便之处尽请谅解谢谢

感谢您的阅读!!!