GitLabのCI/CDを並列実行(Runnerを複数同時に実行)できるようにする手順のまとめとなります。
やることとしては、
- パイプラインのJOBを並列実行可能にする
- 並列実行した際にもキャッシュが利用できるようにする
- キャッシュにはGCS(Google Cloud Storage)を利用する
GitLab RunnerでのCI/CD環境の構築手順については下記を参照ください。
GitLab Runnerの並列処理数の変更
単純な並列処理数の変更だけであれば特に難しいことはなく、GitLab Runnerの設定ファイルを下記の通り変更します。
concurrent = 2
デフォルトでは1
が設定されているので、並列処理可能な上限値に変更してあげます。
数値についてはサーバーのスペックと相談ください。
設定を変更したら、一応GitLab Runnerを再起動しておきます。
$ sudo gitlab-runner restart
これでGitLabのパイプラインで、並列実行できるJOBは並列実行されるようになります。
共有キャッシュの設定
上記の手順で並列実行は可能となりましたが、JOBでキャッシュを利用する場合には共有キャッシュの設定が必要となります。
default:
image: node:16
tags:
- shared
cache:
key:
files:
- yarn.lock
paths:
- node_modules
stages:
- build
- test
build:
stage: build
script:
- yarn install -D
- yarn run build
lint:
stage: test
script:
yarn run lint
test:
stage: test
script:
yarn run test
例えば上記のような、build
で作成(yarn install
)したnode_modules
の内容をキャッシュし、lint
test
で利用するような場合です。
上記のパイプラインは下記のようになり、
まずbuild
が実行され、その後にlint
test
が並列で実行されます。
そして、共有キャッシュの設定を行わないままこれを実行すると、lint
かtest
のどちらかが失敗するはずです。
これは、一方はbuild
のキャッシュが利用できたので成功、もう一方はキャッシュが利用できずに失敗、という状態になります。
各JOBのログを確認すると、下記のようなログが出力されていると思います。
- build
Running on runner-xxx-concurrent-0 via gitlab-vm...
- lint
Running on runner-xxx-concurrent-0 via gitlab-vm...
- test
Running on runner-xxx-concurrent-1 via gitlab-vm...
ここで注目すべきはconcurrent-0 or 1
という部分です。
これは並列実行を可能にした為、RunnerA-0
RunnerA-1
という形でナンバリングされた2つのRunnerが実行されていることを意味します。
デフォルトのキャッシュはこのナンバリングされたRunner毎に保持する為、build
と同じRunnerが利用されたJOBは成功し、違う方は失敗するという理屈になります。
下記のようなログも出力されているはずです。
Restoring cache
Checking cache for 337fc97642de98f9e28d99f19d9781b6e69631fa-non_protected...
No URL provided, cache will not be downloaded from shared cache server. Instead a local version of cache will be extracted.
「共有キャッシュサーバーからダウンロードできないので、ローカルのキャッシュを利用します」的な内容です。
というわけで、これを解消するために共有キャッシュの設定を行います。
Cloud Storageにキャッシュ用のバケットを作成
Cloud Storageからバケットの作成。
キャッシュとしての利用なので、
- ロケーションタイプ:Region
- デフォルトストレージクラス:Standard
としています。
次に、キャッシュなので一定期間で削除するように設定しておきます。
バケットのライフサイクルにルールを追加します。
アクションは削除で
削除対象となる経過期間を設定します。
設定例として5日にしているのは、一週間(営業日で5日)保持すれば良いかなと。(次の週でも利用するなら再作成
ここは好きに設定してください。
バケットにアクセスする為のサービスアカウント作成
バケットを作成したら、そこにアクセスする為のサービスアカウントを作成します。
今回はGitLab Runner用として作成しています。
サービスアカウントを作成したら、バケットの権限タブから「アクセス権を付与」を行います。
プリンシパルには先ほど作成したサービスアカウントを指定します。
ロールは下記の2つを指定。
- Storage レガシー バケット オーナー
- Storage レガシー オブジェクト オーナー
次にサービスアカウントにキーを発行します。(GitLab Runnerの設定に使用するもの)
「鍵を追加」でJSONで作成します。
鍵を作成するとJSONファイルがダウンロードされますので、JSONファイルをGitLab Runnerのサーバに配置します。
下記ファイルを作成し、内容をコピペ。
$ sudo vim /etc/gitlab-runner/service-account.json
次にGitLab Runnerの設定ファイルを開いて、
$ sudo vim /etc/gitlab-runner/config.toml
下記の通り変更します。
[[runners]]
[runners.cache]
Type = "gcs"
Path = "cache"
Shared = true
[runners.cache.gcs]
CredentialsFile = "/etc/gitlab-runner/service-account.json"
BucketName = "funlab-gitlab-runners-cache"
公式のドキュメントだと下記になります。
設定したら再起動。
$ sudo gitlab-runner restart
これで共有キャッシュが利用されるようになったはずです。
JOBのログに下記のようなログが出力されていれば成功です。
Downloading cache.zip from https://storage.googleapis.com/xxx