大規模エンタープライズ向けの GitLab 設計方法
何千人もの開発者を対象に GitLab を設計すると、デプロイ方式や runner 戦略、パイプライン性能がそのままアーキテクチャ上の問題になる。可用性、災害復旧、容量計画、成長のしきい値までチェックリスト化する。
日本語
コピー

エンタープライズ規模では、ごく小さなアーキテクチャ上の選択であっても、想定をはるかに超える影響を及ぼすことがある。数チームだけを対象としたデプロイ構成も、何千人もの開発者、リポジトリ、パイプラインを支えるとなればボトルネックになり得る。だからこそ、デプロイ前に下す一つひとつの判断が極めて重要になる。たとえば:
- デプロイ方式は、チームがどの部分を自ら運用するかを決める
- runner 戦略は、CI/CD ワークロードをどう実行し、どう分離を保つか、そしてプラットフォームチームがどれだけ運用負担を負うかを決める
- 可用性目標は、冗長化と復旧の方式を決める
- ワークロードは、プラットフォームに必要な容量を決める
これらの要素が合わさって、プラットフォームが拡張時に余裕をもって対応できるか、それとも新たな運用上の制約を生み出すかが決まる。本ガイドの内容:
- 拡張の前に確定しておくべきアーキテクチャ上の判断
- runner 戦略の計画方法
- 高可用性と災害復旧の計画
- 規模拡大後にパイプライン性能がどこで破綻するか
- Kubernetes とクラウドネイティブなデプロイの注意点
- プラットフォームチーム向けのアーキテクチャ検証チェックリスト
拡張の前に確定しておくべきアーキテクチャ上の判断
GitLab のデプロイ方式は、プラットフォームのどの部分についてチームが容量を見積もり、セキュリティ強化を行い、監視し、アップグレードし、復旧させるかを決める。エンタープライズ向けのデプロイには三つの主要な選択肢がある。GitLab.com: GitLab のマルチテナント型 Software as a Service(SaaS)製品。アプリケーションと基盤インフラは GitLab が運用し、あなたの組織は自組織の GitLab 設定、連携、および自前で管理する runner を担当する。GitLab Dedicated: Amazon Web Services(AWS)上でホストされる、フルマネージドのシングルテナント型 SaaS 製品。更新、高可用性、災害復旧を含む基盤インフラは GitLab が運用し、あなたの組織はアプリケーション層の制御を通じてユーザーとデータアクセスを管理する。GitLab Self-Managed: あなたの組織が GitLab インスタンスを自らインストールし、管理し、保守する。インフラはあなたが管理し、環境の運用、拡張、セキュリティ強化、復旧もあなたの責任となる。どの方式を選ぶかは、組織がどれだけの制御を必要とし、どれだけのインフラ責任を負えるかによって決まる。たとえば、次のような場合に応じて選ぶとよい:
- GitLab.com:マルチテナント型 SaaS で要件を満たせており、インフラ運用の作業をできるだけ減らしたい場合
- GitLab Dedicated:シングルテナントの分離が必要、あるいはネットワークやデータレジデンシーなどについて制御権を持ちたい一方で、GitLab インフラ自体は運用したくない場合
- GitLab Self-Managed:要件上、基盤インフラを直接制御する必要があり、チームにそのプラットフォームを運用する力がある場合
決定を下す前に、ある選択肢が実行可能かどうかを左右し得る要件を先に書き出しておく。特に注目すべきは、データレジデンシー、ネットワーク分離、復旧目標、インフラの制御権だ。そのうえで、各方式がチームに残す実際の運用作業を洗い出す。アップグレード、監視、容量計画、バックアップ、インシデント対応が含まれる。ここまで終えれば、核心となるトレードオフが明確になる。あなたの組織がどれだけのインフラ責任を負う必要があり、現実的にどれだけ負えるのか、ということだ。この運用上の境界を引いたら、次は CI/CD 負荷を実行する計算層の計画に移る。
runner 戦略の計画方法
GitLab Runner は CI/CD ジョブを実行し、GitLab アプリケーションはその背後のパイプラインを調整する。エンタープライズ規模ではこの分離が重要になる。アプリケーションの容量と runner の容量は、それぞれ異なる種類の需要に対応するからだ。アプリケーションは Git、Web、API、自動化のトラフィックを処理し、runner クラスタは CI/CD 作業の量と同時実行数を受け持つ。したがって、runner クラスタの規模はワークロードそのものに基づいて決めるべきであり、開発者の数から割り出すものではない。まず次の情報を記録する:
- ジョブ数と実行時間
- ピーク時の同時実行数
- OS と計算リソースの要件
- ネットワーク経路と専用ハードウェア
- 特権を必要とするジョブ、機密データを扱うジョブ
- リリースウィンドウや定時スキャンなどのピーク時間帯
これらのデータをもとに、設定したキュー待ち時間の目標を達成するには、何個のジョブを同時に実行する必要があるかを見積もる。ワークロードのデータはチームの規模よりも重要だ。開発者の数が同じ2つの組織でも、パイプラインの頻度、自動化の度合い、ジョブの要件が異なれば、必要な CI/CD はまったく別物になる。
適切な Runner スコープを選ぶ
Runner スコープは、各リソースプールをチームがどこまで使えるかを決める。インスタンス Runner は GitLab インスタンス全体のプロジェクトで使えるが、グループ Runner は指定したグループ内のプロジェクトとサブグループしかアクセスできない。プロジェクト Runner はスコープが最も狭く、専用の認証情報、特殊なインフラ、より強固な分離を必要とするワークロードに向く。確保した容量が少数のワークロード専用になるため、ジョブ量が不安定だとプロジェクト Runner は遊休しやすい。判断する際は利用率も考慮に入れる。ワークロードの信頼性と計算能力の要件を満たす範囲で、できるだけ広いスコープを選ぶ。プールが広いほど利用率は上がるのが一般的で、機密性の高いデプロイや特殊なワークロードには専用インフラが妥当なこともある。
オートスケーリングを見越して計画する
オートスケーリングを使えば Runner の容量は需要に応じて増減できるが、そのインフラの運用にもプラットフォームエンジニアリングの時間がかかる。Runner クラスタを自前で管理するなら、新しいリソースがいつ利用可能になるかを考える必要がある。インスタンスの起動、クラウドのクォータ、イメージのダウンロード、キャッシュの可用性は、いずれもピーク時のキュー待ち時間に影響する。追加の計算資源が立ち上がるまでの間、短期的な需要を吸収できるだけの余裕を確保しておく。この運用を GitLab に任せることもできる。GitLab ホスト型 Runnerは GitLab.com と GitLab Dedicated で利用でき、Runner 基盤とオートスケーリングは GitLab が管理する。Runner マシンのプロビジョニング、パッチ適用、スケーリングにかかる時間を減らしたいチームにとって、Runner の戦略はインフラ管理の判断から、容量とワークロードの配置の判断へと比重が移る。
Executor をワークロードに合わせる
どの Executor を選ぶかで、CI/CD ジョブがどこで動き、チームがどのインフラを運用するかが決まる。クラウドネイティブな環境なら、Kubernetes executorは既存の Kubernetes クラスタを使う。パブリッククラウドの仮想マシン上でオートスケーリングするワークロードには、GitLab が Docker Autoscaler と Instance executor を用意している。どちらが適するかは、ジョブが必要とする環境と、チームが管理できるインフラ次第だ。Kubernetes executor では CI/CD ジョブがそれぞれ自分の Pod で動くので、クラスタの挙動が Runner の性能の一部になる。スケジューリングの遅延、リソースの requests と limits、ノードの容量、オートスケーリングは、ジョブの開始と完了の速さに影響する。こうした制約を容量計画に織り込んでおけば、CI/CD の需要が伸びても Executor がボトルネックにならずに済む。
高可用性と災害復旧の計画
可用性の計画は、停止とデータ損失がビジネスに与える影響から考える。明確にすべきは次の3つだ。
- サービスレベル目標(SLO):平常時にプラットフォームが維持すべきサービス水準
- 目標復旧時間(RTO):サービス停止後、どれだけの時間で復旧しなければならないか
- 目標復旧時点(RPO):組織が許容できるデータ損失の量
これらの目標が、アーキテクチャに必要な冗長性と復旧能力を決める。そのうちどこまでをプラットフォームチームが担うかは、デプロイ形態によって変わる。GitLab Self-Managed を使うなら、こうしたアーキテクチャの判断は自チームの責任だ。本番で使える出発点として GitLab リファレンスアーキテクチャを利用し、自組織の可用性と復旧の要件に合わせてトポロジーを調整する。GitLab Dedicated では、基盤となる災害復旧インフラとフェイルオーバーの手順を GitLab が管理する。顧客は地理ベースの災害復旧用にセカンダリ AWS リージョンを選べる。プライマリとセカンダリ間のレプリケーションは GitLab が維持し、必要になればフェイルオーバーを実行する。Self-Managed の場合、復旧の設計では高可用性、災害復旧、バックアップを、互いに補完し合う3つの別の層として扱う。
- 高可用性は、プライマリ環境でのコンポーネント障害の影響範囲を限定する。
- 災害復旧は、サイトやリージョン全体が失われた後にサービスを復旧させる。
- バックアップは、破損や削除、そしてレプリケーションがセカンダリサイトまで運んでしまうその他の障害に備える。
さらに Self-Managed では、復旧目標をアーキテクチャの要件に落とし込む。どこに冗長性が必要か、データをどう複製するか、バックアップで重要なデータをどう守るかを決める。復旧計画には認証やネットワークなど依存するサービスも含める。GitLab Geo はアクティブ-パッシブ方式の災害復旧アーキテクチャを提供し、セカンダリサイトがプライマリから同期する。Self-Managed 環境ではフェイルオーバーは顧客が運用する手順なので、本番に近い条件で手順を訓練し、結果を RTO と RPO で測る。失敗した依存関係や、復旧を遅らせかねない手作業を記録し、それを設計の改善につなげる。
規模を拡大したとき、パイプライン性能はどこで崩れるか
GitLab の利用が広がるほど、性能計画の重心は「想定需要から容量を見積もる」ことから「実負荷の下でプラットフォームがどう振る舞うかを確かめる」ことへ移る。最初の一歩は、時間がどこで消えているかを見つけることだ。GitLab はキュー待ち時間と実行時間を分けて記録するので、調査の取っ掛かりになる。ジョブのキュー待ち時間は実行が始まるまでどれだけ待ったかを示し、ジョブ時間は実際の実行時間を記録する。パイプライン時間はキュー待ちを含まず、パイプラインの実行にかかった時間を測る。これらの指標が指し示すボトルネックはそれぞれ違う。キュー待ち時間が長ければ Runner の容量が足りない可能性がある。実行時間が長ければ、原因はパイプラインの設計、テストスイート、依存関係のダウンロード、リポジトリの転送にあるかもしれない。
性能ベースラインの確立
通常負荷とピーク負荷の両方で代表的なプロジェクトをテストし、どこから性能が劣化し始めるかを見極める。リリースウィンドウ、定期的なセキュリティスキャン、コミットが集中する時期などもテストに含め、ボトルネックを露呈するシグナルを追跡する:
- キュー待ち時間
- ジョブ時間とパイプライン時間
- runner の稼働率
- リトライと失敗
- キャッシュヒットの状況
- アーティファクトの転送時間
- インフラの飽和度
結果は runner プールとワークロード種別ごとに分けて見る。全社平均のままでは、特定のチームやワークロードにしか影響しないボトルネックが覆い隠される。これを踏まえてしきい値を設定し、runner をいつ増やすか、パイプラインをいつ最適化するか、GitLab 本体をいつ水平スケールするかの判断に使う。
大規模リポジトリと monorepo は別途テストする
大規模リポジトリと monorepoは、GitLab と runner インフラに異なる要求を突きつける。頻繁な clone と fetch は CPU、メモリ、ディスク、ネットワークの消費を押し上げ、複数のパイプラインが同じリポジトリに同時アクセスする場合はなおさらだ。影響を見積もるときにリポジトリのサイズだけを見てはいけない。clone の頻度、並行する CI/CD 活動、ブランチのパターン、ジョブごとに転送されるデータ量も、プラットフォームの負荷に影響する。
まずワークロードを最適化し、それからスケールする
パイプラインの設計を最適化するだけでも、プラットフォームにかかる圧力を減らせる。互いに独立した job を並列実行し、不要な pipeline を削除し、頻繁にダウンロードする依存関係をキャッシュし、アーティファクトの保持期間を制限する。monorepo では、関連するパスが変更されたときだけ job を起動し、job ごとに転送するリポジトリデータを減らす。運用開始後も測定を続ける。利用状況は絶えず変化するからだ。Self-Managed 環境では、実際のリソース利用状況とワークロードパターンこそが、アーキテクチャをいつ拡張すべきかを判断する最も明確なシグナルになる。
Kubernetes とクラウドネイティブデプロイの考慮事項
GitLab のアーキテクチャにおいて、Kubernetes は二つの異なる役割を担いうる。Kubernetes executor は既存クラスタ内で CI/CD job を pod として実行でき、GitLab Self-Managed は Kubernetes 上でクラウドネイティブアーキテクチャとして動作できる。この二つの選択はプラットフォームの別々の部分に影響するため、分けて評価すべきだ。Kubernetes で runner を動かすと変わるのは CI/CD 計算資源の供給とスケール方法であり、GitLab を Kubernetes 上で動かすと変わるのは、チームがアプリケーションとその周辺インフラを運用する方法である。
Kubernetes runner はクラスタの一部として計画する
Kubernetes executor を使う場合、runner manager は Kubernetes API を呼び出し、CI/CD job ごとに pod を作成する。つまりクラスタ自体が runner アーキテクチャの一部になる。これらの job が依存する Kubernetes リソースとガバナンス、すなわち namespace、service account、リソースの requests と limits、ワークロード分離を計画に入れる。機密性の高い操作を伴うデプロイ job では、信頼度の低いビルドワークロードとの間により強固な分離が必要になることもある。容量と設定も同様に重要だ。クラスタのオートスケールが、キュー待ち時間の目標を満たすのに十分な速さでノードを追加できるかテストする。クラスタが最終的に十分な計算資源を供給できたとしても、ノードの供給が遅すぎれば、需要のピーク時に job は待ち行列に並んだままになる。
Kubernetes 上の GitLab に適したアーキテクチャを選ぶ
GitLab 自体を Kubernetes 上で動かす場合は、より上位のアーキテクチャ判断が必要になる。新規の Self-Managed デプロイでは、GitLab は Cloud Native リファレンスアーキテクチャの使用を推奨している。このモードでは GitLab の各コンポーネントが Kubernetes 上で動作し、PostgreSQL、Redis、オブジェクトストレージは外部に残る。特定のコンポーネントを Kubernetes の外に置かざるを得ない場合、Cloud Native Hybrid は依然として選択肢になる。たとえば、リポジトリ単位の高可用性を実現するために Gitaly Cluster が必要なチームは、ハイブリッドアーキテクチャか VM ベースのリファレンスアーキテクチャを検討すべきだ。標準の Cloud Native アーキテクチャでは Gitaly が非クラスタ構成で動作するためである。どのモードを選んでも、Kubernetes を GitLab プラットフォーム全体の運用計画に組み込む。チームにはクラスタと外部サービスを対象とした可観測性が必要であり、GitLab とそのインフラ依存を考慮したアップグレード手順も必要になる。容量テストとリカバリテストは、クラスタを本番環境の一部としてカバーすべきだ。GitLab クラウドネイティブの概要に、このデプロイモードの詳細な説明がある。Kubernetes の運用モデルがインフラ要件に合致し、チームにそれを確実に運用する力がある場合に選ぶとよい。
プラットフォームチームのアーキテクチャ検証チェックリスト
本番稼働の前に、このチェックリストでデプロイ、スペック、Runner、リカバリ、性能に関する主要なアーキテクチャ判断を一つずつ検証する。各項目について、その判断を裏付ける証拠を残すか、不足を埋める責任者を指名する。
| 検証内容 | 証拠または責任者 |
|---|---|
| デプロイモード | |
| 選択したデプロイモードがデータレジデンシー、分離、ネットワーク、カスタマイズの要件を満たしている。 | |
| GitLab、プラットフォームチーム、インフラプロバイダーの間の責任分担が明確である。 | |
| アップグレード、メンテナンス、サポート、容量管理に明確な責任者と文書化されたプロセスがある。 | |
| アプリケーションスペック | |
| 想定 RPS が Self-Managed デプロイのベースラインアーキテクチャ規模を決定している。 | |
| スペックの算出が API、Web、Git トラフィックの構成を反映している。 | |
| 大規模 monorepo や高負荷な自動化など、非典型的なワークロードを設計が考慮している。 | |
| Runner 戦略 | |
| Runner のスペックがジョブ量、所要時間、ピーク同時実行数、計算資源要件を反映している。 | |
| Runner のスコープが信頼境界、特権アクセス、ワークロード分離の要件と一致している。 | |
| オートスケールの上限、クラウドクォータ、起動時間、準備済み容量がピーク負荷でテストされている。 | |
| キュー待ち時間とパイプライン時間の目標がそれぞれ定義され、個別に監視されている。 | |
| Runner manager のアーキテクチャが重要なワークロードの単一障害点を避けている。 | |
| 可用性とリカバリ | |
| SLO、RTO、RPO の目標がビジネスオーナーとテクニカルオーナーの承認を得ている。 | |
| 冗長化、バックアップ、レプリケーション、フェイルオーバーの手順が必要な障害シナリオをカバーしている。 | |
| リカバリテストがアイデンティティ、DNS、シークレット、ネットワーク、外部連携を網羅している。 | |
| 直近のリカバリ演習が目標を達成したか、改善作業が計画されている。 | |
| 性能と成長 | |
| 代表的なプロジェクト、monorepo、セキュリティジョブ、リリースワークロードが想定ピーク負荷でテストされている。 | |
| ダッシュボードがキュー待ち時間、ジョブとパイプラインの時間、エラー、インフラ飽和度、Runner 稼働率を追跡している。 | |
| スケールのしきい値が、いつ拡張し、いつワークロードを最適化するかを明確にしている。 | |
| 利用パターンと組織の要求の変化に対応するため、アーキテクチャの定期的なレビュー体制がある。 |
企業規模は、初期のアーキテクチャ上のあらゆる判断に圧力をかける。最も堅牢な GitLab 環境は、組織が実際にどう動いているかを反映し、要件の変化に十分な余地を残している。導入が広がるにつれて、その前提も変わっていく。継続的に計測し、要件が変わったらアーキテクチャを見直し、次の判断は証拠に基づいて下す。この規律が、GitLab を「より多くのユーザーを支えるだけのプラットフォーム」から「組織の歩みについていけるプラットフォーム」へと変える。