以下是 Jenkins 与 GitLab 的核心知识总结,以及它们如何通过流水线实现**持续集成(CI)**的完整链路。
一、Jenkins 核心知识点
| 维度 | 核心内容 |
|---|---|
| 定位 | 开源的自动化服务器,专注于构建、测试、部署的流水线编排 |
| 架构 | Master-Agent(主从)模式:Master 负责调度与 Web UI,Agent(Node)负责实际执行构建任务 |
| 配置方式 | Pipeline as Code:通过 Jenkinsfile(Groovy DSL)将流水线定义版本化,随代码一起管理 |
| 执行环境 | 支持物理机、虚拟机、Docker、Kubernetes(动态创建 Agent Pod) |
| 插件生态 | 2000+ 插件,几乎可对接任何工具(Git、Maven、Docker、K8s、钉钉、SonarQube) |
| 核心优势 | 极度灵活、复杂流程编排能力强、企业级集成度高 |
| 核心劣势 | 插件依赖多、配置复杂、界面老旧、Groovy 学习曲线陡峭 |
| 关键组件 | Jenkinsfile、Kubernetes Plugin、Blue Ocean(可视化)、Credentials(凭据管理) |
Jenkins 实现 CI 的核心流程:
Git Push → Webhook 触发 Jenkins Master → 调度 K8s Agent Pod →
执行 Jenkinsfile 阶段(Build → Test → Package)→ 产物归档
二、GitLab 核心知识点
| 维度 | 核心内容 |
|---|---|
| 定位 | 一体化 DevOps 平台:代码托管 + CI/CD + 项目管理 + 安全扫描 + 容器注册表 |
| 架构 | GitLab Server + Runner:Server 负责代码与调度,Runner 负责执行 CI 任务 |
| 配置方式 | .gitlab-ci.yml(YAML 语法),与代码同仓库,提交即触发 |
| 执行环境 | Shell、Docker、Docker Machine、Kubernetes、SSH |
| 内置能力 | 代码审查(MR)、Issue 跟踪、内置 Container Registry、SAST/DAST 安全扫描 |
| 核心优势 | 开箱即用、配置简单、与代码仓库天然一体、界面现代 |
| 核心劣势 | 复杂流水线能力弱于 Jenkins、大集群下 Runner 管理较分散 |
| 关键组件 | .gitlab-ci.yml、GitLab Runner、CI/CD Pipelines、Container Registry |
GitLab 实现 CI 的核心流程:
Git Push → GitLab 识别 .gitlab-ci.yml → 分发给 Runner(K8s Pod)→
按 stages 顺序执行(build → test → package)→ 结果回显在 MR/Commit 页面
三、Jenkins vs GitLab 对比
| 对比维度 | Jenkins | GitLab CI |
|---|---|---|
| 出身 | 纯 CI/CD 工具,后扩展生态 | 代码仓库出身,后扩展 CI/CD |
| 配置语法 | Groovy(Jenkinsfile) | YAML(.gitlab-ci.yml) |
| 学习曲线 | 陡峭(需学 Groovy + 插件机制) | 平缓(YAML 直观) |
| 与代码绑定 | Jenkinsfile 可放代码库,但配置分散 | .gitlab-ci.yml 与代码天然一体 |
| 执行单元 | Stage → Node/Agent | Stage → Job → Runner |
| K8s 集成 | Kubernetes Plugin(动态 Pod 模板) | Kubernetes Executor(Runner 作为 Pod) |
| 安全扫描 | 依赖插件(SonarQube、Trivy) | 内置 SAST/DAST/依赖扫描 |
| 镜像仓库 | 需外部 Harbor/Nexus | 内置 Container Registry |
| 适用场景 | 大企业、复杂流水线、多工具链集成 | 中小团队、追求一体化、快速上手 |
| 触发方式 | Webhook、定时、上游触发 | Git Push、MR、定时、Pipeline 触发 |
四、流水线实现持续集成(CI)的原理
无论 Jenkins 还是 GitLab,CI 的实现都遵循相同的阶段模型:
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Source │ → │ Build │ → │ Test │ → │ Package │
│ 代码触发 │ │ 编译构建 │ │ 测试验证 │ │ 制品打包 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
│ │ │ │
git push mvn/package junit/test docker build
webhook npm run build sonar scan push harbor
1. Source(代码触发)
- 触发源:
git push、Merge Request、定时任务、上游流水线触发 - 代码隔离:通过分支策略(Git Flow / Trunk Based)控制哪些分支触发 CI
2. Build(编译构建)
- 任务:拉取依赖、编译源码、生成二进制产物(JAR/WAR/静态文件)
- 优化:多阶段 Docker 构建、依赖缓存(Maven
~/.m2、npmnode_modules)
3. Test(测试验证)
- 测试金字塔:
- 单元测试(快、多、本地):JUnit、pytest、Jest
- 集成测试(中速):TestContainers、Spring Boot Test
- E2E 测试(慢、少):Cypress、Selenium
- 质量门禁:SonarQube 代码覆盖率、漏洞扫描阻断流水线
4. Package(制品打包)
- 容器化:
docker build生成镜像,推送到 Harbor / GitLab Registry - 版本管理:镜像标签绑定 Git Commit SHA(
order-service:a1b2c3d),确保可追溯
五、结合 K8s 的 CI 实战流程
Jenkins 版(K8s Agent 动态创建)
// Jenkinsfile
pipeline {
// 动态 K8s Pod 模板:每个 Stage 使用不同容器
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.9-eclipse-temurin-17
command: ['cat']
tty: true
- name: docker
image: docker:24-dind
securityContext:
privileged: true
- name: helm
image: alpine/helm:latest
command: ['cat']
tty: true
"""
}
}
stages {
stage('Build') {
steps {
container('maven') {
sh 'mvn -B clean package'
}
}
}
stage('Test') {
steps {
container('maven') {
sh 'mvn test'
}
}
}
stage('Package') {
steps {
container('docker') {
sh 'docker build -t harbor.company.com/ecommerce/order-service:${BUILD_NUMBER} .'
sh 'docker push harbor.company.com/ecommerce/order-service:${BUILD_NUMBER}'
}
}
}
}
}
GitLab 版(K8s Runner)
# .gitlab-ci.yml
stages:
- build
- test
- package
variables:
DOCKER_REGISTRY: "harbor.company.com"
build:
stage: build
image: maven:3.9-eclipse-temurin-17
script:
- mvn -B clean package -DskipTests
artifacts:
paths:
- target/*.jar
test:
stage: test
image: maven:3.9-eclipse-temurin-17
script:
- mvn test
coverage: '/Total.*?(\d+\%)/'
package:
stage: package
image: docker:24-dind
services:
- docker:24-dind
script:
- docker build -t $DOCKER_REGISTRY/ecommerce/order-service:$CI_COMMIT_SHA .
- docker push $DOCKER_REGISTRY/ecommerce/order-service:$CI_COMMIT_SHA
六、核心概念速查
| 术语 | Jenkins | GitLab | 含义 |
|---|---|---|---|
| 流水线定义文件 | Jenkinsfile | .gitlab-ci.yml | 描述 CI 阶段的代码 |
| 执行器 | Agent / Node | Runner | 实际跑构建任务的机器/Pod |
| 阶段 | stage('Build') | stages: - build | 流水线的逻辑步骤 |
| 步骤 | steps { sh '...' } | script: - ... | 阶段内的具体命令 |
| 产物 | artifacts | artifacts: | 阶段间传递的文件 |
| 缓存 | 插件配置 | cache: | 加速构建的依赖缓存 |
| 环境变量 | env.VAR | variables: | 全局或阶段级变量 |
| 触发条件 | Webhook / 定时 | only: - main | 控制何时触发流水线 |
七、一句话总结
| 工具 | 一句话 |
|---|---|
| Jenkins | "万能流水线工厂"——Groovy 编程实现任意复杂编排,适合大企业多工具链集成 |
| GitLab | "一体化 DevOps 工作台"——YAML 声明快速搭建 CI,代码、审查、构建、安全一站式搞定 |
持续集成的本质:开发者每次 git push 后,系统自动完成编译 → 测试 → 打包,并在几分钟内给出成功/失败的明确反馈,让问题在早期暴露、早期修复,而不是等到上线前才发现。