Dedicated から Cells へ: 技術的分析
はじめに
このドキュメントは、既存の GitLab Dedicated アーキテクチャが大量の GitLab Cell インスタンスのデプロイと運用の基盤として使用できる方法を説明するハイレベルな概要を意図しています。
さらに、Dedicated アーキテクチャにおける特定の決定、それらが GitLab Dedicated と GitLab Cells の両方にとってなぜ有益であるか、そして GitLab.com の IaC や GET などの他のアプローチとどのように異なるかを説明します。
読者への注意: これは GitLab.com のアプローチや GET の批評ではないことを念頭に置いてください。 これは Dedicated がこれらの他のアプローチとどのように、そしてなぜ異なるかの説明であり、異なる要件がどのように異なる設計の選択をもたらしたかについての洞察を提供します。
GitLab Dedicated は環境自動化テクノロジーである
このドキュメントのコンテキストでは、GitLab Dedicated は主として、多数のほぼ均質な GitLab アプリケーション環境の設定、デプロイ、アップグレード、監視、および保守を自動化するテクノロジーと考えることができます。
Dedicated は GitLab.com とどのように異なるか?
GitLab.com は最大の単一 GitLab デプロイであり、おそらく最も複雑です。GitLab.com は、VM 設定用の Chef Cookbooks のための chef-repo、Terraform 設定のための config-mgmt、および Helm、Kubernetes マニフェスト、Tanka を含む Kubernetes 設定のための k8s-workloads グループを含む複数のプロジェクトにわたってプロビジョニングおよび設定されています。
異種環境と均質環境
均質な GitLab 環境と異種な GitLab 環境の区別について説明します。
GitLab.com: 多数の異種環境
現在、config-mgmt プロジェクトには 64 の環境が管理されています。chef-repo には 22 の Chef 環境と 569 のロール(一部のロールは未使用の可能性があります)があります。GitLab.com の Helm チャートは同じ Helm テンプレートを使用して均質です。Terraform と Chef の場合、多くのサブモジュールを共有し、一貫性を確保するための努力がなされていますが、これらの環境はそれぞれユニークです。しかし、各環境は他のものと異なる場合があります。均一性を確保する方法はなく、時間の経過とともにこれらの環境はさまざまな理由で均一性から逸脱しています。

似ているが異なる: GitLab.com の config-mgmt プロジェクトの環境
GitLab.com はもともと少数の環境(本番とステージング)のために構築されたため、多数の均質な環境にスケールアップするように設計されていませんでした。
これを考える別の方法として、GitLab.com の Staging と Production の Terraform 環境である gstg と grpd は、互いのレプリカではなく、または同じ設定を異なる入力値で使用しているわけではありません(例えば Staging を Production のより小さい/安価なコピーにするためなど)。これらは、互いに並行して構築された 2 つの独自の環境です。

同じようで、違う: Staging と Production の GKE ゾーン設定。似ているが同じではない。
GitLab.com はさまざまな理由でこの方向に進化し、そのアプローチは最大限の柔軟性を可能にします。しかし、新しい環境の作成にはオペレーターの数週間または数ヶ月の時間がかかります。Dedicated は新しい環境の作成にオペレーターの数分と実際の時間の数時間を必要とします。 さらに、運用および Day 2 の観点から、これらの環境の異種な性質により、多数の環境にわたるバッチ操作の適用が困難になり、手動プロセスが生じます。
GitLab.com 環境の非均質な性質は、変更を調整する必要がある複数のプロジェクトによってさらに複雑になりますが、これについては後で詳しく説明します。
Dedicated: 均質で繰り返し可能な機能的環境
Dedicated は、すべての環境に対して単一の IaC 設定(Terraform、Ansible、Kubernetes マニフェストなど)を使用することで環境間の均質性を強制します。環境間に存在できる唯一の違いは、環境への入力変数によって制御されます。 これらの入力変数をテナントモデルと呼びます。すべての環境が同じ IaC を使用するため、テナントモデルでこれらの違いを表現せずに、クラウドリソース、Ansible 設定、Terraform モジュールなどを追加または削除することは不可能です。
均質な環境を持つことでより高い一貫性が提供されます。これは、多数の環境を一括で移行する必要がある場合に特に重要で、設定の組み合わせの可能性がはるかに少なくなり、変更の自動化が可能になります。
IaC 設定ツール
GitLab.com: 多数の異なる設定管理ツール
GitLab.com の場合、環境の変更はさまざまな異なるプロジェクトにわたって調整・適用される必要があります。通常、変更が正しい順序とシーケンスで行われるように手動調整が必要です。例えば、Terraform の変更を適用した後に chef-repo の変更が必要な場合があります。これらの変更の手動調整に差異が生じると、予期しない結果につながり、最終的にはより遅い配信、障害、さらにはデータ損失につながる可能性があります。

GitLab.com: 多数の異なる設定管理ツール
Dedicated: すべての環境変更のための単一エントリーポイント
Dedicated は、テナントまたは Cell 環境へのすべてのアトミックな変更をカプセル化する単一プロジェクト Instrumentor を提供することでこのモデルを簡素化しようとしています。複数のプロジェクトにわたる変更の調整の問題は、すべての変更を単一プロジェクトに統合することで解決されます。

Dedicated: すべての環境変更のための単一エントリーポイント
Dedicated: アトミックプロビジョニングプロセスが決定性、テスト可能性、再現性を向上させる
異なる設定プロジェクトにわたる環境の組み合わせへのロールアウトの調整から解放された Dedicated は、はるかに決定論的な方法で環境を理解できます。これにより、テスト可能性、再現性が大幅に向上し、多数の環境を実行する場合、最終的にはより良い可用性とレジリエンスにつながります。
GitLab.com の複雑なデータベース変更と Dedicated での同様の変更を比較してみます。 GitLab.com 環境に変更を加えるには:
- Staging の Terraform モジュール変更を行う
- Staging の chef-repo 変更を行う
- Staging の Terraform モジュール変更をマージして適用する
- Staging の chef-repo 変更をマージして適用する
- 変更が期待通りに動作することをテストする
- Production の類似した、しかし同一ではない Terraform モジュール変更を作成する
- Production の Terraform モジュール変更をマージして適用する
- Production の Chef-Repo 変更をマージして適用する
この例は 2 つの環境のみを説明していますが、環境が増えるほど(例: Pre-Prod)変更のロールアウトに必要な作業が増えます。 さらに、環境が同一であること、またはある環境の一部の機能がその環境での動作を変更しないことの保証もありません。環境は決定論的でなく、これにより変更ロールアウト中に追加のリスクが生じます。この追加のリスクはその後、より複雑な変更に対して CR の形式の変更管理プロセスによって管理されます。通常の手動ステップと同様に、このプロセスは設定ドリフトの可能性を減らすことを目的としていますが、ロールアウトも遅くなります。
Dedicated の場合、ワークフローは次のとおりです:
- Instrumentor で変更を行い、マージリクエストブランチのレビューアプリを使用してサンドボックス環境で変更をテストする。
- Instrumentor のメインブランチに変更を承認してマージする。
- Instrumentor は自動的に Instrumentor パッケージの新しいバージョンをリリースする。
- ステージングから始め、すべてのテナントモデルを新しいバージョンに順次更新し、すべてのテナント/Cell が最新バージョンを実行するまでフリート全体にロールアウトする。問題が検出された場合はロールアウトを停止する。
Dedicated において重要なことは、すべての変更が単一のアーティファクト - Instrumentor の単一のリリース系統にカプセル化されていることです。
まとめ
| GitLab.com | GitLab Dedicated | |
|---|---|---|
| IaC 設定 各環境は単一の設定を共有しているか、独自のユニークな TF モジュールを持っているか? | 多数 | 1 つ |
| プロビジョニング/設定リポジトリ 広範囲にわたるインフラ変更を行うために、変更を複数のプロジェクトに分散させる必要があるか? | 多数 | 1 つ |
| 設定の柔軟性 設定はどのくらい柔軟か?例えば、単一環境の差分に対して。 | 非常に高い | 限定的(テナントモデルのみ) |
| Day 2 運用の自動化 Day 2 運用が自動化される可能性。 | 時々自動化 | 自動化のみ |
Dedicated は GET とどのように異なるか?
GET は、適切に構築できる私たちのリファレンスアーキテクチャに基づいたベース本番 GitLab 環境のスケールでのデプロイと運用を可能にするツールのコレクションです。
Dedicated は内部的に GET を使用していますが、GET は主に単一の GitLab インスタンスで使用することを意図しています。
さらに、GET は汎用ユースケースに適した汎用 GitLab 環境として意図されています。重要なことに、GET は Dedicated が提供するコンプライアンス、セキュリティ、規制、および高度なネットワーキング機能の多くなど、すべての可能なユースケースを処理しない(また処理すべきでもない)。
GET は、クラウド環境内で動作する GitLab Reference Architecture に準拠したマルチホストおよび/または Kubernetes ベースの GitLab インストールを維持しようとしている顧客に正しく注力しています。この環境を数十または数百のインスタンスにスケールアップすることには注力しておらず、これをサポートするための機能を追加すると、Dedicated 以外のすべての GET ユーザーにとって採用の障壁となる多大な複雑さが加わることになります。
GitLab Dedicated のコンポーネント
このセクションでは、GitLab Dedicated のコンポーネントを説明し、これらのコンポーネントが設計に含まれた理由に注目します。

GitLab Dedicated コンポーネント
Switchboard
Switchboard は GitLab Dedicated 顧客のユーザーインターフェースであり、顧客がウェブユーザーインターフェースを通じて GitLab インスタンスをプロビジョニングおよび設定できるようにします。これは GCP アクセスのための Google Console、Elastic プロビジョニングのための Elastic Cloud などに類似しています。 Switchboard は常に GitLab Dedicated テナントオペレーター(顧客インスタンスをサポートする SRE であれ、顧客オペレーターであれ)のユーザーインターフェースとなることに注力してきました。これは GitLab Dedicated との顧客インタラクションを簡素化する製品機能です。
Switchboard の設計は Dedicated のケース、つまり顧客が Dedicated インスタンスとインタラクションできるようにすることのみに注目してきました。Cells は Switchboard が設計された時点では GitLab Dedicated のスコープ外であり、Switchboard は GitLab Dedicated 顧客のオンボーディング、インタラクション、情報収集を簡素化するためにのみ設計されています。
Cells に Switchboard を使用することは適切な選択ではありません。Cells は DevOps ワークフローと CI/CD パイプラインを使用して、Switchboard が開発される前の Dedicated の早期イテレーションが行っていたように、Amp コントロールプレーンで Instrumentor プロビジョナージョブを開始する必要があります。テナントモデルを Switchboard を使用するか別のタイプのインターフェースを使用するかに関わらず、インターフェースが同じになるような方法で構造化しておくことは、最初からの設計の選択でした。
Amp
Amp はプロビジョニングジョブが実行される実行環境です。これはプロビジョニングジョブの実行に必須ではありません。実際、Dedicated レビューアプリでは、Instrumentor は Amp を必要とせずに GitLab CI パイプライン内で直接動作し、開発者のサンドボックスアカウントで操作します。さらに、Instrumentor は環境自動化エンジニアのラップトップでローカルに実行できます。これにより、新しい機能の開発時に開発時間を大幅に短縮できます。
ただし、Amp の利点は、本番環境においてセキュアで、信頼できる、高度に制御された環境であることです。 Dedicated は認証に長期間有効なセキュリティキーを使用しないよう推奨しており、代わりに信頼関係、OIDC、IDフェデレーション、およびその他の最新の認証方法を使用しています。Amp はこれを安全に行えるコントロールプレーンを提供します。
セキュリティ上の理由から、Cells も Amp 環境でジョブをデプロイし続けることを推奨します。ただし、これらのジョブは GitLab Kubernetes Runner 経由で CI/CD パイプラインジョブから直接透過的に呼び出すことができます。セキュリティ、権限、その他のコンテキストは、より高レベルのインターフェース内ではなく Amp レベルで保証されます。
テナントモデルスキーマ
プロビジョニングプロセスへのすべての入力がテナントモデルを通じて行われるため、モデルはユーザーおよび/またはオペレーターとプロビジョナー Instrumentor 間のインターフェースとなります。
すべての入力が一貫していて定義された範囲内にあることを確保するために、テナントモデルスキーマはシステムへのすべての入力を検証します。 これにより、予期しない結果やセキュリティ侵害、データ損失につながる可能性のある予期しない入力を防ぎます。
Cells: Cells は Cell インスタンスに適したスキーマを定義するために独自のテナントモデルスキーマを使用します。
Instrumentor
Instrumentor はプロビジョニングと設定ツールです。Instrumentor への外部抽象化はテナントモデルスキーマであり、インターフェースや上流クライアントに影響を与えることなく、異なるツールを使用し、時間の経過とともに置き換えることができます。現在、Instrumentor は Terraform、Ansible、Helm、Kubernetes マニフェストを使用しています。
Cells は Dedicated GCP Instrumentor を使用するか、そのフォークを使用するかのいずれかになります。決定を下す前にさらなる分析が必要です。
テナントコントロール: tenctl
tenctl(テナントコントローラー)は、プロビジョニングプロセス全体で広く使用される golang バイナリです。また、開発時の使用と GitLab CI/CD でもローカルでの実行をサポートしています。
tenctl はさまざまなツール(Terraform、Ansible など)とテナントデータ間のギャップを埋めます。これには以下が含まれます:
- クラウドプロバイダー設定ファイル(
.aws_credentials.ini、AWS_REGION環境変数など)などの基礎ツールの設定処理 - 認証と認可の処理
- GET、Ansible、Terraform などが必要とする設定ファイルをテンプレート化するための単一の方法(Jsonnet を使用し、YAML、ini、JSON、その他すべての必要なコマンドタイプを生成できる)
- 同様のプロジェクトでは、このテンプレート化は通常、さまざまなツール(jq、Go テンプレート、envsubst、bash スクリプトの文字列連結など)を使用して行われます
- 単一ツールを持つことで、はるかに一貫したテンプレート化、テストハーネスなどが可能になります
- JSON スキーマを使用したテナントモデルスキーマ検証。
- テナントモデルが手動介入なしで自動的にアップグレードできるようにするテナントモデル移行ツール
- バックアップのステータスの確認など、Ansible、Terraform などでカバーされないクラウドプロバイダーオーケストレーション。
多くのプロビジョニングツールでは、tenctl が提供する機能は通常、一連の bash スクリプトとして書かれています。これらのスクリプトは構造化されておらず、スケールアップが困難で、テストと検証が困難です。これにより開発が遅くなり、プロビジョニングや Day 2 運用中のバグやデータ損失さえ引き起こす可能性があります。
このツールを Go で書くことで、すべての環境で同一に動作する単一ツール(MacOS と異なるバージョンの Linux でのコマンドラインツールへのシェルアウトの違いがない)の利点が得られ、完全にテストされています。さらに、Go はより良い構造を促し、プロジェクトの複雑さが時間の経過とともに増加しても構造がスケールできることを保証します。
tenctl の代替は、今日多くのインフラストラクチャプロジェクトで見られるもの: 保守されていない - そして保守できない - テストされていない bash スクリプトが数十もあり、それぞれが独自の入力、引数、実行できる環境のサブセット、入力データを設定データに変換する独自の方法を持っています。これにより複雑さ、不一致、認知的負荷が生じ、最終的には予期しない動作(別名:「自分のマシンでは動いた」)によるより低い速度と障害さえ引き起こします。
類推でこれを説明すると:bash と curl だけを使用して Kubernetes クラスターとインタラクションすることは可能です。ただし、kubectl を使用するとはるかに一貫性があり、スケーラブルなクライアントが提供されます。tenctl は kubectl に似ていますが、Kubernetes インスタンスではなく GitLab テナントインスタンスに焦点を当てています。
Cells は tenctl のようなツールを使用することで大きな恩恵を受けます。異なるツール全体で設定をテンプレート化する単一の方法があることで、現在 GitLab.com 環境に存在するドリフトを避けることができます。
Dedicated が Cells をサポートするためにどのように使用できるか
設計上の考慮事項
GitLab Dedicated に適用される設計上の考慮事項の多くは、Cells のデプロイにも同様に適用されます。
- 多数の均質な環境が必要になります
- 環境間の各潜在的な違いは、それらの違いの組み合わせ数が指数関数的に増加することになります
- 環境を複数の独立したモジュールとして定義することは、すぐに維持不可能になります
- 潜在的な組み合わせが多くなるほど:
- Day 2 運用の環境自動化が困難になります
- 変更のテスト可能性が低下します
- 単一のアトミックプロビジョナーを持つ均質な GitLab 環境は、多数の環境にわたって変更を段階的にロールアウトできます。これは Kubernetes のレプリカセットが新しいポッドを段階的にロールアウトし、すべての古いポッドが置き換えられるまで古いバージョンを安全に置き換えていくのと大きく異なりません。
環境自動化を使用した Cells のデプロイ
Cells は、Switchboard が開発される前に Environment Automation が使用していたデプロイモデルと同じものを使用できます。これは switchboard_la プロジェクトで表されています。

環境自動化を使用した Cells のデプロイ
このデプロイモデルでは、グラフィカルユーザーインターフェースを省略し、DevOps モデルを提供します。このアプローチは、SRE が作業する方法とはるかに一致しています。 プロジェクトは GitLab インスタンスで維持され、テナントモデルは git リポジトリ内のファイルとして保管されます。
すべての変更は標準的な GitLab 承認アプローチによるマージリクエストで制御されます。
変更がメインブランチにマージされると、CI パイプラインが開始され、Amp 環境でジョブが開始されます。SRE は CI トレースなどの標準的な GitLab ツールを使用して変更の進行状況を監視できます。
