Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | - |
このドキュメントは作業中のものであり、セルズの設計のごく初期の状態を表しています。重要な点は文書化されていませんが、将来的には追加される予定です。これはCellsの可能性のあるアーキテクチャの一つであり、どのアプローチを実装するか決める前に、代替案と比較検討するつもりです。この文書化は、このアプローチを選ばなかった理由を文書化できるよう、これを実装しないと決めた場合でも残しておきます。
Cells:コンテナ・レジストリ
GitLabContainer RegistryはGitLabにDockerコンテナイメージを保存できる機能です。
1.定義
GitLabコンテナレジストリは、PostgreSQL、Redis、オブジェクトストレージの依存関係を必要とする複雑なサービスです。現在、コンテナレジストリのデータストレージとイメージ保持ポリシーを最適化するために、コンテナレジストリメタデータを導入する作業が行われています。
GitLabコンテナレジストリは保存されたデータのコンテナとして機能しますが、それだけでは認証しませんdocker login
。 docker login
ユーザー認証情報(personal access token
)またはCIビルド認証情報(ephemeralci_builds.token
)を使って実行docker login
さ docker login
れます。
コンテナレジストリはデータ重複排除を使用します。これは、多くのプロジェクト間で共有される同じブロブ(イメージレイヤー)が一度だけ保存されることを意味します。各レイヤーはsha256
によってハッシュ化されます。
docker login
、GitLabによって署名されたJWT時間制限付き認証トークンを要求しますが、コンテナレジストリサービスによって検証されます。JWT トークンは、すべての作成者スコープ (container repository images
) とオペレーションタイプ (push
またはpull
) を保存します。一つのJWT認証トークンは多くの認可スコープを持つことができます。これにより、コンテナレジストリやクライアントは、他のスコープから既存のブロブをマウントすることができます。GitLabは作成者が許可したスコープのみで応答します。そして、与えられたオペレーションが実行できるかどうかを検証するのはGitLabコンテナレジストリ次第です。
GitLab.comのPagesは常にプロジェクトにスコープされます。各プロジェクトは多くのコンテナレジストリイメージを添付することができます。
現在GitLab.comでは、実際のレジストリサービスはhttps://registry.gitlab.com
。
主な問題点は以下の通りです:
- GitLab.comによって処理される認証リクエスト(
https://gitlab.com/jwt/auth
)。 - 外部サービスによって実行され、独自のデータストアを使用する
https://registry.gitlab.com
。 - データの重複排除。レジストリがCell内で実行されるCellsアーキテクチャは、データストレージの効率を低下させます。
2.データフロー
2.1.作成者が送信する承認リクエスト。docker login
curl \
--user "username:password" \
"https://gitlab/jwt/auth?client_id=docker&offline_token=true&service=container_registry&scope=repository:gitlab-org/gitlab-build-images:push,pull"
結果はエンコードされ、署名されたJWTトークンです。2番目のBase64エンコードされた文字列(.
で分割)には、認可されたスコープを持つJSONが含まれています。
{"auth_type":"none","access":[{"type":"repository","name":"gitlab-org/gitlab-build-images","actions":["pull"]}],"jti":"61ca2459-091c-4496-a3cf-01bac51d4dc8","aud":"container_registry","iss":"omnibus-gitlab-issuer","iat":1669309469,"nbf":166}
2.2.Dockerクライアントはタグを取得します。
curl \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Bearer token" \
https://registry.gitlab.com/v2/gitlab-org/gitlab-build-images/tags/list
curl \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Bearer token" \
https://registry.gitlab.com/v2/gitlab-org/gitlab-build-images/manifests/danger-ruby-2.6.6
2.3.Dockerクライアントがブロブとマニフェストをフェッチします。
curl \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Bearer token" \
https://registry.gitlab.com/v2/gitlab-org/gitlab-build-images/blobs/sha256:a3f2e1afa377d20897e08a85cae089393daa0ec019feab3851d592248674b416
3.提案
3.1.コンテナレジストリをCellsアーキテクチャとは別にシャード化。
GitLabコンテナレジストリはその広範で一般的にスケーラブルな水平アーキテクチャのため、CellではなくClusterで実行し、独立してスケーリングするべきかどうかを評価する必要があります。この方が簡単かもしれませんが、間違いなく同じ量のデータの分離はできません。
3.2.セル内でコンテナレジストリを実行
/jwt/auth
scope
を除いて、コンテナ・レジストリは Cell の内部サービスとして実行することができます。少なくともGitLab.comの場合、実際のデータはレジストリ経由で転送されるのではなく、オブジェクトストレージ/CDNから直接提供されます。
GitLab.comのデザインは、コンテナのリポジトリイメージをルーティングしやすいURLにエンコードしています。コンテナレジストリの前に同じステートレスルーターサービスを再利用することで、マニフェストやブロブをリダイレクトして提供することができそうです。
唯一の欠点は、セルごとにスタンドアロンのレジストリを管理する複雑さが増すことですが、これは望ましいアプローチかもしれません。
4.評価
GitLabコンテナレジストリをCellで動作させることに理論的な問題はないようです。サービスは簡単にルーティング可能にしてうまく動作させることができるようです。現実的に複雑なのは、インフラ側から複雑なサービスを管理することです。