极狐 GitLab

从 Jenkins 迁移

Tier: 基础版,专业版,旗舰版

Offering: JihuLab.com,私有化部署

如果你正在从 Jenkins 迁移到极狐GitLab CI/CD,你可以创建 CI/CD 流水线,复制并增强你的 Jenkins 工作流。

主要相似点和差异点#

极狐GitLab CI/CD 和 Jenkins 都是 CI/CD 工具,有一些相似之处。极狐GitLab 和 Jenkins 都:

  • 使用阶段来分组作业。
  • 支持基于容器的构建。

此外,两者之间还有一些重要差异:

  • 极狐GitLab CI/CD 流水线全部配置在一个 YAML 格式的配置文件中。Jenkins 使用 Groovy 格式的配置文件(声明式流水线)或 Jenkins DSL(脚本式流水线)。
  • 极狐GitLab 提供 JihuLab.com(多租户 SaaS 服务),你也可以运行自己的 私有化部署 实例。Jenkins 部署必须自托管。
  • 极狐GitLab 提供内置的源代码管理(SCM)。Jenkins 需要单独的 SCM 解决方案来存储代码。
  • 极狐GitLab 提供内置的容器镜像仓库。Jenkins 需要单独的解决方案来存储容器镜像。
  • 极狐GitLab 提供内置的代码扫描模板。Jenkins 需要第三方插件来扫描代码。

功能与概念对比#

许多 Jenkins 的功能和概念在极狐GitLab 中都有对应,并提供相同功能。

配置文件#

Jenkins 可以使用 Groovy 格式的 Jenkinsfile 进行配置。极狐GitLab CI/CD 默认使用 .gitlab-ci.yml 文件。

一个 Jenkinsfile 示例:

groovy
1pipeline { 2 agent any 3 4 stages { 5 stage('hello') { 6 steps { 7 echo "Hello World" 8 } 9 } 10 } 11}

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1stages: 2 - hello 3 4hello-job: 5 stage: hello 6 script: 7 - echo "Hello World"

Jenkins 流水线语法#

Jenkins 配置由包含 sections 和 directives 的 pipeline 块组成。极狐GitLab CI/CD 有类似功能,通过 YAML 关键词进行配置。

Sections#

Jenkins极狐GitLab说明
代理镜像Jenkins 流水线在代理上执行,代理 部分定义了流水线如何执行以及要使用的 Docker 容器。极狐GitLab 作业在 Runner 上执行,镜像 关键词定义了要使用的容器。你可以在 Kubernetes 或任何主机上配置自己的 Runner。
后置after_script阶段Jenkins 的 后置 部分定义了在阶段或流水线末尾应执行的操作。在极狐GitLab 中,使用 after_script 来定义在作业末尾要运行的命令,使用 before_script 来定义在作业中其他命令之前执行的操作。使用 阶段 来选择作业应运行的确切阶段。极狐GitLab 支持 .pre.post 阶段,这些阶段始终在所有其他定义的阶段之前或之后运行。
stagesstagesJenkins 的阶段是作业组。极狐GitLab CI/CD 也使用阶段,但更加灵活。你可以有多个阶段,每个阶段可以包含多个独立的作业。在顶层使用 stages 定义阶段及其执行顺序,并在作业级别使用 stage 为该作业定义所在阶段。
stepsscriptJenkins 的 steps 定义要执行的内容。极狐GitLab CI/CD 使用类似的 script 部分。script 部分是一个 YAML 数组,每个条目对应要按顺序运行的命令。

Directives#

Jenkins极狐GitLab说明
environmentvariablesJenkins 使用 environment 来管理环境变量。极狐GitLab CI/CD 使用 variables 关键词来定义 CI/CD 变量,这些变量既可以在作业执行期间使用,也可以用于更动态的流水线配置。这些变量也可以在极狐GitLab UI 的 CI/CD 设置中进行设置。
options不适用Jenkins 使用 options 进行额外配置,包括超时和重试值。极狐GitLab 不需要单独的 options 部分,所有配置都作为 CI/CD 关键词添加到作业或流水线级别,例如 timeoutretry
parameters不适用在 Jenkins 中,可以在触发流水线时要求提供参数。极狐GitLab 通过 CI/CD 变量处理参数,这些变量可以在许多地方定义,包括流水线配置、项目设置、在运行时通过 UI 或 API 手动设置。
triggersrules在 Jenkins 中,triggers 定义了流水线应何时再次运行,例如通过 cron 表达式。极狐GitLab CI/CD 可以因为多种原因自动运行流水线,包括 Git 更改和合并请求更新。使用 rules 关键词来控制应针对哪些事件运行作业。定时流水线在项目设置中定义。
tools不适用在 Jenkins 中,tools 定义了要在环境中安装的额外工具。极狐GitLab 没有类似的关键词,推荐使用预先构建好作业所需确切工具的容器镜像。这些镜像可以被缓存,并且可以预先包含流水线所需的工具。如果作业需要额外的工具,可以在 before_script 部分中安装。
input不适用在 Jenkins 中,input 用于添加用户输入提示。与 parameters 类似,在极狐GitLab 中通过 CI/CD 变量处理输入。
whenrules在 Jenkins 中,when 定义了阶段应在何时执行。极狐GitLab 也有一个 when 关键词,它根据前面作业的状态(例如作业是通过还是失败)来决定作业是否应该开始运行。要控制何时将作业添加到特定的流水线中,请使用 rules

常见配置#

本节介绍常用的 CI/CD 配置,并展示如何将它们从 Jenkins 转换到极狐GitLab CI/CD。

Jenkins 流水线 会在特定事件(例如推送新提交)发生时生成自动化的 CI/CD 作业。Jenkins 流水线在 Jenkinsfile 中定义。极狐GitLab 的对应文件是 .gitlab-ci.yml 配置文件

Jenkins 不提供存储源代码的位置,因此 Jenkinsfile 必须存储在单独的源代码管理仓库中。

作业#

作业是按特定顺序运行以实现特定结果的一组命令。

例如,在 Jenkinsfile 中构建一个容器,然后将其部署到生产环境:

groovy
1pipeline { 2 agent any 3 stages { 4 stage('build') { 5 agent { docker 'golang:alpine' } 6 steps { 7 apk update 8 go build -o bin/hello 9 } 10 post { 11 always { 12 archiveArtifacts artifacts: 'bin/hello' 13 onlyIfSuccessful: true 14 } 15 } 16 } 17 stage('deploy') { 18 agent { docker 'golang:alpine' } 19 when { 20 branch 'staging' 21 } 22 steps { 23 echo "Deploying to staging" 24 scp bin/hello remoteuser@remotehost:/remote/directory 25 } 26 } 27 } 28}

这个示例:

  • 使用 golang:alpine 容器镜像。
  • 运行一个用于构建代码的作业。
    • 将构建出的可执行文件存储为产物。
  • 添加第二个作业来部署到 staging,该作业:
    • 仅在提交目标为 staging 分支时存在。
    • 在构建阶段成功后启动。
    • 使用前一个作业中的构建产物。

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1default: 2 image: golang:alpine 3 4stages: 5 - build 6 - deploy 7 8build-job: 9 stage: build 10 script: 11 - apk update 12 - go build -o bin/hello 13 artifacts: 14 paths: 15 - bin/hello 16 expire_in: 1 week 17 18deploy-job: 19 stage: deploy 20 script: 21 - echo "Deploying to Staging" 22 - scp bin/hello remoteuser@remotehost:/remote/directory 23 rules: 24 - if: $CI_COMMIT_BRANCH == 'staging' 25 artifacts: 26 paths: 27 - bin/hello
并行执行#

在 Jenkins 中,不依赖于前面作业的作业可以通过添加到 parallel 部分来并行运行。

例如,在 Jenkinsfile 中:

groovy
1pipeline { 2 agent any 3 stages { 4 stage('Parallel') { 5 parallel { 6 stage('Python') { 7 agent { docker 'python:latest' } 8 steps { 9 sh "python --version" 10 } 11 } 12 stage('Java') { 13 agent { docker 'openjdk:latest' } 14 when { 15 branch 'staging' 16 } 17 steps { 18 sh "java -version" 19 } 20 } 21 } 22 } 23 } 24}

该示例使用不同的容器镜像并行运行 Python 和 Java 作业。Java 作业仅在更改 staging 分支时运行。

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1python-version: 2 image: python:latest 3 script: 4 - python --version 5 6java-version: 7 image: openjdk:latest 8 rules: 9 - if: $CI_COMMIT_BRANCH == 'staging' 10 script: 11 - java -version

在这种情况下,无需额外配置即可使作业并行运行。默认情况下,作业可以并行运行,每个作业在不同的 Runner 上执行,前提是有足够的 Runner 可用于所有作业。Java 作业被设置为仅在更改 staging 分支时运行。

矩阵#

在极狐GitLab 中,你可以使用矩阵在单个流水线中多次并行运行一个作业,但每个作业实例具有不同的变量值。Jenkins 是顺序执行矩阵的。

例如,在 Jenkinsfile 中:

groovy
1matrix { 2 axes { 3 axis { 4 name 'PLATFORM' 5 values 'linux', 'mac', 'windows' 6 } 7 axis { 8 name 'ARCH' 9 values 'x64', 'x86' 10 } 11 } 12 stages { 13 stage('build') { 14 echo "Building $PLATFORM for $ARCH" 15 } 16 stage('test') { 17 echo "Building $PLATFORM for $ARCH" 18 } 19 stage('deploy') { 20 echo "Building $PLATFORM for $ARCH" 21 } 22 } 23}

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1stages: 2 - build 3 - test 4 - deploy 5 6.parallel-hidden-job: 7 parallel: 8 matrix: 9 - PLATFORM: [linux, mac, windows] 10 ARCH: [x64, x86] 11 12build-job: 13 extends: .parallel-hidden-job 14 stage: build 15 script: 16 - echo "Building $PLATFORM for $ARCH" 17 18test-job: 19 extends: .parallel-hidden-job 20 stage: test 21 script: 22 - echo "Testing $PLATFORM for $ARCH" 23 24deploy-job: 25 extends: .parallel-hidden-job 26 stage: deploy 27 script: 28 - echo "Testing $PLATFORM for $ARCH"

容器镜像#

在极狐GitLab 中,你可以使用 image 关键词在独立的、隔离的 Docker 容器中运行 CI/CD 作业

例如,在 Jenkinsfile 中:

groovy
1stage('Version') { 2 agent { docker 'python:latest' } 3 steps { 4 echo 'Hello Python' 5 sh 'python --version' 6 } 7}

该示例展示了在 python:latest 容器中运行的命令。

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
version-job: image: python:latest script: - echo "Hello Python" - python --version

变量#

在极狐GitLab 中,使用 variables 关键词来定义 CI/CD 变量。使用变量可以重用配置数据、实现更动态的配置或存储重要值。变量可以全局定义,也可以按作业定义。

例如,在 Jenkinsfile 中:

groovy
1pipeline { 2 agent any 3 environment { 4 NAME = 'Fern' 5 } 6 stages { 7 stage('English') { 8 environment { 9 GREETING = 'Hello' 10 } 11 steps { 12 sh 'echo "$GREETING $NAME"' 13 } 14 } 15 stage('Spanish') { 16 environment { 17 GREETING = 'Hola' 18 } 19 steps { 20 sh 'echo "$GREETING $NAME"' 21 } 22 } 23 } 24}

该示例展示了如何使用变量将值传递给作业中的命令。

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1default: 2 image: alpine:latest 3 4stages: 5 - greet 6 7variables: 8 NAME: "Fern" 9 10english: 11 stage: greet 12 variables: 13 GREETING: "Hello" 14 script: 15 - echo "$GREETING $NAME" 16 17spanish: 18 stage: greet 19 variables: 20 GREETING: "Hola" 21 script: 22 - echo "$GREETING $NAME"

变量也可以在极狐GitLab UI 的 CI/CD 设置中进行设置。在某些情况下,你可以使用受保护被屏蔽的变量来处理密钥值。这些变量可以在流水线作业中像在配置文件中定义的变量一样被访问。

例如,在 Jenkinsfile 中:

groovy
1pipeline { 2 agent any 3 stages { 4 stage('Example Username/Password') { 5 environment { 6 AWS_ACCESS_KEY = credentials('aws-access-key') 7 } 8 steps { 9 sh 'my-login-script.sh $AWS_ACCESS_KEY' 10 } 11 } 12 } 13}

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
login-job: script: - my-login-script.sh $AWS_ACCESS_KEY

此外,极狐GitLab CI/CD 为每个流水线和作业提供了预定义变量,这些变量包含与流水线和仓库相关的值。

表达式和条件判断#

当新流水线启动时,极狐GitLab 会检查哪些作业应该在该流水线中运行。你可以根据变量状态或流水线类型等因素来配置作业的运行条件。

例如,在 Jenkinsfile 中:

groovy
1stage('deploy_staging') { 2 agent { docker 'alpine:latest' } 3 when { 4 branch 'staging' 5 } 6 steps { 7 echo "Deploying to staging" 8 } 9}

在该示例中,作业仅在提交到的分支名为 staging 时运行。

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1deploy_staging: 2 stage: deploy 3 script: 4 - echo "Deploy to staging server" 5 rules: 6 - if: '$CI_COMMIT_BRANCH == staging'

Runner#

与 Jenkins 代理类似,极狐GitLab Runner 是运行作业的主机。如果你使用的是 JihuLab.com,你可以使用实例 Runner 队列来运行作业,而无需自行配置 Runner。

要将 Jenkins 代理转换用于极狐GitLab CI/CD,请卸载该代理,然后安装并注册 Runner。Runner 不需要太多开销,因此你或许可以使用与 Jenkins 代理类似的配置。

关于 Runner 的一些关键细节:

  • Runner 可以配置为跨实例、群组共享,或者专用于单个项目。
  • 你可以使用 tags 关键词进行更精细的控制,并将 Runner 与特定作业关联。例如,你可以为需要专用、更强大或特定硬件的作业使用一个标签。
  • 极狐GitLab 支持Runner 自动伸缩。使用自动伸缩仅在需要时配置 Runner,并在不需要时缩减。

例如,在 Jenkinsfile 中:

groovy
1pipeline { 2 agent none 3 stages { 4 stage('Linux') { 5 agent { 6 label 'linux' 7 } 8 steps { 9 echo "Hello, $USER" 10 } 11 } 12 stage('Windows') { 13 agent { 14 label 'windows' 15 } 16 steps { 17 echo "Hello, %USERNAME%" 18 } 19 } 20 } 21}

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1linux_job: 2 stage: build 3 tags: 4 - linux 5 script: 6 - echo "Hello, $USER" 7 8windows_job: 9 stage: build 10 tags: 11 - windows 12 script: 13 - echo "Hello, %USERNAME%"

产物#

在极狐GitLab 中,任何作业都可以使用 artifacts 关键词来定义作业完成时要存储的一组产物。产物是可以在后续作业中使用的文件,例如用于测试或部署。

例如,在 Jenkinsfile 中:

groovy
1stages { 2 stage('Generate Cat') { 3 steps { 4 sh 'touch cat.txt' 5 sh 'echo "meow" > cat.txt' 6 } 7 post { 8 always { 9 archiveArtifacts artifacts: 'cat.txt' 10 onlyIfSuccessful: true 11 } 12 } 13 } 14 stage('Use Cat') { 15 steps { 16 sh 'cat cat.txt' 17 } 18 } 19 }

对应的极狐GitLab CI/CD .gitlab-ci.yml 文件为:

yaml
1stages: 2 - generate 3 - use 4 5generate_cat: 6 stage: generate 7 script: 8 - touch cat.txt 9 - echo "meow" > cat.txt 10 artifacts: 11 paths: 12 - cat.txt 13 expire_in: 1 week 14 15use_cat: 16 stage: use 17 script: 18 - cat cat.txt 19 artifacts: 20 paths: 21 - cat.txt

缓存#

当作业下载一个或多个文件并将其保存以供将来更快访问时,就会创建缓存。后续使用相同缓存的作业无需再次下载这些文件,因此执行速度更快。缓存存储在 Runner 上,如果启用了分布式缓存,还会上传到 S3。Jenkins 核心不提供缓存功能。

例如,在 .gitlab-ci.yml 文件中:

yaml
1cache-job: 2 script: 3 - echo "This job uses a cache." 4 cache: 5 key: binaries-cache-$CI_COMMIT_REF_SLUG 6 paths: 7 - binaries/

Jenkins 插件#

Jenkins 中通过插件启用的一些功能在极狐GitLab 中通过提供类似功能的关键词和特性原生支持。例如:

安全扫描功能#

你可能在 Jenkins 中使用过插件来实现代码质量、安全或静态应用扫描等功能。极狐GitLab 提供开箱即用的安全扫描器,可在 SDLC 的各个部分检测漏洞。你可以使用模板将这些插件添加到极狐GitLab 中。例如,要将 SAST 扫描添加到你的流水线中,请将以下内容添加到你的 .gitlab-ci.yml

yaml
include: - template: Jobs/SAST.gitlab-ci.yml

你可以通过 CI/CD 变量自定义安全扫描器的行为,例如使用 SAST 扫描器

密钥管理#

特权信息,通常称为“密钥”,是你在 CI/CD 工作流中需要的敏感信息或凭证。你可能使用密钥来解锁工具、应用程序、容器和云原生环境中的受保护资源或敏感信息。

Jenkins 中的密钥管理通常通过 Secret 类型字段或 Credentials 插件处理。存储在 Jenkins 设置中的凭证可以通过 Credentials Binding 插件作为环境变量暴露给作业。

对于极狐GitLab 的密钥管理,你可以使用一个支持的外部服务集成。这些服务将密钥安全地存储在极狐GitLab 项目之外,但你必须有该服务的订阅。

极狐GitLab 也支持 OIDC 认证,适用于支持 OIDC 的其他第三方服务。

此外,你可以通过将凭证存储在 CI/CD 变量中来使其对作业可用,但以明文形式存储的密钥容易意外泄露,与在 Jenkins 中一样。你应始终将敏感信息存储在被屏蔽受保护的变量中,这可以减轻一些风险。

同时,切勿将密钥作为变量存储在 .gitlab-ci.yml 文件中,因为该文件对所有可以访问项目的用户公开。存储敏感信息在变量中应仅在项目、群组或实例设置中进行。

请查看安全指南,以提高 CI/CD 变量的安全性。

规划并执行迁移#

以下推荐步骤清单是根据观察到能够快速完成此迁移的组织而创建的。

创建迁移计划#

在开始迁移之前,你应该创建一个迁移计划,为迁移做好准备。对于从 Jenkins 迁移,请思考以下问题:

  • Jenkins 中的作业目前使用了哪些插件?
    • 你是否确切了解这些插件的功能?
    • 是否有任何插件封装了一个常用的构建工具?例如 Maven、Gradle 或 NPM?
  • Jenkins 代理上安装了哪些软件?
  • 是否有正在使用的共享库?
  • 你是如何从 Jenkins 进行身份验证的?你是在使用 SSH 密钥、API 令牌还是其他密钥?
  • 是否需要从你的流水线访问其他项目?
  • Jenkins 中是否有用于访问外部服务的凭证?例如 Ansible Tower、Artifactory 或其他云提供商或部署目标?

前提准备#

在进行任何迁移工作之前,你应该首先:

  1. 熟悉极狐GitLab。
  2. 设置并配置极狐GitLab。
  3. 测试你的极狐GitLab 实例。
    • 确保Runner可用,可以通过使用共享的极狐GitLab.com Runner 或安装新的 Runner 来实现。

迁移步骤#

  1. 将项目从您的 SCM 解决方案迁移到极狐GitLab。
  2. 在每个项目中创建一个 .gitlab-ci.yml 文件。
  3. 将 Jenkins 配置迁移到极狐GitLab CI/CD 作业中,并对其进行配置以直接在合并请求中显示结果。
  4. 使用云部署模板环境极狐GitLab Kubernetes Agent迁移部署作业。
  5. 检查是否有任何 CI/CD 配置可在不同项目中重用,然后创建并共享 CI/CD 模板。
  6. 查看流水线效率文档,了解如何使您的极狐GitLab CI/CD 流水线更快、更高效。

额外资源#

  • 您可以使用 JenkinsFile Wrapper 在极狐GitLab CI/CD 作业中运行完整的 Jenkins 实例,包括插件。通过此工具,您可以推迟迁移不太紧急的流水线,从而帮助简化向极狐GitLab CI/CD 的过渡。

    JenkinsFile Wrapper 未与极狐GitLab 打包在一起,不在支持范围内。 更多信息,请参阅支持声明

如果您的问题在这里没有得到解答,极狐GitLab 社区论坛可能会是一个很好的资源。