对比背景

  • GitLab CI/CD(内置):配置即代码、与 MR/Registry/环境深度集成,开箱即用
  • GitLab + Jenkins(解耦):GitLab 只做代码托管与触发源,Jenkins 承担全部流水线执行;适合已有 Jenkins 生态、需要 Groovy 级定制或对接大量内部系统的团队

架构链路:push/MR/tag → GitLab Webhook → Jenkins(Multibranch)→ Jenkinsfile 执行 → Commit Status API 回写 GitLab → MR 显示构建状态

概念映射总表

GitLab CI/CDJenkins 等价物备注
.gitlab-ci.ymlJenkinsfile(Declarative)放仓库根目录,Multibranch 自动发现
Pipeline / Stage / Jobbuild / stage {} / steps {}一一对应
Runner + ExecutorAgent(node)+ label内置节点 / 静态 agent / docker agent / K8s pod
tags 路由agent { label 'xxx' }label 支持表达式
rules / only / exceptwhen { branch/tag/changeset/expression }
workflow:rules无直接对应靠触发器配置 + when 条件模拟
needs(DAG)parallel {} / Scripted 并发Declarative 的 DAG 表达力较弱
include / extendsShared Library(@Library)/ load()
Variables(protected/masked)Credentials + withCredentials日志自动 mask,支持 folder/项目分级
File 类型变量File Credential用法几乎一致(变量是路径)
artifactsarchiveArtifacts + copyArtifacts
cache无原生机制workspace 复用 / stash / 共享卷 DIY
artifacts:reports(junit/coverage)junit / publishCoverage 步骤Jenkins UI 展示;MR 侧展示靠插件
dotenv 报告传参无对应readProperties 读归档文件模拟
environment / 部署审计无原生自建审计或用 Deployment 类插件
resource_groupLockable Resources 插件 lock()
interruptiblemilestone 步骤新构建取消同 milestone 的旧构建
retry / timeoutretry(n) / timeout(time:)
allow_failurecatchError(buildResult:'SUCCESS', stageResult:'FAILURE')
parallel:matrixmatrix {} 指令Declarative 1.5+
trigger(多项目)build job: 'group/project', parameters: [...]
定时调度triggers { cron('H 2 * * *') }
MR 触发 + 状态回写GitLab Plugin + Multibranch合并门禁在 GitLab 侧配置
Pipeline editor / CI Lintjenkins-cli declarative-linter / Replay
Interactive Web Terminal无只能登 agent 机器

落地五步

1. 插件清单

必装:GitLab Plugin、Git、Pipeline(workflow-aggregator)、Credentials Binding、Multibranch、GitLab Branch Source。 按需:Docker Pipeline、Kubernetes、Lockable Resources、Job Cacher(缓存)、Warnings NG(MR 问题装饰)。

2. 打通 GitLab ↔ Jenkins

  • Jenkins:Manage Jenkins → System → GitLab → 添加 connection(GitLab URL + API token,勾 Enable authentication)
  • 新建 Multibranch Pipeline → Branch Sources 选 GitLab Project;插件会自动管理 webhook(push/MR/tag 事件)
  • 合并门禁:GitLab 16.6+ 在 protected branch 可配 required status checks,把 Jenkins commit status 设为合并必要条件(旧版本需 Premium 的 External Status Checks;否则仅展示不强制)

3. Jenkinsfile 等价示例

对照 cicd-recipes 的 test→build→deploy 骨架:

pipeline {
    agent { docker { image 'golang:1.24' } }   // K8s 场景换 agent { kubernetes }
 
    environment { GOPROXY = 'https://goproxy.cn,direct' }
 
    options { gitLabConnection('gitlab') }     // GitLab Plugin 状态回写
 
    stages {
        stage('Test') {
            steps { sh 'go test -race ./...' }
            post { always { junit allowEmptyResults: true, testResults: 'test-results/*.xml' } }
        }
        stage('Build') {
            steps {
                sh 'go build -o app ./cmd/app'
                archiveArtifacts artifacts: 'app', fingerprint: true
            }
        }
        stage('Deploy') {
            when { branch 'main' }               // 等价 rules: if branch == main
            steps {
                lock('prod-deploy') {            // 等价 resource_group
                    withCredentials([file(credentialsId: 'kube-config-prod', variable: 'KUBECONFIG')]) {
                        sh 'kubectl set image deployment/app app=registry.example.com/app:$GIT_COMMIT -n prod'
                        sh 'kubectl rollout status deployment/app -n prod --timeout=180s'
                    }
                }
            }
        }
    }
}

4. 并行与矩阵

stage('Tests') {
    parallel {
        stage('unit') { steps { sh 'go test ./...' } }
        stage('lint') { steps { sh 'golangci-lint run' } }
    }
}
stage('Matrix') {
    matrix {
        axes {
            axis { name 'DB'; values 'mysql', 'postgres' }
            axis { name 'VER'; values '15', '16' }
        }
        stages { stage('run') { steps { sh './run-tests.sh $DB $VER' } } }
    }
}

5. Agent 弹性

  • docker agent:agent { docker { image ... } },等价 docker executor
  • K8s 动态 agent:Kubernetes 插件 pod template,按 Pod 起容器、跑完即销,等价 kubernetes executor:
agent {
    kubernetes {
        yaml '''
            apiVersion: v1
            kind: Pod
            spec:
              containers:
              - name: golang
                image: golang:1.24
                command: ['sleep', 'infinity']
        '''
    }
}
// steps 里用 container('golang') { sh '...' }

Jenkins 需要 DIY 的差距清单

能力GitLab CI 现状Jenkins 侧方案
依赖缓存原生 cache + S3 后端workspace 固定节点 / stash-unstash / 共享 NFS / docker layer cache
部署环境与审计Environments 页面 + 回滚自建(job 参数 + 外部记录)或插件
Job 间变量传递dotenv 报告archiveArtifacts + readProperties
DAG 可视化Pipeline DAG 视图较弱(Blue Ocean 已停止积极维护)
MR 行内评论SAST/测试报告 decorationWarnings NG + GitLab plugin
现场调试终端Interactive Web Terminal无,只能登 agent
防双流水线workflow:rulesMultibranch 默认按分支/MR 分开,需自行约束

结论

  • Jenkins 优势:Groovy 可编程性、插件生态、对接遗留系统的灵活性
  • GitLab CI 优势:与 MR/Registry/Secrets/Environments 的开箱集成、配置即代码、DAG 与缓存原生支持
  • 选型建议:团队已有 Jenkins 资产且定制需求重 → GitLab+Jenkins(Multibranch + GitLab Plugin + Shared Library + K8s agent 是标准组合);从零开始或追求低运维 → 直接用 GitLab CI/CD

相关