Shared Runner , self-Managed Runner 間キャッシュ共有の方法
GitLab CI で self-Managed Runner を構築していたら、キャッシュの受け渡しが上手く動かなかったので、模索した話
tl;dr
- Shared,self-Managed 間は
cache
ではなくartifacts
を使おう -
artifacts
をやりとりするjob
は必ず後に実行されるようにしよう - 受け取り側のjobは
dependencies
を使おう。stageを後ろにしても良い - Runner 間のデータのやり取りのTopicはマニュアルには書いてなさそう
やりたいこと
Shared Runner
で ビルドした生成物を キャッシュの受け渡しで self-Managed Runner
に渡してデプロイしたい
背景
元々開発環境にはJenkinsを入れて、ビルド&デプロイをしていたんですが...
- 開発環境側でビルドする必要もない
- Node.js系のビルドは回数を重ねるとメモリを圧迫して定期的な再起動が必要
ってところが課題に上がっていてCIツール側でビルドしてからデプロイしたい、
GitLab CIに寄せたいと言うことで、
開発環境のインスタンスに Runner Install して、既に組んであるパイプラインに開発環境のデプロイフローを追加したくなりました。
とりあえずデプロイしてみる
と言うわけでとりあえずRunner登録して、デプロイしてみる
Shared Runner のCacheが取れない
Checking cache for caches-feature/ci/change_ci_path-36148020-npm-18-nuxt3_output-non_protected...
No URL provided, cache will not be downloaded from shared cache server. Instead a local version of cache will be extracted.
- Shared Runner にあった、Google Storageへのリンクが取れない
Checking cache for caches-feature/ci/change_ci_path-36148020-npm-18-nuxt3-non_protected...
Downloading cache from https://storage.googleapis.com/gitlab-com-runners-cache/project/36148020/caches-feature/ci/change_ci_path-36148020-npm-18-nuxt3-non_protected
Successfully extracted cache
どうもマニュアルを調べたところ self-Managed Runner のconfig.toml の設定をShared Runner のGCS設定に揃える必要がある様子。
参考:The [runners.cache.gcs] section
[runners.cache]
Type = "gcs"
Path = "path/to/prefix"
Shared = false
[runners.cache.gcs]
AccessID = "cache-access-account@test-project-123456.iam.gserviceaccount.com"
PrivateKey = "-----BEGIN PRIVATE KEY-----\nXXXXXX\n-----END PRIVATE KEY-----\n"
BucketName = "runners-cache"
ということで取得できないのでcache
指定は使えない となると、他の選択肢は
-
artifacts
を使う - 自前でHost する
ぐらいかなと思う。
S3/R2などにHostしてもいいけど、どうせならGitLabで完結したいので、artifacts
を使う方向で考える
APIでartifactsを取得してみる
まず、Job Artifacts APIがあるので、試してみる。
artifact_download:
stage: test
script:
- 'curl --location --output artifacts.zip --header "JOB-TOKEN: $CI_JOB_TOKEN" "https://gitlab.example.com/api/v4/projects/1/jobs/42/artifacts"'
JOB-TOKENしてもあり、これが正式な方法なのかな?って思いつつハードコーディングされているところを変数に落とし込んで、
curl --verbose\
--location\
--output artifacts.zip\
--header "JOB-TOKEN: $CI_JOB_TOKEN"\
"$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/jobs/$CI_JOB_ID/artifacts"
こんな感じで、やってみる。
上手くいかない・・・
どうも
artifactsを作るJobと受け取るJobで、IDが別なのでJob IDを指定できない
ってことで他の手がないかちょっと考える
ChatGPT先生に聞いてみる
ChatGPT先生に確認してみたら、この手法が良さそうだったので試してみる
-
アーティファクトを使用する方法:
- 最初のジョブで、必要な情報を含むファイルを生成してアーティファクトとして保存します。
- 次のジョブで、アーティファクトを取得し、その情報を使用します。
例えば、最初のジョブでファイルを生成し、アーティファクトとして保存するコマンドは以下のようになります:
job1: script: - echo "ジョブID: $CI_JOB_ID" > job_info.txt artifacts: paths: - job_info.txt
次のジョブでアーティファクトを取得するコマンドは以下のようになります:
job2: script: - cat job_info.txt dependencies: - job1
参考:dependencies
In this example, two jobs have artifacts: build osx and build linux. When test osx is executed,
the artifacts from build osx are downloaded and extracted in the context of the build.The same thing happens for test linux and artifacts from build linux.
The deploy job downloads artifacts from all previous jobs because of the stage precedence.
-
dependencies
でartifacts
を生成しているjobを指定するとダウンロードして展開する - 後段の
stage
は 前stage
までに作られたartifacts
全てをダウンロードして展開する
dependencies
を使ってみる
結論から言うと上手くいった。
generate:
stage: build
needs: [ "prepare" ]
script:
- npx nuxt generate
cache:
- key: caches-$CI_COMMIT_REF_NAME-$CI_PROJECT_ID-$JS_PKG-$NODE_VER-node_modules
paths:
- node_modules
policy: pull
- key: caches-$CI_COMMIT_REF_NAME-$CI_PROJECT_ID-$JS_PKG-$NODE_VER-nuxt3
paths:
- .nuxt
policy: pull
artifacts:
name: caches-$CI_COMMIT_REF_NAME-$CI_PROJECT_ID-$JS_PKG-$NODE_VER-nuxt3_output
paths:
- .output
deploy:instance:dev:
stage: deploy
needs: [ "generate"]
variables:
GIT_STRATEGY: none
dependencies:
- generate
before_script:
- rm -rf /var/www/git-vue
- mkdir /var/www/git-vue
script:
- cp -r ./.output /var/www/git-vue/
- ls -la /var/www/git-vue/
tags:
- $CI_DEPLOY_DEV_TAG
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
手順
-
generate
ジョブで.output
をartifacts
に -
dependencies
をgenerate
に設定し、artifactsをダウンロードできるようにする
ログ
Downloading artifacts for generate (5139095646)...
Downloading artifacts from coordinator... ok host=cdn.artifacts.gitlab-static.net id=5139095646 responseStatus=200 OK token=64_GGSVJ
Executing "step_script" stage of the job script
$ rm -rf /var/www/git-vue
$ mkdir /var/www/git-vue
$ cp -r ./.output /var/www/git-vue/
$ ls -la /var/www/git-vue/
合計 12
drwxrwxr-x 3 www-data www-data 4096 9月 21 23:40 .
drwxr-xr-x 17 www-data www-data 4096 9月 21 23:40 ..
drwxr-xr-x 4 www-data www-data 4096 9月 21 23:40 .output
- .outputが正しくコピーされている
後課題
artifacts
でキャッシュを渡せるようになりましたが、artifacts
は最新以外は破棄される設定になっていたり、cache
より少し使い勝手が悪いので、
開発時にエラーが出ないような設定を模索する必要があるので、その辺りの運用も答えが出たら追記したいと思います。
Discussion