4. 流水线基础:GitLab CI/CD 与 Jenkins Pipeline 对比、流水线阶段划分

在云原生交付体系中,流水线是策略执行的最后一公里。Kyverno 回滚护栏需要嵌入到流水线的 Pre-Deploy 校验 与 Post-Deploy 验证 阶段。本章首先对比两种主流流水线引擎——GitLab CI/CD 与 Jenkins Pipeline,然后定义标准化的 Build / Test / Deploy 阶段划分,为后续集成 Kyverno 策略提供清晰的锚点。

4.1 GitLab CI/CD 与 Jenkins Pipeline 对比

两种引擎在架构、配置语法、触发方式、可观测性上存在显著差异。下表从 8 个关键维度进行对比:

对比维度 GitLab CI/CD Jenkins Pipeline
配置位置 仓库内 .gitlab-ci.yml Jenkinsfile(Declarative / Scripted)
执行模型 Runner 拉取 Job,每个 Job 独立容器 Master/Agent 架构,Pipeline 跨 Node 执行
阶段定义 stages 全局声明,Job 通过 stage 字段归属 stage 块嵌套在 pipeline 内,支持并行/嵌套
条件触发 rules / only / except,支持变量与变更路径 when 条件 + expression Groovy 脚本
产物传递 artifacts 跨 Job 传递,依赖 needs stash / unStash 跨 Stage 传递
安全集成 原生 CI/CD 变量 + 外部 Secrets 插件 Credentials Binding + HashiCorp Vault 插件
可观测性 内置 Pipeline 视图 + Job 日志 + 测试报告 Blue Ocean / Stage View + 日志持久化
回滚支持 需手动或 API 触发回退 Job 可通过 input 或 error 触发回滚 Stage
选型建议: 若团队已深度使用 GitLab 生态,优先选择 GitLab CI/CD 以减少工具链割裂;若需要复杂的条件分支、人工审批、多环境编排,Jenkins Pipeline 的 Groovy 灵活性更高。

4.2 流水线阶段划分:Build / Test / Deploy

无论使用哪种引擎,云原生流水线都应遵循 三阶段模型。每个阶段内部可包含多个并行或串行的 Job,但阶段边界必须清晰,以便插入 Kyverno 策略检查点。

4.2.1 Build 阶段

  • 输入: 源代码 + 依赖锁文件(如 go.sum、package-lock.json)
  • 核心活动: 编译、镜像构建、SBOM 生成、镜像签名
  • 产出: 容器镜像(含标签)、软件物料清单(SPDX/CycloneDX)
  • Kyverno 切入点: 在镜像推送前,对 Dockerfile 或 build-args 执行准入策略(如禁止 root 用户、强制只读根文件系统)

4.2.2 Test 阶段

  • 输入: 构建产物 + 测试套件 + 模拟集群配置
  • 核心活动: 单元测试、集成测试、安全扫描(Trivy / Grype)、策略模拟(Kyverno CLI)
  • 产出: 测试报告、漏洞清单、策略评估结果
  • Kyverno 切入点: 使用 kyverno apply 对渲染后的 Kubernetes 资源 YAML 进行预检,生成通过/失败报告

4.2.3 Deploy 阶段

  • 输入: 通过测试的镜像 + 部署清单 + 环境变量
  • 核心活动: 灰度发布(Canary / Blue-Green)、资源 Apply、健康检查、回滚准备
  • 产出: 运行中的工作负载、监控指标、回滚快照
  • Kyverno 切入点: 在 kubectl apply 之前,调用 Kyverno API 进行集群级准入校验;部署后执行 kyverno test 验证预期策略是否生效
实践要点: 建议在 Test 阶段末尾增加一个 策略门禁(Policy Gate) Job,该 Job 汇总所有 Kyverno 检查结果,若存在 violation 则直接中断流水线,避免不合规资源进入 Deploy 阶段。

4.3 流水线阶段与策略检查点关系图

下图展示了标准三阶段流水线中,Kyverno 策略检查点的插入位置:

流水线阶段与 Kyverno 策略检查点 流水线三阶段与 Kyverno 策略检查点 Build 阶段 编译 · 镜像构建 · SBOM Test 阶段 单元测试 · 安全扫描 · 策略预检 Deploy 阶段 灰度发布 · 准入校验 · 回滚 🔍 镜像策略检查 🔍 资源 YAML 预检 🔍 集群准入校验 💡 策略门禁:Test 阶段末尾汇总所有 Kyverno 检查结果, 若存在 violation 则中断流水线,阻止不合规资源进入 Deploy。

4.4 两种引擎的阶段定义示例

以下分别给出 GitLab CI/CD 与 Jenkins Pipeline 的三阶段定义骨架,便于后续直接嵌入 Kyverno 检查 Job。

4.4.1 GitLab CI/CD 阶段定义

stages:
  - build
  - test
  - deploy

build-image:
  stage: build
  script:
    - docker build -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA} .
    - docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
  artifacts:
    paths:
      - sbom.json

kyverno-precheck:
  stage: test
  script:
    - kyverno apply deployment.yaml --policy ./policies/ --output result.json
    - cat result.json | jq -e '.violations | length == 0'
  needs: [build-image]

deploy-canary:
  stage: deploy
  script:
    - kubectl set image deployment/app app=${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
    - kubectl rollout status deployment/app
  when: manual

4.4.2 Jenkins Pipeline 阶段定义

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'docker build -t myapp:${BUILD_NUMBER} .'
                sh 'docker push myapp:${BUILD_NUMBER}'
            }
        }
        stage('Test') {
            parallel {
                stage('Unit Test') {
                    steps { sh 'go test ./...' }
                }
                stage('Kyverno Precheck') {
                    steps {
                        sh 'kyverno apply deployment.yaml --policy ./policies/ --output result.json'
                        sh 'jq -e \'.violations | length == 0\' result.json'
                    }
                }
            }
        }
        stage('Deploy') {
            input {
                message '确认部署到生产环境?'
                ok '部署'
            }
            steps {
                sh 'kubectl set image deployment/app app=myapp:${BUILD_NUMBER}'
                sh 'kubectl rollout status deployment/app'
            }
        }
    }
}
注意: 上述示例中 kyverno apply 命令假设已在 Runner/Agent 上安装 Kyverno CLI。生产环境建议将 Kyverno CLI 封装为容器镜像,通过 image:(GitLab)或 containerTemplate(Jenkins)引入,避免依赖主机环境。

4.5 阶段划分对回滚护栏的影响

清晰的阶段边界直接决定了回滚护栏的触发时机与回滚范围:

  • Build 阶段失败: 回滚到上一个成功构建的镜像标签,无需涉及 Kubernetes 资源变更。
  • Test 阶段策略违规: 回滚到上一个通过策略预检的提交,同时触发策略告警通知。
  • Deploy 阶段准入拒绝: 自动触发 Pre-Deploy 回滚,保持集群当前版本不变,并记录 Kyverno 拒绝原因。
  • Deploy 后健康检查失败: 触发 Post-Deploy 回滚,调用 kubectl rollout undo 或 Helm rollback,恢复至上一次稳定版本。