GitLab CIのTips的なものを記載していきます。
環境(stg / prd)毎に異なるレジストリにpushする
実際の運用では、stagingとproductionのDockerイメージを、異なるレジストリで管理することもあると思います。そのようなケースではEnvironment scopeを使うと良いと思います。
まず、以下のイメージのように同名のカスタム変数を異なるEnvironment scope(stg / prd)で登録します。
その上で、.gitlab-ci.ymlを以下のようにします。
- 元々のbuildの内容は
.build
としてテンプレート化する -
build_stg
とbuild_prd
を新たに作って.build
をextendする -
タグ名
$CI_COMMIT_TAG
のパターンマッチで、x.y.z
の形式なら環境名をprd
とし、それ以外なら環境名をstg
とする(それにより読み込まれるカスタム変数が切り替わる)stages: - build_stage .build: stage: build_stage image: name: gcr.io/kaniko-project/executor:debug # 省略(上の実例と全く同じ) build_stg: extends: .build environment: name: stg except: variables: - $CI_COMMIT_TAG =~ /^([\d]+\.){2,3}[\d]+$/ build_prd: extends: .build environment: name: prd only: variables: - $CI_COMMIT_TAG =~ /^([\d]+\.){2,3}[\d]+$/
これで、タグ名によってpush先のレジストリを変更することができました。
初めてのパイプラインが登録されない
こちらのissueにあるように、masterブランチ(デフォルトブランチ)に.gitlab-ci.ymlが存在しない場合、たとえ別ブランチに.gitlab-ci.ymlが存在しても、GitLab CIが有効にならないようです。
自分の場合は、masterブランチに存在しない状況で、topicブランチを切って.gitlab-ci.ymlを作成したため、まさにこの問題に当たってしまいました。
結局、masterブランチに.gitlab-ci.ymlを配置してあげるとうまくパイプラインが登録されるようになりました。
GitLab CIでGCR上のDockerイメージをpullして使う
以下の様な感じで、GCR上のDockerイメージを利用してGitLab CIの処理を行う方法です。
test:
stage: test
image:
name: asia.gcr.io/myproject/myimage:1.2.3
script:
- poetry run python -m unittest
何も設定なしに実行すると以下の様なエラーが発生します。
ERROR: Preparation failed: Error response from daemon: unauthorized: You don’t have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication (executor_docker.go:192:0s)
GCRはプライベートリポジトリなので docker pullする際に、認証を行ってあげる必要があります。設定方法はこちらのドキュメントに書いてあります。
方法はいくつかあるようです。
- 案1)
DOCKER_AUTH_CONFIG
変数にクレデンシャル情報を設定する- UIからカスタム変数として登録する【採用】
- ○ 開発担当者が好きに設定できる
- ○ クレデンシャル情報もcommit対象にならない
- .gitlab-ci.ymlでvariableとして登録する【不採用】
- ○ 開発担当者が好きに設定できる
- × クレデンシャル情報がcommit対象になる
- config.tomlに記載する【不採用】
- × インフラ担当者(GitLabが動いているサーバに入って設定できる人)しか設定できない
- × runnerに対してクレデンシャル設定が固定になってしまう(プロジェクトによって使い分けたりできない)
- UIからカスタム変数として登録する【採用】
- 案2) config.jsonにcredential helperやcredential storeの情報を記載する【不採用】
- × インフラ担当者(GitLabが動いているサーバに入って設定できる人)しか設定できない
- × サーバに対してクレデンシャル設定が固定になってしまう
- × shared runnerだと使えない
- × Credentials Store and Credential Helpers require binaries to be added to the GitLab Runner’s $PATH
結局、UIからカスタム変数としてDOCKER_AUTH_CONFIG
を設定する方法を採用しました。
GitLab管理画面の対象プロジェクトで Settings > CI/CD > Variables > Add variable で、DOCKER_AUTH_CONFIG
という名前のカスタム変数を登録します。値は以下の形式になります。
{
"auths": {
"asia.gcr.io": {
"auth": "Base64の文字列"
}
}
}
このBase64の文字列ですが、以下の形式の文字列をBase64に変換する必要があります。
$ echo -n "username:password" | base64
bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ= # サンプルです
GCRの場合は、usernameが_json_key
固定で、passwordがjsonキーファイルの中身のJSONそのものになります(この情報がなかなか分からず探すのに時間がかかったw)。実際には以下の様なコマンドを実行してあげて出てきた文字列を、DOCKER_AUTH_CONFIG
のauthのところに貼り付けてあげればOKです。
$ echo -n "_json_key:$(cat ./key.json)" | base64
ZW5fdXJpIda90jmad@spkfvfadm,dGgyLmdvb2dsZWFwaXMuYerqwrw29tL3Rva2VuIiwKICAiYXV0aF9wcm92aWRlcl94NTA5X2Nadsabag:sdpakmfpadsmfajfe8bfnpuqwehfjhsdnv7qewjkbvdsag1MDkvc2NyYXBlciU0MHByZC1hc3RhbXVzZS1hc3RhbXVzZS5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIKfQ== # サンプルです
これで設定は完了で、ジョブを実行すればちゃんとGCRからdocker pullできると思います。
ちなみにうまくいくと、以下の様なログが出力され、$DOCKER_AUTH_CONFIGを使って認証が行われていることを確認できます。
Running with gitlab-runner 12.2.0 (88hrewe6q)
on my-runner 9jqf932qe
Using Docker executor with image asia.gcr.io/myproject/myimage:1.2.3 ...
03:06
Authenticating with credentials from $DOCKER_AUTH_CONFIG
Pulling docker image asia.gcr.io/myproject/myimage:1.2.3 ...
Using docker image sha256:sa9nfbpiahfp98qwendpjoahv09ufheqwofndnoafnsfa for asia.gcr.io/myproject/myimage:1.2.3