Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
accepted |
@nolith
|
@glopezfernandez
|
@marin
| devops data_stores | 2021-11-18 |
オブジェクトストレージ:direct_upload
統合
概要
GitLabは3つのユーザーデータを保存します:データベースレコード、Gitリポジトリ、そしてユーザーがアップロードしたファイル(ブループリント全体を通してファイルストレージと呼ばれます)。
ファイルストレージに対するユーザーと貢献者のエクスペリエンスには、大幅な改善の余地があります:
- GitLabの初期設定には、1バケットだけでなく13バケットの作成と設定が必要です。
- ファイルストレージを使う機能では、貢献者はローカルストレージとオブジェクトストレージの両方を考える必要があります。その結果、機能が壊れたりセキュリティのイシューが発生したりします。
- ファイルストレージを扱うコントリビューターは、Workhorse、Omnibus、クラウドネイティブの GitLab(CNG) 用のコードも書かなければならないことがよくあります。
問題の定義
オブジェクトストレージはGitLabの基本コンポーネントであり、共有、分散、可用性の高い(HA) ファイルストレージの内部実装を提供します。
時間をかけて、私たちはアプリケーション全体でオブジェクトストレージのサポートを構築し、何度も繰り返しながら特定の問題を解決してきました。このため、開発者(新機能やバグ修正)からインストールに至るまで、全体的に複雑さが増しています:
- GitLabの新しいインストールでは、機能のグループごとに必要なオブジェクトストレージのバケットを1つだけでなく複数作成し設定する必要があります。これはインストールエクスペリエンスや新機能の採用に影響を与え、退屈なソリューションからさらに遠ざかることになります。
- クラウドネイティブのGitLabのリリースには、NFS共有ストレージの削除とダイレクトアップロードの開発者が必要でした。この機能はマイルストーンに次ぐマイルストーンで、いくつかのタイプのアップロードに拡張されましたが、グローバルに有効になることはありませんでした。
- 今日、GitLabはローカルストレージとオブジェクトストレージの両方をサポートしています。ローカルストレージはシングルボックスのインストールかNFSでのみ動作します。NFSはもはやユーザーに推奨しておらず、GitLab.comでも使われていません。
- CarrierWave、Fog、Go S3/Azure SDKがすべて使用されており、テストも複雑になっています。
- FogとCarrierWaveはネイティブSDK(例えばAWS S3 SDK)のレベルまでメンテナンスされていないため、通常であれば “無料 “であるはずの顧客からのリクエスト機能(例えばイシュー#242245)をサポートするために、これらのツールをメンテナーやモンキーパッチを当てなければなりません。
- 多くの場合、オブジェクトストレージのファイルを無駄にコピーしています(例えば、イシュー#285597)。大きなファイル(たとえばLFSやパッケージ)は、最終化するのに時間がかかったり、結果としてまったく動作しません。
現状からの改善点
以下は、オブジェクトストレージの実装に影響を与えているペインポイントを取り除くために、私たちが取ることができる主な方向性を簡単に説明したものです。
これは、オブジェクトストレージワーキンググループのために録画されたYouTubeビデオとしても利用可能です。
MinIOを出荷してGitLabアーキテクチャをシンプルに
当初、オブジェクトストレージのサポートはPremiumの機能であり、私たちのCEディストリビューションの一部ではありませんでした。そのため、ローカルストレージとオブジェクトストレージの両方をサポートしなければなりませんでした。
ローカルストレージでは、コンポーネント間でストレージを共有することが前提です。これは、シングルボックスインストール、HAなし、またはNFSを使用することで実現できます。
オブジェクトストレージについては、テストギャップがあります。また、WorkhorseとMinIOが必要ですが、これらは私たちのパイプラインには存在しないため、モック実装に置き換えられる部分が多すぎます。さらに、CIでもローカル開発者でも、共有ディスクの存在は、HA環境にデプロイするまで、しばしば壊れた実装を隠してしまいます。
MinIOを製品の一部として出荷することを検討するのも1つの方法です。これにより、クラウドとローカルインストールの違いを減らし、ファイルストレージを単一のテクノロジーで標準化することができます。
ローカルのディスクオペレーションがなくなることで、開発の複雑さが軽減されるだけでなく、ユーザー提供のデータをローカルストレージに書き込まなくなるため、いくつかのセキュリティ攻撃ベクトルが緩和されます。
また、開発モードでは常にローカルオブジェクトストレージを実行し、マージリクエストレビュー時にローカルファイルへのディスクアクセスは赤旗を立てることになるので、ヒューマンエラーも減らすことができます。
この取り組みについては、このエピックで説明します。
特定のサードパーティ技術を検討する前に、オープンソースソフトウェアライセンスの影響を考慮する必要があります。2021年4月23日現在、MinIOはAGPL v3ライセンスの対象です。このブループリントで提案されているMinIOの出荷を決定する前に、GitLab Legalに相談する必要があります。
すべてのアップロードでデフォルトで直接アップロードを有効にします。
機能のグループごとに専用のバケットが必要なため、すべての場所で直接アップロードを有効にしているわけではありません。新しいアップロードに貢献するには、Ruby on Rails と Go の両方でコーディングする必要があります。
専用のバケットがない新機能を実装するには、開発者は Omnibus と CNG でマージリクエストを作成し、SRE と調整して新しいバケットを私たちの環境に設定する必要があります。
ユーザーが GitLab を再設定し、インフラストラクチャに新しいバケットを用意する必要があるためです。また、初期インストールがより複雑になります。
デフォルトでダイレクトアップロードを実装し、オブジェクトストレージを統合設定することで、新機能を出荷するために必要なマージリクエストの数を4つから1つに減らすことができます。また、バケットが常に同じになるため、SREの介入も不要になります。
これにより、GitLab 設定ファイルだけでなく、開発者とレビューのプロセスも簡素化されます。そして、全てのユーザーはインフラストラクチャの雑用なしに、すぐに新機能にアクセスできるようになります。
オブジェクトストレージのコードを簡素化
私たちの実装はサードパーティのフレームワークの上に構築されており、オブジェクトストレージクライアントはすべてサードパーティのライブラリです。残念ながら、その中にはメンテナンスされていないものもあります。5GBのGit LFSオブジェクトをプッシュできない顧客もいますが、このような重要な機能がサードパーティライブラリに実装されているため、私たちはその修正に手間取っており、修正をマージしてリリースするのも外部のメンテナーに頼っています。
直接アップロードが導入される前は、「_Rubyアプリケーションからファイルをアップロードするシンプルで非常に柔軟な方法を提供するgem」_であるCarrierWaveライブラリを使用するのが退屈な解決策でした。しかし、Workhorseからファイルをアップロードするため、CarrierWaveの内部をパッチして直接アップロードをサポートする必要がありました。
CarrierWaveの削除と新しい合理化された内部アップロードAPIを含む簡単な提案は、このイシューコメントに記載されています。
理想的には、オブジェクトストレージクライアントをGoとRubyで重複させる必要はありません。CarrierWaveを削除することで、プロバイダのS3互換性レベルが十分でない場合に、公式にサポートされているネイティブクライアントを利用することができます。
イテレーション
このセクションでは、可能性のある反復をいくつか挙げます。これは最終的なロードマップを意図したものではなく、オブジェクトストレージワーキンググループのために始めた会話です。
- CarrierWaveを使用しない認可のために、新しいキャッチオールバケットと統一された内部APIを作成します。
- MinIOをOmnibusと一緒に出荷(CNGイメージにはすでに含まれています)。
- GitLab-QA を拡張して、サポートされているすべての設定をカバーします。
- ローカルディスクへのアクセスを廃止。
- 複数のバケットを使用する設定を廃止。
- バケット間のマイグレーションを実装。
- 現在のCarrierWaveのアップロードを新しい実装にマイグレーションします。
- 次のメジャーリリースで:ローカルディスクへのアクセスおよび複数のバケットを使用した設定のサポートを削除します。
現在の反復計画の利点
現在の計画は、最初のステップから目に見えるメリットを提供するように設計されています。
キャッチボールバケツの導入により、現在直接アップロードの対象になっていないすべてのアップロードがその恩恵を受けられるようになり、1回のマージリクエストで新機能を出荷できるようになります。
MinIOをOmnibusと一緒に出荷することで、新規インストールをオブジェクトストレージにデフォルト設定できるようになり、Omnibusがバケットの作成を担当できるようになります。これにより、Kubernetes以外でのHAインストールが簡素化されます。
そして、CarrierWaveの各アップローダを新しい実装にマイグレーションし、GitLabのインストールが1つのバケットで済むようにします。
追加資料
- 開発者ガイドをアップロードします。
- モノリスの高速化、Go によるスマートなリバースプロキシの構築: Workhorse の歴史と、最初のクラウド ネイティブ インストールをリリースする際に直面した課題について説明するプレゼンテーションです。
- オブジェクトストレージの改善エピック。
- GraphQL APIに移行していますが、直接アップロードはサポートしていません。