GltLab持续集成发布(CI/CD)
一、 GitLab CI/CD 核心概念
首先,理解几个关键名词:
-
**CI - 持续集成**
* **核心**:开发者频繁地将代码集成到主干分支。
* **实践**:每次集成都通过自动化的构建和测试来验证,从而尽快发现错误。
* **好处**:减少集成问题,让团队更快地开发软件。
-
**CD - 持续交付/持续部署**
* **持续交付**:是 CI 的下一步。代码通过 CI 流程后,可以**一键手动**部署到生产环境。
* **持续部署**:是更自动化的持续交付。代码通过 CI 流程后,**自动**部署到生产环境。
* **区别**:部署到生产环境这一步是手动的还是自动的。
-
**GitLab Runner**
* **是什么**:一个用来执行 CI/CD **任务** 的轻量级、高可扩展的应用程序。
* **它在哪运行**:它可以运行在任何机器上——你的本地电脑、云服务器、Kubernetes 集群等。
* **作用**:它“监听” GitLab 实例,当有新的 CI/CD 任务(如代码推送)时,GitLab 会将任务分派给 Runner,Runner 则按照指令执行。
-
**Pipeline - 流水线**
* **是什么**:一次 CI/CD 执行的顶层结构。它定义了从构建、测试到部署的完整流程。
* **触发**:通常由代码推送(git push)或合并请求(Merge Request)触发。
-
**Stage - 阶段**
* **是什么**:Pipeline 中的一个逻辑分组,例如
build(构建)test(测试)deploy(部署)阶段。* **特点**:
\* 一个 Pipeline 可以包含多个 Stage。 \* \*\*Stage 是按顺序执行的\*\*,下一个 Stage 必须等上一个 Stage 的所有 Job 都成功后才能开始。 * 同一个 Stage 中的多个 Job 会*\*并行执行\*\*。 -
**Job - 任务**
* **是什么**:Stage 里的一个具体执行任务。它是 CI/CD 的最小执行单元。
* **例子**:在
test阶段,你可能会有unit-test(单元测试)integration-test(集成测试)等多个 Job。Job 里包含了真正要运行的*脚本**(script)。
-
**.gitlab-ci.yml 文件**
* **是什么**:GitLab CI/CD 的**配置文件**,位于项目的根目录。
* **作用**:它定义了 Pipeline 的结构和行为,包括有哪些 Stage,每个 Job 做什么。
* **没有这个文件,CI/CD 就不会工作**。
**关系总结**:
一个 **Pipeline** 由多个 **Stage** 组成,每个 **Stage** 包含多个 **Job**,而 **Job** 则由 **GitLab Runner** 来执行。所有这些都定义在 **.gitlab-ci.yml** 文件中。
二、 快速开始:一个完整的实战示例
假设我们有一个 Node.js 项目,我们来为它配置一个简单的 CI/CD 流程。
第一步:准备项目
在项目根目录创建一个 .gitlab-ci.yml 文件。
第二步:编写 .gitlab-ci.yml 配置文件
```yaml
1. 定义 Pipeline 有哪些阶段,按顺序执行
stages:
- install_deps
- test
- build
- deploy
2. 定义全局变量,可以被所有 Job 继承
variables:
NODE_VERSION: "18"
3. 缓存 node_modules,加速后续 Job 的执行
cache:
key: ${CI_COMMIT_REF_SLUG} # 使用分支名作为缓存 key
paths:
- node\_modules/
--- 第一个阶段:安装依赖 ---
install_dependencies:
stage: install_deps
image: node:$NODE_VERSION # 指定执行环境为 Node.js 官方镜像
script:
- npm install
artifacts: # 将 node_modules 传递给后续阶段
paths:
- node\_modules/
only: # 只有 master 分支和合并请求时触发此 Job
- master
- merge\_requests
--- 第二个阶段:运行测试 ---
run_unit_tests:
stage: test
image: node:$NODE_VERSION
script:
- npm run test
dependencies: # 显式声明依赖 install_dependencies Job 的 artifacts
- install\_dependencies
only:
- master
- merge\_requests
--- 第三个阶段:构建项目 ---
build_project:
stage: build
image: node:$NODE_VERSION
script:
- npm run build
artifacts: # 将构建产物(dist/)传递给后续阶段或提供下载
paths:
- dist/
dependencies:
- install\_dependencies
only:
- master
--- 第四个阶段:部署(示例:部署到服务器) ---
deploy_to_server:
stage: deploy
image: alpine:latest # 使用一个轻量级 Linux 镜像
before_script:
# 安装 SSH 密钥和 rsync(这里是最简示例,实际需配置 CI/CD Variables)
- apk add --no-cache openssh-client rsync
- eval \$(ssh-agent -s)
- echo "\$SSH\_PRIVATE\_KEY" | tr -d '\\r' | ssh-add -
- mkdir -p \~/.ssh
- chmod 700 \~/.ssh
script:
# 使用 rsync 同步文件到服务器
- rsync -avz --delete -e "ssh -o StrictHostKeyChecking=no" ./dist/ user@your-server.com:/path/to/www/
environment: # 定义部署环境
name: production
url: https://your-website.com
dependencies:
- build\_project
only:
- master # 只有推送到 master 分支才执行部署
```
第三步:配置 GitLab Runner
-
**获取注册令牌**:
* 进入你的 GitLab 项目页面。
* 进入
设置->CI/CD->Runner展开。* 在
“设置特定于项目的Runner”部分,找到“注册令牌”,复制它。 -
**安装并注册 Runner**(以在一台 CentOS/Ubuntu 服务器上为例):
```bash
下载 GitLab Runner 二进制文件 (Linux x64)
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
赋予执行权限
sudo chmod +x /usr/local/bin/gitlab-runner
创建一个 GitLab Runner 用户
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
安装并作为服务运行
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
开始注册流程
sudo gitlab-runner register
```
* 根据提示输入:
\* \*\*GitLab 实例 URL\*\*: `https://gitlab.com`(如果是私有化部署,则换成你的地址) \* \*\*注册令牌\*\*:刚才复制的令牌。 \* \*\*描述\*\*:给你的 Runner 起个名字,如 `my-project-runner`。 \* \*\*标签\*\*:可以给 Runner 打上标签,如 `node, linux`。在 `.gitlab-ci.yml` 中可以通过 `tags` 来指定由哪个 Runner 执行。 \* \*\*执行器\*\*:推荐使用 `docker`,因为它最干净。这里我们示例中使用 `shell`(更简单,但环境需自己准备)。 -
**配置 SSH 密钥(用于部署)**:
* 在运行 Runner 的机器上生成 SSH 密钥对
ssh-keygen -t rsa -b 4096 -C "gitlab-runner@server"* 将公钥
id_rsa.pub)添加到目标部署服务器的~/.ssh/authorized_keys文件中。* 在 GitLab 项目设置中,进入
设置->CI/CD->Variables展开。* 点击
“添加变量”:\* \*\*Key\*\*: `SSH_PRIVATE_KEY` \* \*\*Value\*\*: 复制刚才生成的\*\*私钥\*\*`id_rsa`)的\*\*全部内容\*\*。 \* \*\*勾选\*\* `“Mask variable”` 和 `“Protect variable”`(增强安全性)。
第四步:触发 Pipeline
完成以上步骤后,当你向 master 分支推送代码或者创建一个合并请求时,GitLab 会自动检测到 .gitlab-ci.yml 文件,并开始运行 Pipeline。
你可以在项目的 CI/CD -> Pipelines 页面查看运行状态和日志。
三、 .gitlab-ci.yml 常用关键字详解
* stages:定义 Pipeline 的阶段顺序。
* variables:定义环境变量。
* cache:缓存文件或目录,加速后续 Job。
* image:指定 Docker 镜像作为 Job 的运行环境。
**script:*必须**,由 Runner 执行的 Shell 脚本。
* before_script:在 script 之前执行,用于设置环境。
* after_script:在 script 之后执行,无论 Job 成功与否。
* artifacts:指定在 Job 成功时打包的文件/目录,传递给后续 Stage 或提供下载。
* dependencies:指定当前 Job 依赖哪个上游 Job 的 artifacts。
* only / except:控制 Job 在什么情况下运行(如特定分支、标签)。
**rules:*更强大和推荐**的替代 only/except 的规则系统,支持 ifchanges 等条件判断。
* tags:指定由哪个标签的 Runner 来执行此 Job。
* environment:定义部署目标环境。
* when:控制 Job 的运行时机,如 on_success(默认)on_failure, manual(手动触发)。
四、 最佳实践
- **保持 Pipeline 快速**:快速反馈是关键。优化测试和构建时间,使用缓存。
- **使用
rules代替only/except**rules更灵活,功能更强大。 - **利用缓存和 Artifacts**:避免重复工作,显著提升速度。
- **编写有意义的 Job 名称**:让日志更易读。
- **处理敏感信息**:**永远不要**将密码、密钥等写在
.gitlab-ci.yml文件里。始终使用 GitLab 的 **CI/CD Variables**。 - **从失败中学习**:仔细阅读 Job 日志,它是调试的最好朋友。
- **使用 Docker 镜像**:保证环境的一致性,避免“在我机器上是好的”问题。
通过这个教程,你应该已经对 GitLab CI/CD 的核心概念、配置方法和实战流程有了清晰的认识。现在就去你的项目中创建一个 .gitlab-ci.yml 文件开始实践吧!