4、CI/CD概念与工具选型:持续集成/持续部署核心思想、Jenkins vs GitLab CI vs GitHub Actions对比

4.1 持续集成与持续部署:到底在解决什么问题?

先聊聊CI/CD这个概念。说实话,我刚入行那会儿,觉得CI/CD就是个花架子——不就是自动编译、自动部署吗?手动操作也挺快的啊。

直到有一次,我在一家创业公司做项目。团队五个人,每天手动合并代码、手动测试、手动上线。结果呢?上线前发现A同学改的接口和B同学改的前端对不上,回滚花了两个小时。老板在群里问「怎么又挂了」,那滋味...嗯,你懂的。

持续集成(CI),说白了就是「频繁地把代码合并到主干,并且每次合并都自动验证」。它的核心思想是:尽早发现集成问题。你想想看,如果每个人都在自己的分支上开发两周,最后合并时冲突一大堆,那得多痛苦?

持续部署(CD),则是「每次通过CI验证的代码,自动部署到生产环境」。当然,很多团队会加一道手动审批的门槛,这叫「持续交付」——代码随时可以部署,但要不要部署由人决定。

核心思想总结:

  • CI:频繁合并 + 自动构建 + 自动测试 = 尽早发现问题
  • CD:自动部署到生产 = 缩短交付周期
  • 核心目标:让「从代码提交到上线」这个过程,变得可重复、可追溯、低风险

我个人习惯把CI/CD比作「流水线上的质检员」。没有质检员,产品做出来可能全是次品;有了质检员,每道工序都自动检查,次品率自然就降下来了。

4.2 工具选型:Jenkins vs GitLab CI vs GitHub Actions

选工具这件事,我踩过不少坑。曾经有个项目,我一股脑上了Jenkins,结果发现团队就三个人,维护Jenkins的精力比写代码还多。后来换了GitLab CI,真香。

下面我结合自己的实际经验,给你做个对比。

维度 Jenkins GitLab CI GitHub Actions
部署方式 自托管,需单独部署服务器 自托管或SaaS 云端SaaS(GitHub提供)
配置方式 Web界面 + Jenkinsfile .gitlab-ci.yml .github/workflows/*.yml
插件生态 极其丰富(1000+插件) 中等,但够用 Marketplace丰富,增长快
学习曲线 陡峭(插件配置复杂) 平缓(YAML配置直观) 平缓(模板丰富)
适合场景 大型企业、复杂流水线 中小团队、GitLab用户 开源项目、GitHub用户
维护成本 高(需专人维护) 低(SaaS版几乎零维护) 极低(完全托管)

4.3 Jenkins:老牌劲旅,但有点「重」

Jenkins是我最早接触的CI工具。说实话,它的插件生态确实无敌——你想得到的、想不到的功能,基本都有插件。但问题也出在这里:插件多了,配置就变得极其复杂。

我曾经维护过一个Jenkins实例,上面装了80多个插件。每次升级Jenkins版本,都要花半天时间检查插件兼容性。有一次升级后,某个插件直接罢工,整个流水线瘫痪了两天。嗯,那滋味...你懂的。

避坑指南:我曾经因为Jenkins插件版本冲突,导致构建环境不一致。后来我养成了一个习惯:所有插件版本锁定,升级前先在测试环境验证。另外,尽量用Pipeline as Code(Jenkinsfile),别在Web界面上手动配置——否则换台机器你就得重来。

什么时候选Jenkins?

  • 你的团队有专门的运维/DevOps人员
  • 需要高度定制化的流水线(比如多环境、多分支、复杂触发条件)
  • 公司有自建机房的传统,不想用云服务

4.4 GitLab CI:一体化体验,中小团队首选

GitLab CI是我现在最常用的工具。为什么?因为它和GitLab代码仓库深度集成,你不需要额外部署任何东西——只要在项目根目录放一个.gitlab-ci.yml文件,流水线就自动跑起来了。

它的配置方式也很直观。举个例子,一个简单的Python项目流水线:

# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

test-job:
  stage: test
  script:
    - pip install -r requirements.txt
    - pytest tests/

build-job:
  stage: build
  script:
    - docker build -t myapp:$CI_COMMIT_SHORT_SHA .
    - docker push registry.example.com/myapp:$CI_COMMIT_SHORT_SHA

deploy-job:
  stage: deploy
  script:
    - kubectl set image deployment/myapp myapp=registry.example.com/myapp:$CI_COMMIT_SHORT_SHA
  only:
    - main

你看,三个阶段清清楚楚。而且GitLab CI的Runner可以跑在本地、Kubernetes、或者直接用GitLab提供的共享Runner。我个人习惯用Kubernetes Runner,这样流水线跑完自动销毁,不浪费资源。

小技巧:GitLab CI的rules关键字比only/except更灵活。比如「只有main分支且不是WIP的MR才触发部署」,用rules一行搞定。我建议你直接学rules,别在only/except上浪费时间。

什么时候选GitLab CI?

  • 团队已经在用GitLab管理代码
  • 不想维护额外的CI服务器
  • 需要和Kubernetes深度集成(GitLab CI原生支持)

4.5 GitHub Actions:开源项目的标配

GitHub Actions是后来者,但发展速度惊人。它的最大优势是社区生态——你可以在Marketplace找到各种现成的Action,比如部署到AWS、发送Slack通知、运行代码扫描等等。

举个例子,一个简单的Node.js项目CI:

# .github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v3
      - uses: some/deploy-action@v1
        with:
          api-key: ${{ secrets.API_KEY }}

你看,uses关键字直接引用别人写好的Action,省去了自己写脚本的麻烦。不过要注意:别盲目信任第三方Action。我曾经见过一个Action偷偷把环境变量上传到外部服务器——嗯,安全审计没通过。

安全提醒:使用第三方Action时,建议锁定版本(比如@v3而不是@latest),并且定期审查Action的源码。对于敏感操作(比如部署到生产),尽量用官方或自建的Action。

什么时候选GitHub Actions?

  • 项目托管在GitHub上(尤其是开源项目)
  • 团队规模小,不想折腾基础设施
  • 需要快速集成各种第三方服务

4.6 我的选型建议

说了这么多,到底怎么选?我个人的经验是:

  • 个人项目或小团队(1-5人):GitHub Actions(如果代码在GitHub)或GitLab CI(如果代码在GitLab)。别折腾Jenkins,维护成本太高。
  • 中型团队(5-20人):GitLab CI。一体化体验好,而且自托管Runner可以跑在内部网络,安全性有保障。
  • 大型企业(20人以上):Jenkins。虽然重,但插件生态和定制能力无可替代。不过建议用Pipeline as Code,别在Web界面上点来点去。

最后说一句:工具只是手段,不是目的。我见过有人把Jenkins流水线写得像天书,也见过有人用GitHub Actions写出优雅的流水线。关键是理解CI/CD的核心思想——自动化、可重复、快速反馈。工具选哪个,真的没那么重要。

一句话总结:CI/CD不是银弹,但它能帮你把「上线」这件事从「心惊胆战」变成「习以为常」。选一个你团队用得顺手的工具,先跑起来,再慢慢优化。