GitLabのCode Quality を専用Runnerで動かして高速化する

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

GitLab の Code Qualityはソースコードの品質管理のために有効なので社内でも利用しています。
しかし、そのCode Qualityの実行はDocker-in-Dockerで動いてるのでDockerイメージのキャッシュが効かず起動が遅いという問題がありました。

以前、以下の記事でDockerイメージの展開のスピードをアップすることにより爆速化するという記事を書きました(爆速化は言い過ぎでタイトルがツリだったことは反省しています)

禁断手法を使って社内のGitLab Runnerを爆速化した話(DinDの場合) - Qiita
https://qiita.com/ynott/items/ac39dfe9aa60f88382aa

GitLab社でもCodeQualityの起動の遅さについては検討がされていて、解消されると思っていたのですが、どうもCodeQualityの機能側でなんとかする事は技術的な制約により諦めてしまったようです。

Technical Investigation: Code Quality template without DinD (#267930) · イシュー · GitLab.org / GitLab · GitLab
https://gitlab.com/gitlab-org/gitlab/-/issues/267930


その代わりにCode Qualityの専用Runnerを動かすことにより、起動スピードを改善したということでしたので試してみました。

# 1. Code Quality 専用 RunnerをRegisterする

通常のRunnerと違うところは、Runnerのregisterの指定方法が違うだけです。
Runnerのタグ名は、`cq-sans-dind`にしていますが、任意に付けられます。

`<project_token>`は、ご利用のGitLabサーバーのTokenに変更してください。

私は、tag無しのジョブをこの専用Runnerで動かしたくなかったので、
`--run-untagged="false"`を追加しています。
また、ジョブで生成されたものが大きい事もあるので、
`--output-limit 1048576`を追加しています。

```bash
$ gitlab-runner register --executor "docker" \
  --docker-image="docker:stable" \
  --url "https://gitlab.example.co.jp/" \
  --description "cq-sans-dind" \
  --tag-list "cq-sans-dind" \
  --locked="false" \
  --access-level="not_protected" \
  --docker-volumes "/cache"\
  --docker-volumes "/builds:/builds"\
  --docker-volumes "/var/run/docker.sock:/var/run/docker.sock" \
  --registration-token="<project_token>" \
  --non-interactive \
  --docker-volumes "/certs/client" \
  --output-limit 1048576 \
  --run-untagged="false"
```

上記のRegisterで以下のようなconfig.tomlが設定されます(該当部分のみ抽出)

```toml:config.toml
[[runners]]
  name = "cq-sans-dind"
  output_limit = 1048576
  url = "https://gitlab.example.co.jp/"
  token = "xxxxxxxxxxxxxxxxxxxxx"
  executor = "docker"
  builds_dir = "/tmp/builds"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock", "/certs/client", "/tmp/builds:/tmp/builds"]
    shm_size = 0
```

参考：Code Quality | GitLab
https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html#set-up-a-private-runner-for-code-quality-without-docker-in-docker

# 2. .gitlab-ci.yamlを以下のように変更する

特定のRunnerでCodeQualityを実行して欲しいので、以下の用にtagsを追加します。

```yaml:.gitlab-ci.yml
include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  services:            # Shut off Docker-in-Docker
  tags:
    - cq-sans-dind
  rules:
    - if: '$CODE_QUALITY_DISABLED'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run code quality job in merge request pipelines
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'      # Run code quality job in pipelines on the master branch (but not in other branch pipelines)
    - if: '$CI_COMMIT_TAG'                               # Run code quality job in pipelines for tags
```

# 3. どうなったか、結果

実行時間は以下のようになりました。
上3つが専用Runnerで実施した時間になります。1分程度でジョブが終了しているのが分かると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/0792d035-352c-b68c-1012-77a0bc47e35b.png)

# 4. まとめ

専用Runnerを作る必要はありますが、その効果は大きかったです。