GitLab CI/CDのコストを極限まで削り、開発速度を最大化する「Runner階層戦略」の極意
GitLabを使いこなすテックリードなら、一度は直面するはずだ。「なぜCI/CDの月額請求額が、クラウドのインフラ費用を超えているのか?」と。
共有のInstance Runnersに甘え、すべてのプロジェクトを同じ巨大なマシンで処理させているなら、それは「コストの垂れ流し」だ。今日は、私が大規模開発チームで実践している、GitLab Runnerの階層構造をハックしてコストを最適化し、ビルド時間を劇的に短縮する「戦術」を伝授する。
—
1. なぜ「Instance Runner」だけでは地獄を見るのか
GitLabのRunner階層(Instance > Group > Project)を理解せず、デフォルト設定のまま運用するのは、全社員に経費制限なしの法人カードを渡しているようなものだ。
- Instance Runners: 全プロジェクト共有。特定の重量級ビルドにリソースを食い尽くされ、他の小規模なテストが待機列で死ぬ。
- Group Runners: 特定のプロダクト群に最適化可能。ここがコスト削減の主戦場だ。
- Project Runners: 個別最適化の極みだが、管理コストが高い。
鉄則: 「重いビルド」と「軽いテスト」を物理的に分離せよ。これだけで、AWS/GCPのスポットインスタンス料金を30〜40%は削れる。
—
2. オートスケーリングの魔法:コスト削減の具体的構成
クラウド(AWS/GCP)上でRunnerを動かす際、最もやってはいけないのが「常時起動」だ。Kubernetes Executorを使い、スポットインスタンスのみを使用するRunnerを構築するのが正解だ。
推奨の `config.toml` 設定(抜粋)
[[runners]]
name = “spot-runner-k8s”
executor = “kubernetes”
[runners.kubernetes]
image = “alpine:latest”
# 重要: スポットインスタンスを強制的に使うためのノードセレクタ
node_selector = { “cloud.google.com/gke-spot” = “true” }
# 待機時間を極限まで減らす(アイドル時間を短く)
poll_timeout = 60
[runners.kubernetes.node_tolerations]
“cloud.google.com/gke-spot” = “NoSchedule”
[runners.cache]
# S3/GCSバケットを共有し、ビルド時間を短縮
Type = “s3”
Shared = true
—
3. 「タグ戦略」によるジョブの適切なルーティング
全てのジョブを同一のRunnerで処理させるな。タグを使って、ジョブの「重さ」に応じて適切なマシンへ投げろ。
- `fast-check`: 小さなインスタンス(共有サーバー)へ。並列実行数を増やして回転率を上げる。
- `heavy-build`: メモリを食うビルド。スポットインスタンスの高スペック機へ。
.gitlab-ci.yml のベストプラクティス
.job_template:
tags:
- k8s-runner # 共通タグ
retry: 2 # ネットワークエラー対策
test:job:
extends: .job_template
tags:
- fast-check # 軽量Runnerへルーティング
script:
- npm test
build:image:
extends: .job_template
tags:
- heavy-build # スポットインスタンスの高メモリ機へ
script:
- docker build …
—
4. チームの生産性を底上げする「神テクニック」
隠れたキーボードショートカット
- `g` + `i`: Issuesへ即移動。
- `g` + `m`: Merge Requestsへ即移動。
- CI実行画面で `s`: パイプラインを即座に再試行。これを知っているだけでブラウザのクリック数が半分になる。
絶対に入れるべき「GitLab Workflow」プラグイン(VS Code)
ブラウザとエディタを行き来するのは時間の無駄だ。VS Codeの「GitLab Workflow」拡張機能を使えば、エディタ内でパイプラインの状態を確認し、Failedしたジョブのログを直接確認できる。
設定の共有化ルール:`include` の活用
個々のプロジェクトに `.gitlab-ci.yml` をコピペさせるな。`include` キーワードを使って、全プロジェクト共通のジョブ定義を一つのレポジトリに集約せよ。
プロジェクト側の設定はこれだけで完結させる
include:
- project: ‘devops/ci-templates’
file: ‘/templates/node-app.yml’
—
5. テックリードからの最終提言
コスト管理の本質は「節約」ではなく「無駄な待機時間の排除」にある。
1. キャッシュ戦略: `cache:key` に `CI_COMMIT_REF_SLUG` を使うな。`files` を使ってロックインを防ぎ、S3/GCSへのアップロード/ダウンロード時間を最適化せよ。
2. アーティファクトの保存期間: デフォルトの期限は長すぎる。`expire_in: 1 week` など、プロジェクトの特性に合わせて厳格に管理しろ。
3. Runnerの健全性監視: Prometheusメトリクスを有効にし、Grafanaで「Runnerの待機ジョブ数」と「クラウドコスト」を重ねて可視化しろ。
これらをやり遂げたとき、あなたのチームのCI/CDは単なる自動化ツールから、「開発のボトルネックを完全に解消するエンジン」へと進化する。
さあ、今すぐ設定ファイルを開き、タグを打ち込み、インフラの無駄を削ぎ落としてくれ。それがプロの仕事だ。