- Shallow cloning
- Git strategy
- Gitクローンパス
- Git clean flags
- Git fetch extra flags
- フォークベースのワークフロー
- Git フェッチキャッシュステップ
大規模リポジトリ向けにGitLabを最適化
ワークツリー内のファイルが50kを超えるような大規模リポジトリでは、クローンやチェックアウトに時間がかかるため、パイプラインの効率を超えた最適化が必要になることがあります。
GitLabとGitLab Runnerはこのシナリオをうまく処理しますが、一連のオペレーションを効率的に実行するために最適化された設定が必要です。
大きなリポジトリを扱うための一般的なガイドラインはシンプルです。各ガイドラインは以下のセクションで詳しく説明します:
- 常にインクリメンタルにフェッチしてください。ワークツリーをすべて再作成するようなクローンはしないでください。
- データ転送を減らすために常にシャロークローンを使用してください。CPUへの影響が大きくなるため、GitLabインスタンスに負担がかかることに注意してください。
- フォークベースのワークフローを多用する場合は、クローンディレクトリを制御してください。
-
git clean
フラグを最適化し、ビルドに影響したり高速化したりする可能性のあるデータを確実に削除または保持します。
Shallow cloning
GitLab Runner 8.9で導入されました。
GitLab と GitLab Runner はデフォルトでシャロークローンを行います。
理想的には、常にGIT_DEPTH
10のような小さな数字を GIT_DEPTH
使うべきです。GIT_DEPTH
これは GitLab Runner に浅いクローンを実行するように指示します。シャロークローンは、変数で定義したコミット数までのブランチの最新の変更のみを Git にリクエスト GIT_DEPTH
させます。
これにより、Gitリポジトリからの変更の取得が大幅に高速化されます。特に、リポジトリに大きなファイルからなる非常に長いバックログがある場合は、データ転送量を効果的に減らすことができます。
次の例では、Runner をシャロークローンにして指定したブランチだけを取得するようにしています。他のブランチやタグは取得しません。
variables:
GIT_DEPTH: 10
test:
script:
- ls -al
Git strategy
GitLab Runner 8.9で導入されました。
デフォルトでは、GitLab はfetch
Git 戦略 を使うように設定されており、大規模なリポジトリに推奨されています。このストラテジーは転送するデータ量を減らし、CIからリポジトリに対して行うオペレーションにはあまり影響を与えません。
Gitクローンパス
GitLab Runner 11.10で導入されました。
GIT_CLONE_PATH
を使うと、ソースをクローンする場所をコントロールできるようになります。これはフォークワークフローで大きなリポジトリを多用する場合に意味があります。
GitLab Runnerから見たフォークワークフローは、別々のリポジトリと別々のワークツリーとして保存されます。つまり、GitLab Runnerはワークツリーの使い方を最適化することができないので、GitLab Runnerに指示する必要があるかもしれません。
このような場合、理想的にはGitLab Runnerのエクゼキューターを指定されたプロジェクトにのみ使用し、異なるプロジェクトで共有しないようにして、このプロセスをより効率的にしたいものです。
GIT_CLONE_PATH
$CI_BUILDS_DIR
現在のところ、ディスクから任意のパスを選ぶことはできません。
Git clean flags
GitLab Runner 11.10で導入されました。
GIT_CLEAN_FLAGS
では、各 CI ジョブでgit clean
コマンドを実行するかどうかを制御できます。デフォルトでは、GitLab は指定された SHA にワークツリーがあり、リポジトリがクリーンであることを保証します。
GIT_CLEAN_FLAGS
をnone
に設定すると無効になります。非常に大きなリポジトリでは、git
clean
がディスク I/O を大量に消費するため、これが望ましいかもしれません。GIT_CLEAN_FLAGS: -ffdx
-e .build/
(例) でこれを制御すると、後続の実行の間にワークツリー内のいくつかのディレクトリの削除を制御して無効にすることができ、インクリメンタルビルドを高速化することができます。これは、既存のマシンを再利用し、ビルドに再利用できる既存のワークツリーがある場合に最大の効果を発揮します。
GIT_CLEAN_FLAGS
が受け付ける正確なパラメータについては、git clean
のドキュメントを参照ください。利用可能なパラメーターは Git のバージョンに依存します。
Git fetch extra flags
GitLab Runner 13.1 で導入されました。
GIT_FETCH_EXTRA_FLAGS
を使うと、フラグを追加してgit fetch
の挙動を変更することができます。
たとえば、プロジェクトにCIジョブが依存しないタグが大量に含まれている場合、--no-tags
を追加フラグに追加することで、フェッチをより高速かつコンパクトにすることができます。
また、リポジトリにタグがあまり含まれて_いない_場合、--no-tags
、場合によっては大きな違いが生まれます。CIビルドがGitタグに依存していないのであれば、試してみる価値はあるでしょう。
詳しくはGIT_FETCH_EXTRA_FLAGS
ドキュメント を参照してください。
フォークベースのワークフロー
GitLab Runner 11.10で導入されました。
上記のガイドラインに従って、私たちがしたいことを想像してみましょう:
- 大きなプロジェクト(ディレクトリに50kファイル以上)の最適化。
- 貢献するためにフォークベースのワークフローを使用します。
- 既存のワークツリーを再利用。リポジトリと一緒にクローンされるランナーをあらかじめ設定しておきます。
- プロジェクトとすべてのフォークにのみ割り当てられたランナー。
shell
Executor を使った例とdocker
Executor を使った例を考えてみましょう。
shell
エクゼキュータの例
次のようなconfig.toml
があるとします。
concurrent = 4
[[runners]]
url = "GITLAB_URL"
token = "TOKEN"
executor = "shell"
builds_dir = "/builds"
cache_dir = "/cache"
[runners.custom_build_dir]
enabled = true
このconfig.toml
:
-
shell
Executor を使用します、 - すべてのクローンが保存されるカスタム
/builds
ディレクトリを指定します。 -
GIT_CLONE_PATH
を指定できるようにします、 - 一度に最大4つのジョブを実行します。
docker
エクゼキュータの例
次のようなconfig.toml
があるとします。
concurrent = 4
[[runners]]
url = "GITLAB_URL"
token = "TOKEN"
executor = "docker"
builds_dir = "/builds"
cache_dir = "/cache"
[runners.docker]
volumes = ["/builds:/builds", "/cache:/cache"]
このconfig.toml
:
-
docker
Executor を使用します、 -
/builds
すべてのクローンを格納するディスク上の/builds
カスタム/builds
ディレクトリを/builds
指定します。このディレクトリを/builds
マウント/builds
することで、次回以降の実行時に再利用できるようにし、クローン戦略を上書きできるようにします。 - デフォルトで有効になっているため、
GIT_CLONE_PATH
を指定する機能は有効になりません。 - 一度に最大4つのジョブを実行します。
私たちの.gitlab-ci.yml
Executor の設定ができたら、.gitlab-ci.yml
を微調整する必要があります。
このパイプラインは、以下の.gitlab-ci.yml
:
variables:
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_NAME
build:
script: ls -al
このYAML設定はカスタムクローンパスを設定します。すべてのフォークで同じクローンパスを使うので、このパスによって親プロジェクトとフォーク間でワークツリーを再利用できます。
なぜ使う$CI_CONCURRENT_ID
のですか?主な理由は、使用するワークツリーがプロジェクト間で競合しないようにするためです。これは $CI_CONCURRENT_ID
、指定されたエクゼキューター内で一意な識別子を表します。これを使用してパスを構築すると、このディレクトリが他の同時実行ジョブと衝突することはありません。
カスタムクローンオプションをconfig.toml
理想的には、すべてのジョブ関連の設定は.gitlab-ci.yml
に保存されるべきです。 しかし、これらのスキームをランナーの設定の一部にすることが望ましい場合もあります。
上記のForksの例では、この設定をユーザーが発見できるようにすることが望ましいかもしれませんが、これはブランチごとに.gitlab-ci.yml
を更新する必要があるため、管理上のオーバーヘッドをもたらします。このような場合、.gitlab-ci.yml
クローン経路は不可知論とし、Runnerの設定とすることが望ましいでしょう。
.gitlab-ci.yml
がオーバーライドしない場合、ランナーによって使用される以下の仕様でconfig.toml
を拡張することができます:
concurrent = 4
[[runners]]
url = "GITLAB_URL"
token = "TOKEN"
executor = "docker"
builds_dir = "/builds"
cache_dir = "/cache"
environment = [
"GIT_CLONE_PATH=$CI_BUILDS_DIR/$CI_CONCURRENT_ID/$CI_PROJECT_NAME"
]
[runners.docker]
volumes = ["/builds:/builds", "/cache:/cache"]
これにより、クローン設定は与えられたRunnerの一部となり、.gitlab-ci.yml
を更新する必要はありません。
Git フェッチキャッシュステップ
非常にアクティブなリポジトリで大量の参照やファイルがある場合は、Gitaly の pack-objects キャッシュを使うことを検討しましょう。pack-objects キャッシュ:
- GitLabサーバー上のすべてのリポジトリに恩恵を与えます。
- 自動的にフォークを行います。