GitLabアーキテクチャ概要

ソフトウェアの配布

GitLabには2つのソフトウェアディストリビューションがあります:

GitLabは様々なサブスクリプションで利用できます。

GitLabの新しいバージョンは安定版ブランチからリリースされ、main ブランチは最先端の開発に使用されます。

詳しくはGitLabのリリースプロセスをご覧ください。

どちらのディストリビューションも追加のコンポーネントを必要とします。これらのコンポーネントはコンポーネントの詳細セクションで説明されており、すべて独自のリポジトリを持っています。各依存コンポーネントの新しいバージョンは通常タグ付けされていますが、GitLabコードベースのmain ブランチに滞在することで、それらのコンポーネントの最新の安定バージョンを入手することができます。新しいバージョンは一般的にGitLabのリリースと同時期にリリースされますが、クリティカルと判断された非公式のセキュリティアップデートは例外です。

コンポーネント

GitLabの典型的なインストールはGNU/Linuxですが、Kubernetesプラットフォームを使用するデプロイも増えています。知られている最大のGitLabインスタンスはGitLab.comにあり、私たちの公式GitLab Helmチャートと 公式Linuxパッケージを使ってデプロイされています。

典型的なインストールでは、GitLab Workhorseを経由してPumaアプリケーションサーバーにプロキシするウェブサーバーとしてNGINXまたはApacheを使用します。GitLabはPumaアプリケーションサーバーを使ってWebページやGitLab APIを提供します。ジョブキューとしてSidekiqを使い、ジョブ情報、メタデータ、受信ジョブのための非永続データベースバックエンドとしてRedisを使います。

デフォルトでは、PumaとWorkhorse間の通信はUnixドメインソケット経由ですが、TCP経由でのリクエスト転送もサポートされています。Workhorse はgitlab/public ディレクトリにアクセスし、Puma アプリケーションサーバーをバイパスして静的ページ、アップロード (アバター画像や添付ファイルなど)、コンパイル済みアセットを提供します。

GitLabアプリケーションは、永続的なデータベース情報(ユーザー、権限、イシュー、その他のメタデータなど)のためにPostgreSQLを使用します。GitLabは、素のGitリポジトリを設定ファイルのrepositories: セクションで定義された場所に保存します。また、デフォルトのブランチとフック情報もベアリポジトリと一緒に保持します。

HTTP/HTTPSでリポジトリを提供するとき、GitLabはGitLab APIを使って認可とアクセスを解決し、Gitオブジェクトを提供します。

アドオンコンポーネントのGitLab ShellはSSHでリポジトリを提供します。設定ファイル GitLab Shell セクションで定義された場所でSSHキーを管理します。その場所のファイルは決して手動で編集してはいけません。GitLab ShellはGitalyを通してベアリポジトリにアクセスしてGitオブジェクトを提供し、Redisと通信してGitLabが処理するためのジョブをSidekiqに投入します。GitLab ShellはGitLab APIをクエリして作成者とアクセスを決定します。

GitalyはGitLab ShellとGitLabウェブアプリからGitオペレーションを実行し、GitLabウェブアプリにAPIを提供してGitから属性(例えば、タイトル、ブランチ、タグ、その他のメタデータ)を取得し、ブロブ(例えば、差分、コミット、ファイル)を取得します。

GitLab.comのプロダクションアーキテクチャにも興味があるかもしれません。

既存のコンポーネントの適応と新しいコンポーネントの導入

Kubernetesのようなコンテナ化されたプラットフォームと比較して、従来のLinuxマシンにインストールした場合のアプリケーションの動作には根本的な違いがあります。

私たちの公式のインストール方法と比較すると、注目すべき違いがいくつかあります:

  • 公式Linuxパッケージは、異なるサービスで同じファイルシステム上のファイルにアクセスできます。Kubernetesプラットフォーム上で動作するアプリケーションでは、共有ファイルはオプションではありません。
  • 公式Linuxパッケージはデフォルトで、共有設定とネットワークにアクセスできるサービスを持っています。これはKubernetesで実行されるサービスには当てはまらず、サービスは完全に隔離された状態で実行されていたり、特定のポートからのみアクセス可能であったりします。

つまり、新機能のアーキテクトや新しいコンポーネントを追加する際には、サービス間の共有状態を注意深く考慮する必要があります。同じファイルにアクセスする必要があるサービスは、適切なAPIを通じて情報を交換できる必要があります。可能な限り、これはファイルでは行われるべきではありません。

APIファーストを念頭に置いて書かれたコンポーネントはどちらの方式とも互換性があるため、新しい機能やサービスはすべてKubernetesとの互換性を第一に考えて書かなければなりません。

これを確実にする最も簡単な方法は、公式GitLab Helmチャートにあなたの機能やサービスのサポートを追加するか、ディストリビューションチームに連絡することです。

詳細については、新しいサービスコンポーネントを追加するプロセスを参照してください。

簡易コンポーネントの概要

GitLabのアーキテクチャを理解するために使える簡易アーキテクチャ図です。

完全なアーキテクチャ図は以下のコンポーネント図にあります。

Simplified Component Overview

コンポーネント図

%%{init: {"flowchart": { "useMaxWidth": false } }}%% graph LR %% Anchor items in the appropriate subgraph. %% Link them where the destination* is. subgraph Clients Browser((Browser)) Git((Git)) end %% External Components / Applications Geo{{GitLab Geo}} -- TCP 80, 443 --> HTTP Geo -- TCP 22 --> SSH Geo -- TCP 5432 --> PostgreSQL Runner{{GitLab Runner}} -- TCP 443 --> HTTP K8sAgent{{GitLab Agent}} -- TCP 443 --> HTTP %% GitLab Application Suite subgraph GitLab subgraph Ingress HTTP[[HTTP/HTTPS]] SSH[[SSH]] NGINX[NGINX] GitLabShell[GitLab Shell] %% inbound/internal Browser -- TCP 80,443 --> HTTP Git -- TCP 80,443 --> HTTP Git -- TCP 22 --> SSH HTTP -- TCP 80, 443 --> NGINX SSH -- TCP 22 --> GitLabShell end subgraph GitLab Services %% inbound from NGINX NGINX --> GitLabWorkhorse NGINX -- TCP 8090 --> GitLabPages NGINX -- TCP 8150 --> GitLabKas NGINX --> Registry %% inbound from GitLabShell GitLabShell --> GitLabWorkhorse %% services Puma["Puma (GitLab Rails)"] Puma <--> Registry GitLabWorkhorse[GitLab Workhorse] <--> Puma GitLabKas[GitLab Agent Server] --> GitLabWorkhorse GitLabPages[GitLab Pages] --> GitLabWorkhorse Mailroom Sidekiq end subgraph Integrated Services %% Mattermost Mattermost Mattermost ---> GitLabWorkhorse NGINX --> Mattermost %% Grafana Grafana NGINX --> Grafana end subgraph Metadata %% PostgreSQL PostgreSQL PostgreSQL --> Consul %% Consul and inbound Consul Puma ---> Consul Sidekiq ---> Consul Migrations --> PostgreSQL %% PgBouncer and inbound PgBouncer PgBouncer --> Consul PgBouncer --> PostgreSQL Sidekiq --> PgBouncer Puma --> PgBouncer end subgraph State %% Redis and inbound Redis Puma --> Redis Sidekiq --> Redis GitLabWorkhorse --> Redis Mailroom --> Redis GitLabKas --> Redis %% Sentinel and inbound Sentinel <--> Redis Puma --> Sentinel Sidekiq --> Sentinel GitLabWorkhorse --> Sentinel Mailroom --> Sentinel GitLabKas --> Sentinel end subgraph Git Repositories %% Gitaly / Praefect Praefect --> Gitaly GitLabKas --> Praefect GitLabShell --> Praefect GitLabWorkhorse --> Praefect Puma --> Praefect Sidekiq --> Praefect Praefect <--> PraefectPGSQL[PostgreSQL] %% Gitaly makes API calls %% Ordered here to ensure placement. Gitaly --> GitLabWorkhorse end subgraph Storage %% ObjectStorage and inbound traffic ObjectStorage["Object Storage"] Puma -- TCP 443 --> ObjectStorage Sidekiq -- TCP 443 --> ObjectStorage GitLabWorkhorse -- TCP 443 --> ObjectStorage Registry -- TCP 443 --> ObjectStorage GitLabPages -- TCP 443 --> ObjectStorage end subgraph Monitoring %% Prometheus Grafana -- TCP 9090 --> Prometheus[Prometheus] Prometheus -- TCP 80, 443 --> Puma RedisExporter[Redis Exporter] --> Redis Prometheus -- TCP 9121 --> RedisExporter PostgreSQLExporter[PostgreSQL Exporter] --> PostgreSQL PgBouncerExporter[PgBouncer Exporter] --> PgBouncer Prometheus -- TCP 9187 --> PostgreSQLExporter Prometheus -- TCP 9100 --> NodeExporter[Node Exporter] Prometheus -- TCP 9168 --> GitLabExporter[GitLab Exporter] Prometheus -- TCP 9127 --> PgBouncerExporter Prometheus --> Alertmanager GitLabExporter --> PostgreSQL GitLabExporter --> GitLabShell GitLabExporter --> Sidekiq %% Alertmanager Alertmanager -- TCP 25 --> SMTP end %% end subgraph GitLab end subgraph External subgraph External Services SMTP[SMTP Gateway] LDAP %% Outbound SMTP Sidekiq -- TCP 25 --> SMTP Puma -- TCP 25 --> SMTP Mailroom -- TCP 25 --> SMTP %% Outbound LDAP Puma -- TCP 369 --> LDAP Sidekiq -- TCP 369 --> LDAP %% Elasticsearch Elasticsearch Puma -- TCP 9200 --> Elasticsearch Sidekiq -- TCP 9200 --> Elasticsearch end subgraph External Monitoring %% Sentry Sidekiq -- TCP 80, 443 --> Sentry Puma -- TCP 80, 443 --> Sentry %% Jaeger Jaeger Sidekiq -- UDP 6831 --> Jaeger Puma -- UDP 6831 --> Jaeger Gitaly -- UDP 6831 --> Jaeger GitLabShell -- UDP 6831 --> Jaeger GitLabWorkhorse -- UDP 6831 --> Jaeger end %% end subgraph External end click Alertmanager "./architecture.html#alertmanager" click Praefect "./architecture.html#praefect" click Geo "./architecture.html#gitlab-geo" click NGINX "./architecture.html#nginx" click Runner "./architecture.html#gitlab-runner" click Registry "./architecture.html#registry" click ObjectStorage "./architecture.html#minio" click Mattermost "./architecture.html#mattermost" click Gitaly "./architecture.html#gitaly" click Jaeger "./architecture.html#jaeger" click GitLabWorkhorse "./architecture.html#gitlab-workhorse" click LDAP "./architecture.html#ldap-authentication" click Puma "./architecture.html#puma" click GitLabShell "./architecture.html#gitlab-shell" click SSH "./architecture.html#ssh-request-22" click Sidekiq "./architecture.html#sidekiq" click Sentry "./architecture.html#sentry" click GitLabExporter "./architecture.html#gitlab-exporter" click Elasticsearch "./architecture.html#elasticsearch" click Migrations "./architecture.html#database-migrations" click PostgreSQL "./architecture.html#postgresql" click Consul "./architecture.html#consul" click PgBouncer "./architecture.html#pgbouncer" click PgBouncerExporter "./architecture.html#pgbouncer-exporter" click RedisExporter "./architecture.html#redis-exporter" click Redis "./architecture.html#redis" click Prometheus "./architecture.html#prometheus" click Grafana "./architecture.html#grafana" click GitLabPages "./architecture.html#gitlab-pages" click PostgreSQLExporter "./architecture.html#postgresql-exporter" click SMTP "./architecture.html#outbound-email" click NodeExporter "./architecture.html#node-exporter"

コンポーネント凡例

  • デフォルトでインストールされています。
  • ⚙ - 追加設定が必要です。
  • ⤓ 手動インストールが必要です。
  • ❌ - サポートされていないか、説明書がありません。
  • N/A - 該当しません。

コンポーネントのステータスは、各コンポーネントの設定ドキュメントにリンクされています。

コンポーネントリスト

コンポーネント説明Omnibus GitLabGitLab 環境ツールキット(GET)GitLab チャートminikube ミニマルGitLab.comソースGDKCE/EE
証明書管理TLS設定, Let’s EncryptCE & EE
Consulデータベースノードの検出、フェイルオーバーEEのみ
データベースのマイグレーションデータベースのマイグレーションCE & EE
ElasticsearchGitLab内の検索が改善されました。EEのみ
GitalyGitLabによるすべてのGitコールを処理するGit RPCサービスCE & EE
GitLab Exporter様々なGitLabメトリクスを生成します。CE & EE
GitLab Geo地理的に分散したGitLabサイトEEのみ
GitLab Pages静的ウェブサイトのホスティングCE & EE
GitLabエージェントKubernetesクラスタをクラウドネイティブな方法でインテグレーションEEのみ
GitLab セルフモニタリング:アラートマネージャーPrometheusからのアラートを重複排除、グループ化、ルーティングします。CE & EE
GitLabのセルフモニタリング:GrafanaメトリクスダッシュボードCE & EE
GitLab セルフモニタリング:イェーガーGitLabインスタンスによって生成されたトレースを表示CE & EE
GitLab セルフモニタリング:Prometheus時系列データベース、メトリクス収集、クエリサービスCE & EE
GitLab セルフモニタリング:SentryGitLabインスタンスによって生成されたエラーを追跡CE & EE
GitLab シェルSSH セッションでgit を処理します。CE & EE
GitLab Workhorseスマートなリバースプロキシ。CE & EE
インバウンドメール(SMTP)イシュー更新のためのメッセージ受信CE & EE
イェーガー・インタグレーションデプロイ済みアプリの分散トレースEEのみ
LDAP認証集中LDAPディレクトリに対してユーザーを認証CE & EE
MattermostオープンソースのSlack代替ツールCE & EE
MinIOオブジェクトストレージサービスCE & EE
NGINXリクエストを適切なコンポーネントにルーティングし、SSLを終了します。CE & EE
ノードエクスポーターシステム・メトリクスを備えたPrometheusエンドポイント該当なし該当なしCE & EE
送信メール(SMTP)ユーザーへのメール送信CE & EE
パトロニPostgreSQL HAクラスタリーダの選択とレプリケーションの管理EEのみ
PgBouncer ExporterPgBouncerメトリクスとPrometheusエンドポイントCE & EE
PgBouncerデータベース接続プール、フェイルオーバーEEのみ
PostgreSQLエクスポートPostgreSQLメトリクスを使用したPrometheusエンドポイントCE & EE
PostgreSQLデータベースCE & EE
PraefectGitクライアントとGitalyストレージノード間の透過的なプロキシです。CE & EE
Puma (GitLab Rails)ウェブインターフェースとAPIへのリクエストを処理CE & EE
Redis エクスポートRedisメトリクス付きPrometheusエンドポイントCE & EE
RedisキャッシュサービスCE & EE
レジストリコンテナレジストリ、イメージのプッシュ&プルが可能CE & EE
RunnerGitLab CI/CDジョブの実行CE & EE
インテグレーションデプロイされたアプリのエラートラッキングCE & EE
SidekiqバックグラウンドジョブプロセッサCE & EE
トークン失効API流出したシークレットの受信と失効EEのみ

コンポーネント詳細

このドキュメントは、GitLabの内部とそれらがどのように連携しているのかをより深く理解したいシステム管理者やGitLabサポートエンジニアが読むことを想定しています。

デプロイされたとき、GitLabは以下のプロセスの融合と考えるべきです。トラブルシューティングやデバッグの際には、どのコンポーネントを参照しているのかをできるだけ具体的に説明してください。そうすることで、より明確になり、混乱を減らすことができるはずです。

レイヤー

GitLabには、プロセスの観点から2つのレイヤーがあると考えることができます:

  • モニタリング:このレイヤーは、GitLabをアプリケーションとして提供するために必要なものではありませんが、管理者がインフラストラクチャやサービス全体の動きをより深くインサイトできるようにします。
  • Core:プラットフォームとしてGitLabを提供するために不可欠なプロセス。これらのプロセスのどれかが停止すると、GitLabが停止します。Coreレイヤーについては、さらに以下のように分けることができます:
    • プロセッサ:これらのプロセスは、実際にオペレーションを実行し、サービスを表示する役割を担っています。
    • データ:これらのサービスはGitLabサービスの構造化データを保存/公開します。

アラートマネージャー

アラートマネージャはPrometheusが提供するツールで、_Prometheusサーバなどのクライアントアプリケーションから送信されたアラートを処理_します。_電子メール、PagerDuty、Opsgenieなどの適切な受信者インテグレーションへの重複排除、グループ化、ルーティングを行います。また、アラートの消音や抑制も行います。_イシュー#45740で、私たちがどのようなアラートを発しているか、さらに詳しくご覧いただけます。

証明書管理

Consul

Consulはサービスの発見と設定のためのツールです。Consulはディストリビューションで、可用性が高く、非常にスケーラブルです。

データベースのマイグレーション

Elasticsearch

Elasticsearch はクラウド向けに構築されたディストリビューション RESTful 検索エンジンです。

Gitaly

Gitalyは、GitLabの分散デプロイメント(GitLab.comや高可用性デプロイメントを考えてください)におけるGitストレージのためのNFSの必要性を取り除くためにGitLabによって設計されたサービスです。11.3.0現在、このサービスはGitLabの全てのGitレベルのアクセスを扱っています。プロジェクトについての詳細はプロジェクトのREADMEをご覧ください。

Praefect

Praefectは、各Gitクライアントとセカンダリノードへのリポジトリ更新のレプリケーションを調整するGitalyの間の透過的なプロキシです。

GitLab Geo

Geoは、プライマリGitLabインスタンスの読み取り専用ミラーを1つ以上提供することで、分散チームの開発スピードアップを支援するために構築されたプレミアム機能です。このミラー(Geoセカンダリサイト)は、大規模なリポジトリやプロジェクトのクローンやフェッチにかかる時間を短縮したり、ディザスタリカバリソリューションの一部になったりします。

GitLab Exporter

GitLab Exporterは、GitLabアプリケーション内部に関するメトリクスをPrometheusにエクスポートするために社内で設計されたプロセスです。詳しくはプロジェクトのREADMEをご覧ください。

GitLabエージェント

GitLabエージェントは、GitLabとKubernetesのインテグレーションタスクをセキュリティとクラウドネイティブな方法で解決するためのアクティブなクラスタ内コンポーネントです。

Kubernetesクラスターへのデプロイ同期に利用できます。

GitLab Pages

GitLab Pagesは、GitLabのリポジトリから静的なウェブサイトを直接公開できる機能です。

ポートフォリオ、ドキュメント、マニフェスト、ビジネスプレゼンテーションなど、個人的なウェブサイトにもビジネスウェブサイトにも使用できます。コンテンツに任意のライセンスを付与することもできます。

GitLab Runner

GitLab Runnerはジョブを実行し、結果をGitLabに送信します。

GitLab CI/CDはGitLabに含まれるオープンソースの継続的インテグレーションサービスで、テストを調整します。このプロジェクトの古い名前はGitLab CI Multi Runner でしたが、今後はGitLab Runner (CIなし) を使ってください。

GitLab シェル

GitLab ShellはGitLabで設計されたプログラムで、SSHベースのgit セッションを処理し、作成者キーのリストを変更します。GitLab ShellはUnixシェルではなく、BashやZshの代わりでもありません。

GitLab Workhorse

GitLab Workhorseは、Pumaからのプレッシャーを軽減するためにGitLabで設計されたプログラムです。開発者の歴史的な理由についてはこちらをご覧ください。GitLab Workhorseはスマートなリバースプロキシとして機能し、GitLab全体のスピードアップを助けるように設計されています。

Grafana

Grafana は、Graphite、Elasticsearch、OpenTSDB、Prometheus、InfluxDB 用の、オープンソースで機能豊富なメトリクスダッシュボードとグラフエディタです。

イェーガー

JaegerはDapperとOpenZipkinにインスパイアされたディストリビューショントレースシステムです。マイクロサービスベースの分散システムのモニタリングに使えます。

Logrotate

GitLabは多くのサービスで構成されており、その全てがログを記録します。私たちは責任を持ってログを記録するために、独自のLogrotateをバンドルしました。これは一般的なオープンソースのパッケージ版です。

Mattermost

Mattermost はhttps://mattermost.comが提供するオープンソース、非公開クラウド、Slack 代替サービスです。

MinIO

MinIOはGNU AGPL v3.0でリリースされたオブジェクトストレージサーバーです。Amazon S3クラウドストレージサービスと互換性があります。写真、ビデオ、ログファイル、バックアップ、コンテナ/VMイメージなどの非構造化データの保存に最適です。オブジェクトのサイズは数KBから最大5TBまで。

NGINX

NGINXはすべてのHTTPリクエストに対してIngressポートを持ち、GitLab内の適切なサブシステムにルーティングします。私たちは、人気のあるオープンソースのウェブサーバの修正されていないバージョンをバンドルしています。

ノードエクスポーター

Node ExporterはPrometheusのツールで、基盤となるマシンのメトリクス(CPU/ディスク/負荷など)を提供してくれます。Prometheusプロジェクトが提供する一般的なオープンソースのパッケージ版です。

パトロニ

PgBouncer

PostgreSQL 用の軽量なコネクションプーラー。

PgBouncer エクスポーター

PgBouncer用のPrometheusエクスポート。9127/metricsでメトリクスをエクスポート。

PostgreSQL

GitLabはアプリケーションのメタデータやユーザー情報を保存するために人気のデータベースをパッケージ化しています。

PostgreSQL エクスポーター

postgres_exporter はコミュニティが提供するPrometheus Exporterで、PostgreSQLに関するデータをGrafanaダッシュボードで使用するためにPrometheusに配信します。

Prometheus

Prometheusは、GitLab管理者がGitLabサービスを提供するために使用される個々のプロセスに関するメトリクスを公開するための時系列ツールです。

Redis

Redisは保存場所を提供するためにパッケージ化されています:

  • セッションデータ
  • 一時キャッシュ情報
  • バックグラウンドジョブキュー

GitLabがRedisをどのように使うかについては、Redisガイドラインをご覧ください。

Redis エクスポーター

Redis Exporterは、Redisプロセスに関する特定のメトリクスをPrometheusに提供し、Grafanaでこれらのメトリクスをグラフ化できるように設計されています。

レジストリ

レジストリはユーザーが自分のDockerイメージを保存するために使うものです。バンドルされているレジストリでは、NGINXをロードバランサとして、GitLabを認証マネージャとして使っています。クライアントがレジストリからイメージのプルやプッシュをリクエストすると、401 レスポンスと認証トークンの取得先(この場合は GitLab インスタンス)を示すヘッダが返されます。そしてクライアントは GitLab に pull や push の認証トークンをリクエストし、レジストリへのリクエストを再試行します。詳しくはトークン認証を参照ください。

外部のレジストリも GitLab を認証エンドポイントとして使うように設定できます。

セントリー

Sentry fundamentallyは、クラッシュをリアルタイムで監視・修正するためのサービスです。サーバーはPythonで作られていますが、あらゆる言語、あらゆるアプリケーションからイベントを送信するための完全なAPIがコンテナとして含まれています。

デプロイされたアプリの監視については、Sentryインテグレーションドキュメントを参照してください。

Sidekiq

SidekiqはRedisのキューからジョブを取り出して処理するRubyのバックグラウンドジョブプロセッサです。バックグラウンドジョブによって、GitLabは作業をバックグラウンドに移すことで、より速いリクエスト/レスポンスサイクルを提供することができます。

Puma

GitLab 13.0から、Pumaがデフォルトのウェブサーバーになりました。

PumaはRubyアプリケーションサーバーで、GitLabのユーザー向け機能を提供するRailsアプリケーションのコアを実行するために使われます。GitLabのバージョンによってbundleconfig.ru

LDAP認証

送信メール

受信メール

リクエストタイプ別 GitLab

GitLabは、エンドユーザーがサービスにアクセスするための2つの「インターフェース」を提供しています:

  • ウェブHTTPリクエスト(UI/APIの表示)
  • Git HTTP/SSH リクエスト (Git データのプッシュ/プル)

この違いを理解することが重要です。あるプロセスは両方で使われ、またあるプロセスは特定のリクエストタイプに限定されます。

GitLab Web HTTPリクエストサイクル

HTTP エンドポイント(/users/sign_in を考えてください)にリクエストをするとき、リクエストは GitLab サービスを通して次のような経路をたどります:

  • NGINX - 第一線のリバースプロキシとして機能します。
  • GitLab Workhorse - GitLab WorkhorseはRailsアプリケーションにアクセスする必要があるか、Pumaの負荷を減らすために他の場所にアクセスする必要があるかを判断します。
  • Puma - これはWebリクエストであり、アプリケーションにアクセスする必要があるので、Pumaにルーティングします。
  • PostgreSQL/Gitaly/Redis - リクエストのタイプによって、データを保存または取得するためにこれらのサービスをヒットするかもしれません。

GitLab Gitリクエストサイクル

以下では、HTTP と SSH の Git リクエストの経路の違いについて説明します。ウェブリクエストサイクルと重なる部分もありますが、異なる部分もあります。

ウェブリクエスト (80/443)

HTTP上でのGitオペレーションは、Gitドキュメントで説明されているステートレスな “smart “プロトコルを使いますが、これらのオペレーションを扱う責任はGitLabのいくつかのコンポーネントに分かれています。

以下はgit fetch のシーケンス図です。すべてのリクエストは、NGINXや他のHTTPロードバランサーを通過しますが、それによって変換されることはないことに注意してください。すべてのパスは/namespace/project.git URL からの相対パスです。

sequenceDiagram participant Git on client participant NGINX participant Workhorse participant Rails participant Gitaly participant Git on server Note left of Git on client: git fetch<br/>info-refs Git on client->>+Workhorse: GET /info/refs?service=git-upload-pack Workhorse->>+Rails: GET /info/refs?service=git-upload-pack Note right of Rails: Auth check Rails-->>-Workhorse: Gitlab::Workhorse.git_http_ok Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack request Gitaly->>+Git on server: git upload-pack --stateless-rpc --advertise-refs Git on server-->>-Gitaly: git upload-pack response Gitaly-->>-Workhorse: SmartHTTPService.InfoRefsUploadPack response Workhorse-->>-Git on client: 200 OK Note left of Git on client: git fetch<br/>fetch-pack Git on client->>+Workhorse: POST /git-upload-pack Workhorse->>+Rails: POST /git-upload-pack Note right of Rails: Auth check Rails-->>-Workhorse: Gitlab::Workhorse.git_http_ok Workhorse->>+Gitaly: SmartHTTPService.PostUploadPack request Gitaly->>+Git on server: git upload-pack --stateless-rpc Git on server-->>-Gitaly: git upload-pack response Gitaly-->>-Workhorse: SmartHTTPService.PostUploadPack response Workhorse-->>-Git on client: 200 OK

git-upload-pack の代わりにgit-receive-pack が使われる以外は、git push でもシーケンスは同様です。

SSHリクエスト (22)

SSH上でのGitオペレーションは、Gitドキュメントで説明されているステートフルなプロトコルを使うことができますが、その処理の責任はいくつかのGitLabコンポーネントに分かれています。

GitLabのどのコンポーネントもSSHを直接話しません。すべてのSSH接続は、クライアントマシンのGitとSSHサーバーの間で行われ、SSHサーバーが接続を終了します。SSHサーバーに対して、すべての接続はgit ユーザーとして認証されます。GitLabユーザーはクライアントから提示されたSSHキーによって区別されます。

以下は、高速SSHキー検索が有効になっていると仮定した場合の、git fetch のシーケンス図です。AuthorizedKeysCommandGitLab Shellが提供する実行ファイルです:

sequenceDiagram participant Git on client participant SSH server participant AuthorizedKeysCommand participant GitLab Shell participant Rails participant Gitaly participant Git on server Note left of Git on client: git fetch Git on client->>+SSH server: ssh git fetch-pack request SSH server->>+AuthorizedKeysCommand: gitlab-shell-authorized-keys-check git AAAA... AuthorizedKeysCommand->>+Rails: GET /internal/api/authorized_keys?key=AAAA... Note right of Rails: Lookup key ID Rails-->>-AuthorizedKeysCommand: 200 OK, command="gitlab-shell upload-pack key_id=1" AuthorizedKeysCommand-->>-SSH server: command="gitlab-shell upload-pack key_id=1" SSH server->>+GitLab Shell: gitlab-shell upload-pack key_id=1 GitLab Shell->>+Rails: GET /internal/api/allowed?action=upload_pack&key_id=1 Note right of Rails: Auth check Rails-->>-GitLab Shell: 200 OK, { gitaly: ... } GitLab Shell->>+Gitaly: SSHService.SSHUploadPack request Gitaly->>+Git on server: git upload-pack request Note over Git on client,Git on server: Bidirectional communication between Git client and server Git on server-->>-Gitaly: git upload-pack response Gitaly -->>-GitLab Shell: SSHService.SSHUploadPack response GitLab Shell-->>-SSH server: gitlab-shell upload-pack response SSH server-->>-Git on client: ssh git fetch-pack response

git push のオペレーションもよく似ていますが、git upload-pack の代わりにgit receive-pack を使う点が異なります。

SSHキーの高速検索が有効になっていない場合、SSHサーバーは~git/.ssh/authorized_keys ファイルを読み込んで、指定されたSSHセッションで実行するコマンドを決定します。これはRailsのAuthorizedKeysWorker 、ユーザーによってSSHキーが変更されるたびに実行されるようにスケジュールされています。

SSHキーの代わりにSSH証明書を使うこともできます。この場合、AuthorizedKeysCommandAuthorizedPrincipalsCommand に置き換えられます。これはRails内部APIを使わずに証明書からユーザ名を抽出するもので、後の/api/internal/allowed 呼び出しでkey_id の代わりに使われます。

GitLab Shellには、二要素認証コードのリセットなど、Gitalyを使わないオペレーションもいくつかあります。Rails が内部 API呼び出しの一部としてアクションを実行し、GitLab Shell がレスポンスを直接ユーザーにストリーミングします。

システムレイアウト

写真の中で~git とあるのは、Gitユーザーのホームディレクトリのことで、通常は/home/git です。

GitLabは主に/home/gitgit ユーザーとしてホームディレクトリ内にインストールされます。ホームディレクトリ内には、GitLabサーバーソフトウェアとリポジトリがあります(ただし、リポジトリの場所は設定可能です)。

素のリポジトリは/home/git/repositories にあります。GitLabはRuby on railsアプリケーションなので、内部の仕組みはRuby on railsアプリケーションがどのように動くかを勉強することで学ぶことができます。

SSH 経由でリポジトリを提供するために、GitLab Shell というアドオンアプリケーションがあり、これは/home/git/gitlab-shell にインストールされています。

インストールフォルダの概要

git ユーザーのホームディレクトリ](../install/installation.md#gitlab-directory-structure)の[ディレクトリ構造をまとめます。

プロセス

ps aux | grep '^git'

GitLabのオペレーションにはいくつかのコンポーネントがあります。永続データベース(PostgreSQL)とRedisデータベースを必要とし、Apachehttpd または NGINXからproxypass Pumaを使用します。これらのコンポーネントはすべて、GitLabとは異なるシステムユーザーとして実行する必要があります(例えば、gitの代わりに、postgresrediswww-data)。

git ユーザーとして、Sidekiq と Puma(デフォルトではポート8080 で動作するシンプルな Ruby HTTP サーバー)を起動します。GitLabユーザーの下では、通常4つのプロセスがあります:puma master (1プロセス),puma cluster worker (2プロセス),sidekiq (1プロセス)。

リポジトリへのアクセス

リポジトリにはHTTPまたはSSHでアクセスします。HTTP cloning/push/pullはGitLab APIを使用し、SSH cloningはGitLab Shell(以前に説明済み)で処理されます。

トラブルシューティング

詳しくはREADMEをご覧ください。

サービスの初期スクリプト

GitLab initスクリプトはPumaとSidekiqの起動と停止を行います:

/etc/init.d/gitlab
Usage: service gitlab {start|stop|restart|reload|status}

Redis(キーバリューストア/非永続データベース):

/etc/init.d/redis
Usage: /etc/init.d/redis {start|stop|status|restart|condrestart|try-restart}

SSHデーモン:

/etc/init.d/sshd
Usage: /etc/init.d/sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status}

ウェブサーバー(以下のいずれか):

/etc/init.d/httpd
Usage: httpd {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}

$ /etc/init.d/nginx
Usage: nginx {start|stop|restart|reload|force-reload|status|configtest}

永続データベース:

$ /etc/init.d/postgresql
Usage: /etc/init.d/postgresql {start|stop|restart|reload|force-reload|status} [version ..]

サービスのログロケーション

GitLab (PumaとSidekiqのログを含む):

  • /home/git/gitlab/log/ 通常、application.log,production.log,sidekiq.log,puma.stdout.log,git_json.log andpuma.stderr.logを含みます。

GitLab Shell:

  • /home/git/gitlab-shell/gitlab-shell.log

SSH:

  • /var/log/auth.log 認証ログ(Ubuntu)。
  • /var/log/secure auth ログ (RHEL).

NGINX:

  • /var/log/nginx/ にはエラーログとアクセスログが含まれます。

Apachehttpd

  • Apacheのログの説明
  • /var/log/apache2/ はエラーログと出力ログを含んでいます (Ubuntu の場合)。
  • /var/log/httpd/ エラーログと出力ログが含まれます(RHELの場合)。

Redis:

  • /var/log/redis/redis.log にもログローテートされたログがあります。

PostgreSQL:

  • /var/log/postgresql/*

GitLab固有の設定ファイル

GitLabの設定ファイルは/home/git/gitlab/config/* にあります。よく参照される設定ファイルには次のようなものがあります:

  • gitlab.yml:GitLab Railsの設定
  • puma.rb:Pumaウェブサーバの設定
  • database.yml:データベース接続設定

GitLab Shell には/home/git/gitlab-shell/config.yml に設定ファイルがあります。

GitLab Rails に新しい設定を追加する方法

gitlab.yml に属する設定には、次のようなものがあります:

  • 複数のサービスにまたがるアプリケーションの配線方法。例えば、Gitalyアドレス、Redisアドレス、Postgresアドレス、Consulアドレスなどです。
  • 分散トレースの設定と、いくつかの観測可能性の設定。例えば、ヒストグラムのバケット境界。
  • Railsの初期化時、場合によってはPostgres接続が確立する前に設定が必要なもの。

その他の多くの設定は、アプリ自体のApplicationSetting に配置した方がよいでしょう。UIで設定を管理する方が、設定ファイルを管理するよりもユーザーエクスペリエンスが向上します。開発コストに関しては、gitlab.yml を変更する方が高速に反復できるように思われがちですが、以下のすべてのデプロイ方法を考慮すると、トレードオフとしては不十分かもしれません。

gitlab.ymlに設定を追加する場合:

  1. Omnibusにも追加されていることを確認してください。
  2. 必要であれば、Chartにも追加されていることを確認してください。
  3. GDKにも追加されていることを確認してください。

メンテナンス作業

GitLabはバージョン情報を見たり、設定がアプリケーション内で適切に設定されているか素早くチェックするためのRakeタスクを提供しています。メンテナンスRakeタスクを参照してください。簡単に言うと、次のようにします:

sudo -i -u git
cd gitlab
bundle exec rake gitlab:env:info RAILS_ENV=production
bundle exec rake gitlab:check RAILS_ENV=production

sudo -i -u git またはsudo su - gitを使ってgit ユーザーにサインインすることをお勧めします。 GitLab が提供するsudo コマンドは Ubuntu では動作しますが、RHEL では必ずしも動作するとは限りません。

GitLab.com

GitLab.comのアーキテクチャはリファレンスのために詳しく説明されていますが、このアーキテクチャが役に立つのは何百万人ものユーザーがいる場合だけです。

AIアーキテクチャ

SaaSモデルのゲートウェイを利用することで、AIを活用した機能を実現できます。