パイプラインアーキテクチャ
パイプラインは、GitLabにおけるCI/CDの基本的な構成要素です。 このページでは、パイプラインに関連する重要な概念を説明します。
パイプラインは様々な方法で構成することができ、それぞれに利点があります。必要に応じて、これらの方法を混ぜて使うこともできます:
- 基本: すべての設定が一か所に集まっている単純なプロジェクトに適しています。
- Directed Acyclic Graph:効率的な実行を必要とする大規模で複雑なプロジェクトに適しています。
-
親子パイプライン:モノレポや、独立に定義されたコンポーネントの多いプロジェクトに適しています。
概要については、親子パイプライン機能のデモを参照してください。
-
マルチプロジェクトパイプライン:マイクロサービスアーキテクチャのように、プロジェクト間の相互依存が必要な大規模なプロジェクトに適しています。
例えば、3つの異なる GitLab プロジェクトからウェブアプリケーションをデプロイするような場合です。マルチプロジェクトパイプラインを使えば、それぞれのプロジェクトでパイプラインをトリガーし、それぞれにビルド、テスト、デプロイのプロセスを持たせることができます。プロジェクト間の相互依存関係を含め、接続されたパイプラインを一箇所で可視化できます。
概要については、マルチプロジェクトパイプラインのデモを参照してください。
基本的なパイプライン
基本パイプラインはGitLabで最もシンプルなパイプラインです。ビルドステージですべてを並行して実行し、ビルドステージがすべて終了したらテストステージ以降も同じように実行します。最も効率的とは言えませんし、ステップがたくさんあるとかなり複雑になってしまいますが、メンテナーは簡単です:
/.gitlab-ci.yml
パイプラインの基本的な設定例です:
stages:
- build
- test
- deploy
default:
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
build_b:
stage: build
script:
- echo "This job builds something else."
test_a:
stage: test
script:
- echo "This job tests something. It will only run when all jobs in the"
- echo "build stage are complete."
test_b:
stage: test
script:
- echo "This job tests something else. It will only run when all jobs in the"
- echo "build stage are complete too. It will start at about the same time as test_a."
deploy_a:
stage: deploy
script:
- echo "This job deploys something. It will only run when all jobs in the"
- echo "test stage complete."
environment: production
deploy_b:
stage: deploy
script:
- echo "This job deploys something else. It will only run when all jobs in the"
- echo "test stage complete. It will start at about the same time as deploy_a."
environment: production
有向非環状グラフのパイプライン
効率を重視し、すべてをできるだけ早く実行したい場合は、有効非巡回グラフ(DAG) を使用できます。needs
キーワードを使ってジョブ間の依存関係を定義します。GitLabがジョブ間の関係を把握していれば、可能な限りすべてを高速に実行することができ、可能な限り後続のステージにスキップすることもできます。
下の例では、build_a
とtest_a
がbuild_b
とtest_b
よりもずっと速い場合、GitLab はbuild_b
がまだ実行中であってもdeploy_a
を開始します。
図と一致するDAG/.gitlab-ci.yml
の設定例:
stages:
- build
- test
- deploy
default:
image: alpine
build_a:
stage: build
script:
- echo "This job builds something quickly."
build_b:
stage: build
script:
- echo "This job builds something else slowly."
test_a:
stage: test
needs: [build_a]
script:
- echo "This test job will start as soon as build_a finishes."
- echo "It will not wait for build_b, or other jobs in the build stage, to finish."
test_b:
stage: test
needs: [build_b]
script:
- echo "This test job will start as soon as build_b finishes."
- echo "It will not wait for other jobs in the build stage to finish."
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "Since build_a and test_a run quickly, this deploy job can run much earlier."
- echo "It does not need to wait for build_b or test_b."
environment: production
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo "Since build_b and test_b run slowly, this deploy job will run much later."
environment: production
親子パイプライン
パイプラインが複雑になるにつれ、いくつかの関連する問題が浮上し始めます:
- ステージ構造では、次のステージの最初のジョブを開始する前に、ステージ内のすべてのステップを完了する必要があるため、待ち時間が発生し、処理が遅くなります。
- 単一のグローバルパイプラインの設定が管理しにくくなります。
-
include
を持つインポートは設定の複雑さを増し、意図せずにジョブが重複する名前空間の衝突を引き起こす可能性があります。 - パイプラインUXは扱うジョブやステージが多すぎます。
加えて、パイプラインのふるまいをよりダイナミックにする必要があることもあります。特にYAMLが動的に生成される場合、サブパイプラインを開始する(もしくは開始しない)ことを選択できる機能は強力です。
上記の基本パイプラインと 有効非巡回グラフの例では、独立してビルドできる2つのパッケージがあります。これらのケースは親子パイプラインを使うのに理想的です。設定を複数のファイルに分け、よりシンプルに保つことができます。親子パイプラインを組み合わせることができます:
-
rules
キーワード :例えば、その領域に変更があったときだけ、子パイプラインがトリガーされるようにします。 -
include
キーワード: 共通のビヘイビアを取り込み、同じことを繰り返さないようにします。 - DAGパイプラインを子パイプラインの内側に配置することで、両者のメリットを実現しています。
/.gitlab-ci.yml
ダイアグラムに一致する親パイプラインの設定例:
stages:
- triggers
trigger_a:
stage: triggers
trigger:
include: a/.gitlab-ci.yml
rules:
- changes:
- a/*
trigger_b:
stage: triggers
trigger:
include: b/.gitlab-ci.yml
rules:
- changes:
- b/*
/a/.gitlab-ci.yml
にある、DAGneeds
キーワードを使用した子a
パイプライン設定例:
stages:
- build
- test
- deploy
default:
image: alpine
build_a:
stage: build
script:
- echo "This job builds something."
test_a:
stage: test
needs: [build_a]
script:
- echo "This job tests something."
deploy_a:
stage: deploy
needs: [test_a]
script:
- echo "This job deploys something."
environment: production
/b/.gitlab-ci.yml
にある、DAGneeds
キーワードを使用した子b
パイプライン設定例:
stages:
- build
- test
- deploy
default:
image: alpine
build_b:
stage: build
script:
- echo "This job builds something else."
test_b:
stage: test
needs: [build_b]
script:
- echo "This job tests something else."
deploy_b:
stage: deploy
needs: [test_b]
script:
- echo "This job deploys something else."
environment: production
ジョブはGitLabの子パイプラインをトリガーする前や後に実行するように設定することができ、共通のセットアップステップや統一されたデプロイを可能にします。