Jenkinsからの移行

多くのGitLabユーザーが、JenkinsからGitLab CI/CDへの移行に成功しています。JenkinsからGitLabへ移行する前に、GitLab導入の参考となる資料を集めました。このページは「Jenkinsユーザ向けのGitLab CI/CD」ガイドと考えてください。

次のリストは推奨される移行手順です。迅速にJenkinsから移行完了した例を参考として作成されました。

  1. まずはGitLab CI/CDクイックスタートガイド重要な製品の違いを読むことから始めましょう。
  2. 組織移行管理の重要性を学びます。
  3. GitLabインスタンスにRunnerを追加します。
  4. 開発者が、プロ​​ジェクトで次のステップを自身で実行できるように教育します。
    1. クイックスタートガイドパイプライン構成リファレンスを確認します。
    2. Jenkinsラッパーを使用することで、Jenkinsジョブを変更なく一時的に維持できます。
    3. ビルドジョブとCIジョブを移行し、マージリクエストに直接結果を表示するように設定します。Auto DevOpsを出発点として使用し、必要に応じて設定をカスタマイズまたは分割できます。
    4. レビューアプリを追加します。
    5. クラウドデプロイメントテンプレートを使用したデプロイメントジョブの移行、環境の追加、デプロイボードの追加の3つを実行します。
    6. まだJenkinsラッパーを使用して動作しているジョブを、ラッパー無しで動作するよう修正します。
  5. 一般的なCI/CDジョブの定義を把握し、それらのテンプレートを作成して共有します。

JenkinsのパイプラインをGitLabのCI/CDパイプラインに変換する方法や、Auto DevOpsを使ってコードを自動的にテストする方法の例については、Migrating from Jenkins to GitLabのビデオをご覧ください。

それ以外にも、GitLabを利用するための重要な情報をお読みください。

ここで質問の答えが見つからない場合は、GitLab コミュニティフォーラムを利用すると良いでしょう。

組織として移行を管理する

JenkinsからGitLabへの移行で重要なのは、移行に伴う文化的・組織的な変化と、それをうまく管理することです。このために役立つことを挙げます。

  • 移行の目標が何であるかを明確に設定し伝えることで、その努力がなぜ価値のあるものなのかをユーザーに理解してもらいます。作業が完了した時点で価値は明らかになりますが、作業が進行している間も人々はそれを認識する必要があります。
  • 関連する経営陣からの支援と調整は、上記の点でに役立ちます。
  • 何が違うのかを教育するため、この文書の共有などユーザーを育てることに時間をかけることで、成功を確実にできます。
  • 移行の順序を決めたり、遅延させたりする方法を見つけることは非常に有効です。しかし、移行していない(または部分的に移行した)状態を長く放置しておくことは避けたいです。GitLabのすべての利点を得るためには、現在の問題点を含めて既存のJenkinsのセットアップをそのまま移行するだけでは十分でありません。GitLabが提供する改善点を活用する必要があり、そのため(最終的)には移行の一環として実装を更新する必要があります。

JenkinsFile Wrapper

私たちは、プラグインを含むGitLabジョブ内で完全なJenkinsインスタンスを実行できるJenkinsFile Wrapperを構築しています。これにより、緊急性の低いパイプラインの移行を一定期間遅らせることができ、移行のプロセスを容易にできます。

GitLabのラッパーのテストに興味がある方は、公開テストに参加して説明を聞いたり、フィードバックを提供したりしてください。

重要な製品の違い

価値ある製品間には、いくつか高レベルの違いがあります。

  • GitLabを使えば、すべてを意味するルートpipelineキーワードは必要ありません。
  • パイプラインをトリガーしたり、他のパイプラインをトリガーする方法はJenkinsとは異なります。GitLabのパイプラインは、以下の方法でトリガーできます。

  • rules構文を使い、どのジョブがどのようにトリガーされるかによって、どのジョブがどの条件で実行されるかを制御できます。
  • GitLabのパイプラインのスケジューリングコンセプトもJenkinsとは異なります。
  • includeキーワードテンプレートを使用して、パイプライン設定を再利用できます。テンプレートは、中央リポジトリに(異なる権限で)保存し、どのプロジェクトでも使用できます。このセントラルプロジェクトには、スクリプトやその他の再利用可能なコードが含まれている可能性があります。
  • extendsキーワードを使用して、単一のパイプライン設定内で設定を再利用できます。
  • 1つのステージ内のすべてのジョブは常に並列に実行され、すべてのステージは順番に実行されます。有向非巡回グラフの特徴を利用して、必要に応じてこの順番を変更できるようにする計画を立てています。
  • parallelキーワードは、並列化をサポートするテストのようなタスクを自動的に並列化できます。
  • 通常1つのステージ内のすべてのジョブは並列に実行され、すべてのステージは順番に実行されます。
  • 新しいrules構文は、異なるジョブの実行時に制御するために推奨される方法です。これはonly/except構文よりも強力です。
  • 重要な違いは、ジョブは互いに独立して実行され、各ジョブ内に新しい環境が作成されることです。ジョブ間でアーティファクトを受け渡しするには、キーワードartifactsdependenciesを使用します。ジョブが完了したとき、計画されているWorkspaces機能で、連続したジョブ間で共通のワークスペースをより簡単に永続化できます。
  • .gitlab-ci.ymlファイルはリポジトリのルートにチェックインされ、Jenkinsfileと似ていますがGroovy DSLの代わりにYAML形式を使用します(完全なリファレンスを参照してください)。このファイルは、宣言型のJenkinsfile形式に最も似ています。
  • 手動承認またはゲートは、when:manualジョブとして設定できます。これらは保護された環境を活用して、誰が承認できるかを制御できます。
  • GitLabにはコンテナレジストリが付属しており、コンテナイメージを使ってビルド環境を設定することをお勧めします。例えば、あるパイプラインでビルド環境を自分で構築し、それをコンテナレジストリに公開します。その後、各パイプラインで独自に環境を構築するのではなく、コンテナを使ってビルド環境を構築するようにします。コンテナレジストリの使い方については、豊富なドキュメントがあります。
  • 中央のユーティリティリポジトリは、スケジュールされたジョブやユーティリティのような機能を持つ手動ジョブを配置するのに最適な場所となります。Jenkinsのインストールでは、このようなジョブを持つ傾向があります。

AgentとRunnerの比較

Jenkins AgentとGitLab Runnersは、両方ともジョブを実行するホストです。Jenkins Agentを変換するには、Jenkins AgentをアンインストールしてからGitLab Runnerをインストールして登録するだけです。Runnerはオーバーヘッドをあまり必要としないので、使用していたJenkins agentと同じようなサイズにできます。

Runnerの動作には、Agentと比較して重要な違いがあります。

gitlab.comを使用している場合は、共有のRunnerを利用して、自分のRunnerを用意せずにジョブを実行できます。セルフマネージド型のインスタンスでも利用できるようにすることを検討しています。

GroovyとYAMLの比較

JenkinsのパイプラインはGroovyをベースにしているので、パイプラインの仕様はコードとして書かれています。GitLabの動作は少し異なり、より高度に構造化されたYAML形式を使用しています。

これはGitLabの強みであり、学習曲線をよりシンプルにして運用できます。Jenkinsfileを理解して管理するのが難しくなるような、煩雑さの問題を回避できます。

DRY(don’t repeat yourself)の原則に従って、ジョブの振る舞いを一箇所で定義して、必要に応じて再利用できます。extends:構文を使って、ジョブ内の設定を再利用することができますし、include: を使って、パイプライン内の設定を異なるプロジェクトで再利用することもできます。

.in-docker:
  tags:
    - docker
  image: alpine

rspec:
  extends:
    - .in-docker
  script:
    - rake rspec

アーティファクトでの成果物

アーティファクトは、Jenkinsで使用した場合とは少し異なる動作をするかもしれません。GitLabでは、どのジョブでもartifacts:キーワードを使用して、保存するアーティファクトを定義できます。アーティファクトはファイルやファイル一覧を指すように設定でき、ジョブ間で永続化できます。詳しくは、アーティファクトのドキュメントを参照ください。

pdf:
  script: xelatex mycv.tex
  artifacts:
    paths:
      - ./mycv.pdf
      - ./output/
    expire_in: 1 week

さらに、組み込みのコンテナレジストリ、NPMレジストリ、Mavenレジストリなどのパッケージ管理機能を利用できます。パッケージ機能の完全なリスト(ドキュメントへのリンクを含む)は、ドキュメント内の「パッケージ」セクションで確認できます。

統合された機能

プラグインを使ってコードの品質やユニットテスト、セキュリティスキャンなどをJenkinsで行っていた場合、GitLabはエコシステムとの連携を利用して、これらの結果を自動的にマージリクエストやパイプラインの詳細ページ、その他の場所に取り込むことができます。これらの結果を表示させるために、実際には何も設定する必要がない可能性があります。

期待通りに動作しない場合や、利用可能な機能を確認したい場合は、CI機能の索引に利用可能な機能の一覧と、それぞれのドキュメントへのリンクが掲載されています。

テンプレート

高度なCI/CDチームにとって、プロジェクトテンプレートはパイプライン構成の再利用を可能にするだけでなく、内製化を促進します。

セルフマネージド型のGitLabインスタンスでは、インスタンステンプレートリポジトリを構築できます。組織全体の開発チームは、ドロップダウンメニューからテンプレートを選択できます。グループ管理者は、カスタムプロジェクトテンプレートのソースとして使用するグループを設定でき、グループ内のすべてのプロジェクトで使用できます。インスタンス管理者は、インスタンスプロジェクトテンプレートのソースとしてグループを設定できます。

宣言的Jenkinsfileの変換

宣言型のJenkinsfileには”Section”と”Directives” が含まれており、これらはパイプラインの動作を制御するために使用されます。GitLabにはこれらすべてに相当するものがあります。

このセクションでは、Jenkinsfileの構文ドキュメントに基づいて、GitLabの概念を紐付けすることを意図しています。

セクション

agent

エージェントセクションは、パイプラインの実行方法を定義するために使用します。GitLabでは、この機能を提供するためにGitLab Runnerを使用しています。Kubernetesや任意のホスト上で独自のRunner、またはGitLab.comの共有Runnerを利用できます(共有Runner はGitLab.comユーザーのみが利用できることに注意してください)。上のリンクをクリックすると、迅速に起動して実行する方法を説明したドキュメントが表示されます。またタグを使用して、異なるジョブを別のRunner(実行エージェント)に指示する方法もサポートしています。

agentセクションでは、実行に使用するDockerイメージをimageキーワードで定義できます。imageは単一のジョブ、またはトップレベルで設定できます。

my_job:
  image: alpine
  ...

post

postセクションでは、パイプラインの最後に実行すべきアクションを定義します。GitLabでは、ステージを使用してこれもサポートしています。ステージは以下のように定義でき、before_pipelineafter_pipelineのステージに割り当てられたジョブは、期待通りに実行されます。これらのステージは、好きなように呼び出せます。

stages:
  - before_pipeline
  - build
  - test
  - deploy
  - after_pipeline

ジョブの前後に実行するステップの設定は、before_scriptafter_scriptキーワードで行うことができます。

default:
  before_script:
    - echo "I run before any jobs starts in the entire pipeline, and can be responsible for setting up the environment."

stages

GitLab CI/CDでもステージを定義できますが、設定はもう少し自由です。GitLabのstagesキーワードはステージのリストを列挙するトップレベルの設定ですが、個々のジョブをstagesセクションの下に入れ子にする必要はありません。.gitlab-ci.ymlで定義されているジョブは、stage:キーワードを使用することで任意のステージの一部にできます。

特に指定がない限り、すべてのパイプラインはbuildtestdeployの順に実行されることに注意してください。stageが定義されていないジョブは、デフォルトでtestステージに配置されます。 もちろん、ステージを参照する各ジョブは、パイプライン構成に存在するステージを参照しなければなりません。

stages:
  - build
  - test
  - deploy

my_job:
  stage: build
  ...

steps

stepsセクションは個々のジョブのscriptセクションに相当します。これは単純なYAML配列で、各行は実行される個々のコマンドを表します。

my_job:
  script:
    - echo "hello! the current time is:"
    - time
  ...

ディレクティブ

environment

GitLabでは、実行時に変数を定義するためにvariablesキーワードを使用しています。これらは、GitLab UIからCI/CD設定で設定できます。特定の環境やRunnerに対して特定の変数へのアクセスを制限するために使用できる保護された変数のセクションを含む、変数に関する一般的なドキュメントも参照してください。

variables:
  POSTGRES_USER: user
  POSTGRES_PASSWORD: testing_password

options

ここでいうオプションは、オブジェクト自体に関連づけられた様々なオプションを指します。例えば、ジョブに関連したオプションは、ジョブ自体に関連して定義されています。特定のオプションを探している場合は、完全な設定リファレンスページを検索することで、そのオプションがどこにあるのかを見つけることができるはずです。

parameters

GitLabでは手動でのジョブ起動時に、使用する変数を定義する必要はありません。ユーザーは好きな変数を起動時に設定できます。

triggers / cron

GitLabはGitと密接に統合されているので、トリガーのSCMポーリングオプションは必要ありません。使いやすいパイプラインのスケジューリング構文をサポートしています。

tools

GitLabは個別のtoolsディレクティブをサポートしていません。私たちが推奨する最良の方法は、ビルド済みのコンテナイメージを使用することです。このイメージはキャッシュされ、パイプラインに必要なツールをあらかじめビルドしておくことができます。必要に応じてこのイメージを自動的にビルドし、コンテナレジストリにデプロイするようにパイプラインを設定できます。

MacやFreeBSDなどでDocker/Kubernetesを使ってコンテナイメージを使用していない場合、shell executerは環境を事前に設定しておくか、ジョブの一部として設定します。同じような処理を行うために、before_scriptアクションで設定できます。

input

parametersキーワードと同様に、手動ジョブでは常に変数の入力フォームが表示されるため、このキーワードは必要ありません。

when

GitLabはwhenキーワードをサポートしています。これはジョブが失敗した場合(あるいは失敗したにもかかわらず)、ジョブが終了するタイミングを示すために使用されます。しかし、パイプラインを制御するためのロジックのほとんどは、非常に強力なonly/exceptルールシステムにあります(高度な構文も参照してください)。

my_job:
  only: [branches]