gitLab CI/CD 执行流程说明

CI/CD 执行流程说明

描述 GitLab CI/CD 从代码提交到流水线完成的完整执行过程,以及 Docker 容器的创建与管理机制。


整体架构

复制代码
┌─────────────────────────────────────────────────────────┐
│                    Windows 宿主机                        │
│                                                         │
│  ┌──────────────┐    ┌──────────────┐                   │
│  │ Docker Desktop│    │ Git Bash     │                   │
│  │  (WSL2)      │    │ (git push)   │                   │
│  └──────┬───────┘    └──────┬───────┘                   │
│         │                   │                           │
│  ┌──────┴───────────────────┴──────────────────────┐    │
│  │              Docker Engine                       │    │
│  │                                                  │    │
│  │  ┌─────────┐  ┌─────────────┐                   │    │
│  │  │ GitLab  │  │ GitLab      │                   │    │
│  │  │ (CE)    │◄─┤ Runner      │                   │    │
│  │  │ :8090   │  │ (常驻进程)   │                   │    │
│  │  └─────────┘  └──────┬──────┘                   │    │
│  │                      │                           │    │
│  │         为每个 Job 动态创建容器 ▼                  │    │
│  │                                                  │    │
│  │  ┌─────────────────┐  ┌─────────────────────┐   │    │
│  │  │ 辅助容器         │  │ 构建容器             │   │    │
│  │  │ (predefined)    │  │ (python:3.11-slim)  │   │    │
│  │  │ git clone       │  │ pytest / pylint     │   │    │
│  │  │ 缓存恢复/保存    │  │ bandit / claude     │   │    │
│  │  │ artifact 上传   │  │                     │   │    │
│  │  └─────────────────┘  └─────────────────────┘   │    │
│  └──────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────┘

一、触发流程

复制代码
开发者提交代码 (git push)
        │
        ▼
GitLab 接收 push 事件
        │
        ▼
解析 .gitlab-ci.yml
        │
        ▼
创建 Pipeline(流水线)
        │
        ▼
按阶段创建 Job(任务)

触发条件

事件 触发行为
git push 到任意分支 创建完整 Pipeline
创建 Merge Request 触发 MR Pipeline
手动触发(Web/API) 指定分支创建 Pipeline

二、流水线阶段

复制代码
Pipeline #47 (main 分支)
│
├─ Stage 1: test / code-quality / security  ← 并行执行 (needs: [])
│   ├─ Job: run_tests        (47s)
│   ├─ Job: code_quality     (54s)
│   └─ Job: security_scan    (49s)
│
├─ Stage 2: review
│   └─ Job: claude_review    (24s)  ← AI 代码审查
│
├─ Stage 3: deploy
│   └─ Job: deploy           (12s)  ← 打包部署
│
└─ 总耗时: 163 秒

阶段执行规则

规则 说明
同阶段内 needs: [] 表示并行,否则按顺序执行
跨阶段 上一阶段全部完成后才启动下一阶段
allow_failure: true Job 失败不阻塞流水线(code-quality、security、review)
rules 控制 Job 是否创建(如 deploy 只在主分支执行)

三、Docker 容器生命周期

每个 Job 的容器创建过程

run_tests 为例:

复制代码
时间线(约 70 秒)
│
│  ┌─ 辅助容器启动 (predefined)
│  │  镜像: gitlab-runner-helper
│  │  大小: ~30MB
│  │
│  │  任务:
│  │  ├─ 1. 准备执行环境
│  │  │     - 创建 /builds/lizhihua/calculator 目录
│  │  │     - 设置环境变量
│  │  │
│  │  ├─ 2. Git Clone
│  │  │     - git fetch origin
│  │  │     - git checkout <commit-sha>
│  │  │     - 耗时: ~3 秒
│  │  │
│  │  ├─ 3. 恢复缓存
│  │  │     - 从 Docker volume 提取 .cache/pip
│  │  │     - 命中缓存时 pip install 从 30s 降到 5s
│  │  │     - 耗时: ~1 秒
│  │  │
│  │  └─ 4. 准备构建容器
│  │        - 拉取 python:3.11-slim(首次约 124MB)
│  │        - 后续使用本地缓存(pull_policy: if-not-present)
│  │
│  ├─ 构建容器启动 (build)
│  │  镜像: python:3.11-slim
│  │  大小: ~124MB
│  │
│  │  任务:
│  │  ├─ 执行 before_script
│  │  │     - python --version
│  │  │     - pip install pytest pytest-cov
│  │  │
│  │  └─ 执行 script
│  │        - pytest test_calculator.py -v --cov
│  │        - 输出测试报告、覆盖率
│  │
│  └─ 辅助容器再次介入
│     ├─ 保存缓存 (.cache/pip → Docker volume)
│     ├─ 上传 artifacts (report.xml, coverage.xml)
│     └─ 清理临时文件
│
│  容器自动退出(Exited 0)

容器命名规则

复制代码
runner-zapabj0l-project-14-concurrent-0-3aafad579f0e50e5-predefined
  │       │           │         │          │                      │
  │       │           │         │          │                      └─ 辅助容器标识
  │       │           │         │          └─ Job 唯一哈希
  │       │           │         └─ 并发槽位 (0, 1, 2)
  │       │           └─ 项目 ID (14 = calculator)
  │       └─ Runner Token 哈希
  └─ 固定前缀

容器清理

Job 完成后容器自动退出,不会自动删除(保留用于调试)。可通过以下方式清理:

bash 复制代码
# 清理已退出的容器
docker container prune -f

# Runner 配置中启用自动清理
# /etc/gitlab-runner/config.toml
[runners.docker]
  disable_cache = true
  shm_size = 0

四、Runner 配置说明

当前配置 (/etc/gitlab-runner/config.toml)

toml 复制代码
concurrent = 3              # 最大并发 Job 数
request_concurrency = 4     # 同时向 GitLab 请求 Job 的数量
check_interval = 0          # 轮询间隔(0 = 默认)

[[runners]]
  name = "Docker CI Runner"
  url = "http://192.168.1.130:8090"
  executor = "docker"       # 使用 Docker 执行器
  clone_url = "http://192.168.1.130:8090"  # Git clone 地址

  [runners.docker]
    image = "python:3.11-slim"          # 默认镜像
    pull_policy = ["if-not-present"]    # 本地有就不拉取
    privileged = false                  # 不启用特权模式
    volumes = ["/cache"]                # 挂载缓存目录

关键配置项

配置 当前值 说明
concurrent 3 最多同时运行 3 个 Job
pull_policy if-not-present 镜像存在本地时不重复下载
privileged false 容器内不能运行 Docker(安全)
volumes /cache 持久化缓存目录

五、缓存机制

pip 缓存

yaml 复制代码
# .gitlab-ci.yml
variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

cache:
  key: "${CI_COMMIT_REF_SLUG}"    # 按分支隔离缓存
  paths:
    - .cache/pip

缓存存储位置

复制代码
Runner 容器内部
  └─ /cache
      └─ main-protected.tar  ← 缓存归档文件

缓存通过 Docker volume 持久化,容器重启后仍然可用。

缓存效果

场景 pip install 耗时
首次(无缓存) ~30 秒
命中缓存 ~5 秒
缓存失效 ~30 秒

六、资源消耗

常驻进程

组件 内存 CPU(空闲)
GitLab (CE) ~2 GB ~5%
GitLab Runner ~50 MB ~1%
Docker Desktop (WSL2) ~1 GB ~2%
合计 ~3 GB ~8%

每个 Job 运行时

组件 内存 说明
辅助容器 ~30 MB git clone + 缓存处理
构建容器 ~80-150 MB 取决于安装的依赖
单 Job 峰值 ~180 MB
3 Job 并行峰值 ~540 MB concurrent = 3

Docker Desktop 资源建议

资源 最低 推荐
内存 4 GB 6 GB
CPU 2 核 4 核
磁盘 20 GB 40 GB

七、常见问题

Q: 为什么 Job 一直 pending?

Runner 可能离线或配置丢失。检查:

bash 复制代码
# 1. Runner 容器是否在运行
docker ps | grep runner

# 2. Runner 是否注册成功
docker exec gitlab-runner gitlab-runner list

# 3. 查看 Runner 日志
docker logs --tail 20 gitlab-runner

Q: 容器为什么显示 Exited?

正常行为。Job 完成后容器自动退出,状态码 0 表示成功,非 0 表示失败。

bash 复制代码
# 查看所有退出的容器
docker ps -a --filter "status=exited"

# 批量清理
docker container prune -f

Q: 如何手动清理旧容器?

bash 复制代码
# 清理所有已退出的容器
docker container prune -f

# 清理未使用的镜像
docker image prune -f

# 清理所有未使用的资源(谨慎)
docker system prune -f

Q: 并发数设多少合适?

取决于 Docker Desktop 分配的资源:

内存 推荐并发数
4 GB 1-2
6 GB 2-3
8 GB 3-4

当前配置 concurrent = 3,分配 4GB 内存时可能偏紧,建议 Docker Desktop 至少分配 6GB。

Q: 辅助容器可以省略吗?

不可以。辅助容器负责 Git 操作和缓存管理,是 GitLab Runner Docker executor 的必要组件。但可以通过以下方式减少开销:

  • pull_policy = if-not-present 避免重复拉取镜像
  • 增大 concurrent 让多个 Job 共享同一个辅助容器镜像

八、完整执行时序图

复制代码
开发者                    GitLab                    Runner                   Docker
  │                         │                         │                        │
  │── git push ────────────►│                         │                        │
  │                         │                         │                        │
  │                         │── 解析 .gitlab-ci.yml ──►│                        │
  │                         │   创建 Pipeline #47     │                        │
  │                         │   创建 5 个 Job         │                        │
  │                         │                         │                        │
  │                         │◄── 请求 Job ────────────│                        │
  │                         │── 分配 run_tests ──────►│                        │
  │                         │── 分配 code_quality ──►│                        │
  │                         │── 分配 security_scan ─►│                        │
  │                         │                         │                        │
  │                         │                         │── 创建辅助容器 ────────►│
  │                         │                         │   (git clone)          │
  │                         │                         │                        │
  │                         │                         │── 创建构建容器 x3 ─────►│
  │                         │                         │   (pytest/pylint/bandit)│
  │                         │                         │                        │
  │                         │◄── 上传 Job 日志 ───────│                        │
  │                         │◄── 上传 artifacts ──────│                        │
  │                         │                         │                        │
  │                         │                         │── 容器退出 ────────────►│
  │                         │                         │                        │
  │                         │── Stage 1 完成 ────────►│                        │
  │                         │   触发 review 阶段      │                        │
  │                         │                         │                        │
  │                         │                         │── claude_review ──────►│
  │                         │                         │   (AI 代码审查)        │
  │                         │                         │                        │
  │                         │── review 完成 ─────────►│                        │
  │                         │   触发 deploy 阶段      │                        │
  │                         │                         │                        │
  │                         │                         │── deploy ─────────────►│
  │                         │                         │   (打包部署)           │
  │                         │                         │                        │
  │                         │── Pipeline 完成 ───────►│                        │
  │◄── 通知(成功/失败)────│                         │                        │
相关推荐
维度跃迁笔记2 小时前
2核4G轻量服务器部署GitLab实战:配置调优与CI/CD拆分方案
服务器·ci/cd·gitlab
Bigger2 小时前
GitLab-Runner + AI 代码审查服务 + 远程大模型 全套部署运维实战
前端·ci/cd·ai编程
终端行者3 小时前
企业级 Jenkins Pipeline 实战Docker构建前端+Ansible发布
前端·ci/cd·docker·jenkins
jiayong233 小时前
CI/CD与DevOps、Jenkins、K8s关系深度解析
运维·git·ci/cd
Byron Loong18 小时前
GitLab 全部权限角色详解
gitlab
Cat_Rocky19 小时前
Gitlab安装与配置
linux·运维·gitlab
饕餮争锋1 天前
CI/CD 概念详解
ci/cd
D4c-lovetrain1 天前
CentOS9 GitLab 完整配置全流程
gitlab
puamac1 天前
GitLab CI/CD 故障排查手册
ci/cd·gitlab