Gitalyを設定する
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
Gitalyを設定する方法は2つあります:
/etc/gitlab/gitlab.rbを編集して、Gitalyの設定を追加または変更します。Gitaly設定ファイルの例を参照してください。サンプルファイルの設定は、Rubyに変換する必要があります。- ファイルを保存してGitLabを再設定します。
- Gitalyチャートを設定します。
- Helmリリースをアップグレードします。
/home/git/gitaly/config.tomlを編集して、Gitalyの設定を追加または変更します。Gitaly設定ファイルの例を参照してください。- ファイルを保存して、GitLabを再起動します。
次の設定オプションも使用できます:
- TLSサポートの有効化。
- RPC並行処理の制限。
- pack-objects並行処理の制限。
Gitalyトークンについて
Gitalyドキュメント全体で参照されているトークンは、管理者が選択した任意のパスワードにすぎません。これは、GitLab APIまたは他の同様のAPI用に作成されたトークンとは関係ありません。
Gitalyを独自のサーバーで実行する
デフォルトでは、GitalyはGitalyクライアントと同じサーバー上で実行され、前述のように構成されます。シングルサーバーインストールは、以下で使用されるこのデフォルト構成で最適に提供されます:
ただし、Gitalyは独自のサーバーにデプロイでき、複数のマシンにまたがるGitLabインストールに役立ちます。
独自のサーバー上で実行するように構成されている場合、Gitalyサーバーは、クラスター内のGitalyクライアントより前にアップグレードする必要があります。
ディスク要件は、Gitalyノードに適用されます。
独自のサーバーにGitalyをセットアップする手順は次のとおりです:
- Gitalyをインストールします。
- 認証を構成します。
- Gitalyサーバーを構成します。
- Gitalyクライアントを設定します。
- 不要なGitalyを無効にする (オプション)。
ネットワークアーキテクチャ
次のリストは、Gitalyのネットワークアーキテクチャを示しています:
- GitLab Railsは、リポジトリストレージにシャードを分割します。
/config/gitlab.ymlには、ストレージ名から(Gitaly address, Gitaly token)のペアへのマップが含まれています。/config/gitlab.ymlのstorage name->(Gitaly address, Gitaly token)マップは、Gitalyネットワークトポロジの信頼できる唯一の情報源です。(Gitaly address, Gitaly token)は、Gitalyサーバーに対応します。- Gitalyサーバーは、1つ以上のストレージをホストします。
- Gitalyクライアントは、1つ以上のGitalyサーバーを使用できます。
- Gitalyアドレスは、すべてのGitalyクライアントに対して正しく解決されるように指定する必要があります。
- Gitalyクライアントは次のとおりです:
- Puma。
- Sidekiq。
- GitLab Workhorse。
- GitLab Shell。
- Elasticsearch Indexer。
- Gitaly自体。
- Gitalyサーバーは、
/config/gitlab.ymlで指定されているように、独自の(Gitaly address, Gitaly token)ペアを使用して、自身に対してRPC呼び出しを実行できる必要があります。 - 認証は、GitalyノードとGitLab Railsノード間で共有されるスタティックトークンを介して行われます。
次の図は、HTTPおよびHTTPs通信のデフォルトポートを示すGitalyサーバーとGitLab Rails間の通信を示しています。
Gitalyのネットワークトラフィックはデフォルトで暗号化されていないため、Gitalyサーバーをパブリックインターネットに公開しないでください。Gitalyサーバーへのアクセスを制限するために、ファイアウォールの使用を強くお勧めします。別のオプションは、TLSを使用することです。
次のセクションでは、シークレットトークンabc123secretを使用して2つのGitalyサーバーを構成する方法について説明します:
gitaly1.internal。gitaly2.internal。
お客様のGitLab環境には、3つのリポジトリストレージがあることを前提としています:
default。storage1。storage2。
必要に応じて、1つのリポジトリストレージを備えたサーバーを少数使用できます。
Gitalyをインストールする
次のいずれかを使用して、各GitalyサーバーにGitalyをインストールします:
- Linuxパッケージインストールの必要なLinuxパッケージをダウンロードしてインストールしますが、
EXTERNAL_URL=値は指定しないでください。 - セルフコンパイルインストール。Gitalyをインストールする手順に従います。
Gitalyサーバーを構成する
Gitalyサーバーを構成するには、次の操作を行う必要があります:
- 認証を構成します。
- リポジトリストレージのパスを構成します。
- ネットワークリスナーを有効にします。
gitユーザーは、構成されたストレージパスに対する読み取り、書き込み、および権限の設定を実行できる必要があります。
Gitalyトークンのローテーション中にダウンタイムが発生しないように、gitaly['auth_transitioning']設定を使用して、一時的に認証を無効にすることができます。詳細については、認証移行モードの有効化を参照してください。
認証を構成する
GitalyとGitLabは、認証に2つの共有シークレットを使用します:
- Gitalyトークン: GitalyへのgRPCリクエストを認証するために使用されます。
- GitLab Shellトークン: GitLab ShellからGitLab内部APIへの認証コールバックに使用されます。
_Gitalyトークン_を構成するには、
/etc/gitlab/gitlab.rbを編集します:gitaly['configuration'] = { # ... auth: { # ... token: 'abc123secret', }, }_GitLab Shellトークン_を構成するには、次の2つの方法があります:
方法1(推奨: ): GitalyクライアントからGitalyサーバーおよびその他のGitalyクライアント上の同じパスに
/etc/gitlab/gitlab-secrets.jsonをコピーします。方法2:
GitLab Railsを実行しているすべてのノードで、
/etc/gitlab/gitlab.rbを編集します。GITLAB_SHELL_SECRET_TOKENを実際のシークレットに置き換えます:GitLab 17.5以降:
gitaly['gitlab_secret'] = 'GITLAB_SHELL_SECRET_TOKEN'GitLab 17.4以前:
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
Gitalyを実行しているすべてのノードで、
/etc/gitlab/gitlab.rbを編集します。GITLAB_SHELL_SECRET_TOKENを実際のシークレットに置き換えます:GitLab 17.5以降:
gitaly['gitlab_secret'] = 'GITLAB_SHELL_SECRET_TOKEN'GitLab 17.4以前:
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
これらの変更後、GitLabを再構成します:
sudo gitlab-ctl reconfigure
GitalyクライアントからGitalyサーバー(およびその他のGitalyクライアント)上の同じパスに
/home/git/gitlab/.gitlab_shell_secretをコピーします。Gitalyクライアントで、
/home/git/gitlab/config/gitlab.ymlを編集します:gitlab: gitaly: token: 'abc123secret'ファイルを保存して、GitLabを再起動します。
Gitalyサーバーで、
/home/git/gitaly/config.tomlを編集します:[auth] token = 'abc123secret'ファイルを保存して、GitLabを再起動します。
Gitalyサーバーを構成する
Gitalyサーバーを構成します。
/etc/gitlab/gitlab.rbを編集します:# Avoid running unnecessary services on the Gitaly server postgresql['enable'] = false redis['enable'] = false nginx['enable'] = false puma['enable'] = false sidekiq['enable'] = false gitlab_workhorse['enable'] = false gitlab_exporter['enable'] = false gitlab_kas['enable'] = false # If you run a separate monitoring node you can disable these services prometheus['enable'] = false alertmanager['enable'] = false # If you don't run a separate monitoring node you can # enable Prometheus access & disable these extra services. # This makes Prometheus listen on all interfaces. You must use firewalls to restrict access to this address/port. # prometheus['listen_address'] = '0.0.0.0:9090' # prometheus['monitor_kubernetes'] = false # If you don't want to run monitoring services uncomment the following (not recommended) # node_exporter['enable'] = false # Prevent database connections during 'gitlab-ctl reconfigure' gitlab_rails['auto_migrate'] = false # Configure the gitlab-shell API callback URL. Without this, `git push` will # fail. This can be your 'front door' GitLab URL or an internal load # balancer. # Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from Gitaly client to Gitaly server. gitlab_rails['internal_api_url'] = 'https://gitlab.example.com' gitaly['configuration'] = { # ... # # Make Gitaly accept connections on all network interfaces. You must use # firewalls to restrict access to this address/port. # Comment out following line if you only want to support TLS connections listen_addr: '0.0.0.0:8075', auth: { # ... # # Authentication token to ensure only authorized servers can communicate with # Gitaly server token: 'AUTH_TOKEN', }, }それぞれのGitalyサーバーについて、次の内容を
/etc/gitlab/gitlab.rbに追加します:gitaly1.internalの場合:gitaly['configuration'] = { # ... storage: [ { name: 'default', path: '/var/opt/gitlab/git-data/repositories', }, { name: 'storage1', path: '/mnt/gitlab/git-data/repositories', }, ], }gitaly2.internalの場合:gitaly['configuration'] = { # ... storage: [ { name: 'storage2', path: '/srv/gitlab/git-data/repositories', }, ], }ファイルを保存してGitLabを再設定します。
GitalyがGitLab内部APIにコールバックを実行できることを確認します:
sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
/home/git/gitaly/config.tomlを編集します:listen_addr = '0.0.0.0:8075' runtime_dir = '/var/opt/gitlab/gitaly' [logging] format = 'json' level = 'info' dir = '/var/log/gitaly'それぞれのGitalyサーバーについて、次の内容を
/home/git/gitaly/config.tomlに追加します:gitaly1.internalの場合:[[storage]] name = 'default' path = '/var/opt/gitlab/git-data/repositories' [[storage]] name = 'storage1' path = '/mnt/gitlab/git-data/repositories'gitaly2.internalの場合:[[storage]] name = 'storage2' path = '/srv/gitlab/git-data/repositories'/home/git/gitlab-shell/config.ymlを編集します:gitlab_url: https://gitlab.example.comファイルを保存して、GitLabを再起動します。
GitalyがGitLab内部APIにコールバックを実行できることを確認します:
sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
GitLabサーバーからGitalyにリポジトリデータを直接コピーする場合は、メタデータファイル(デフォルトパス/var/opt/gitlab/git-data/repositories/.gitaly-metadata)が転送に含まれていないことを確認してください。このファイルをコピーすると、GitLabがGitalyサーバーでホストされているリポジトリへの直接ディスクアクセスを使用するようになり、Error creating pipelineおよびCommit not foundエラー、または古いデータが発生します。
Gitalyクライアントを設定します
最後の手順として、Gitalyクライアントを更新して、ローカルのGitalyサービスの使用から、構成したばかりのGitalyサーバーを使用するように切り替える必要があります。
GitLabでは、defaultリポジトリストレージを構成する必要があります。この制限の詳細をご覧ください。
GitalyクライアントがGitalyサーバーにアクセスできなくなるようなことがあれば、すべてのGitalyリクエストが失敗するため、これは危険な場合があります。たとえば、ネットワーク、ファイアウォール、または名前解決の問題などです。
Gitalyは次のことを前提としています:
gitaly1.internalGitalyサーバーには、Gitalyクライアントからgitaly1.internal:8075でアクセスでき、そのGitalyサーバーは/var/opt/gitlab/git-dataと/mnt/gitlab/git-dataの読み取り、書き込み、および権限の設定を実行できます。gitaly2.internalGitalyサーバーには、Gitalyクライアントからgitaly2.internal:8075でアクセスでき、そのGitalyサーバーは/srv/gitlab/git-dataの読み取り、書き込み、および権限の設定を実行できます。gitaly1.internalおよびgitaly2.internalGitalyサーバーは、相互にアクセスできます。
混合構成を使用しない限り、一部をローカルGitalyサーバー(gitaly_addressなし)として、一部をリモートサーバー(gitaly_addressあり)としてGitalyサーバーを定義することはできません。
次の2つの方法のいずれかでGitalyクライアントを構成します。これらの手順は暗号化されていない接続用ですが、TLSサポートを有効にすることもできます:
/etc/gitlab/gitlab.rbを編集します:# Use the same token value configured on all Gitaly servers gitlab_rails['gitaly_token'] = '<AUTH_TOKEN>' gitlab_rails['repositories_storages'] = { 'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' }, 'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' }, 'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' }, }または、各Gitalyサーバーが異なる認証トークンを使用するように構成されている場合:
gitlab_rails['repositories_storages'] = { 'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075', 'gitaly_token' => '<AUTH_TOKEN_1>' }, 'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075', 'gitaly_token' => '<AUTH_TOKEN_1>' }, 'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075', 'gitaly_token' => '<AUTH_TOKEN_2>' }, }ファイルを保存してGitLabを再設定します。
Gitalyクライアント(たとえば、Railsアプリケーション)で
sudo gitlab-rake gitlab:gitaly:checkを実行して、Gitalyサーバーに接続できることを確認します。ログを追跡してリクエストを確認します:
sudo gitlab-ctl tail gitaly
/home/git/gitlab/config/gitlab.ymlを編集します:gitlab: repositories: storages: default: gitaly_address: tcp://gitaly1.internal:8075 gitaly_token: AUTH_TOKEN_1 storage1: gitaly_address: tcp://gitaly1.internal:8075 gitaly_token: AUTH_TOKEN_1 storage2: gitaly_address: tcp://gitaly2.internal:8075 gitaly_token: AUTH_TOKEN_2ファイルを保存して、GitLabを再起動します。
sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=productionを実行して、GitalyクライアントがGitalyサーバーに接続できることを確認します。ログを追跡してリクエストを確認します:
tail -f /home/git/gitlab/log/gitaly.log
GitalyサーバーのGitalyログをプルすると、リクエストが届いていることがわかります。Gitalyリクエストをトリガーする確実な方法の1つは、HTTPまたはHTTPS経由でGitLabからリポジトリをクローンすることです。
サーバーフックを構成している場合、リポジトリごとまたはグローバルに、これらをGitalyサーバーに移動する必要があります。複数のGitalyサーバーがある場合は、サーバーフックをすべてのGitalyサーバーにコピーします。
混合構成
GitLabは、多くのGitalyサーバーの1つと同じサーバー上に存在できますが、ローカル構成とリモート構成を混在させる構成はサポートされていません。次の設定は正しくありません。理由:
- すべてのアドレスは、他のGitalyサーバーから到達できる必要があります。
storage1には、一部のGitalyサーバーに対して無効なgitaly_addressのUnixソケットが割り当てられています。
gitlab_rails['repositories_storages'] = {
'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
'storage1' => { 'gitaly_address' => 'unix:/var/opt/gitlab/gitaly/gitaly.socket' },
'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
}ローカルGitalyサーバーとリモートGitalyサーバーを組み合わせるには、ローカルGitalyサーバーに外部アドレスを使用します。例:
gitlab_rails['repositories_storages'] = {
'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
# Address of the GitLab server that also has Gitaly running on it
'storage1' => { 'gitaly_address' => 'tcp://gitlab.internal:8075' },
'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
}
gitaly['configuration'] = {
# ...
#
# Make Gitaly accept connections on all network interfaces
listen_addr: '0.0.0.0:8075',
# Or for TLS
tls_listen_addr: '0.0.0.0:9999',
tls: {
certificate_path: '/etc/gitlab/ssl/cert.pem',
key_path: '/etc/gitlab/ssl/key.pem',
},
storage: [
{
name: 'storage1',
path: '/mnt/gitlab/git-data/repositories',
},
],
}pathは、ローカルGitalyサーバー上のストレージシャードに対してのみ含めることができます。除外した場合、そのストレージシャードにはデフォルトのGitストレージディレクトリが使用されます。
GitLabにはデフォルトのリポジトリストレージが必要です
Gitalyサーバーを環境に追加する場合、元のdefault Gitalyサービスを置き換えることができます。ただし、GitLabではdefaultというストレージが必要なため、defaultストレージを削除するようにGitLabアプリケーションサーバーを再構成することはできません。この制限事項の詳細についてをご覧ください。
制限を回避するには:
- 新しいGitalyサービス上に追加のストレージ場所を定義し、その追加のストレージが
defaultになるように構成します。ストレージの場所には、動作中のストレージを想定するデータベース移行の問題を回避するために、Gitalyサービスが実行されていて、利用可能である必要があります。 - 管理者エリアで、
defaultをゼロのウェイトに設定して、リポジトリがそこに格納されないようにします。
不要なGitalyを無効にする(オプション)
Gitalyをリモートサービスとして実行する場合は、デフォルトでGitLabサーバー上で実行されるローカルGitalyサービスを無効にすることを検討し、必要な場合にのみ実行します。
GitalyをGitLabインスタンス上で無効にすることは、GitalyがGitLabインスタンスとは別のマシン上で実行されるカスタムクラスター構成でGitLabを実行する場合にのみ意味があります。クラスター内のすべてのマシンでGitalyを無効にすることは、有効な構成ではありません(一部のマシンはGitalyサーバーとして動作する必要があります)。
次の2つの方法のいずれかで、GitLabサーバー上のGitalyを無効にします:
/etc/gitlab/gitlab.rbを編集します:gitaly['enable'] = falseファイルを保存してGitLabを再設定します。
/etc/default/gitlabを編集します:gitaly_enabled=falseファイルを保存して、GitLabを再起動します。
Gitalyリスナーインターフェースを変更する
Gitalyがリッスンするインターフェースを変更できます。Gitalyと通信する必要のある外部サービスがある場合は、リスナーインターフェースを変更することがあります。たとえば、完全一致コードの検索が有効になっているが、実際のサービスが別のサーバーで実行されている場合にZoektを使用する完全一致コードの検索などです。
gitaly_tokenは、gitaly_tokenがGitalyサービスとの認証に使用されるため、シークレット文字列である必要があります。このシークレットは、ランダムな32文字の文字列を生成するためにopenssl rand -base64 24で生成できます。
たとえば、Gitalyリスナーインターフェースを0.0.0.0:8075に変更するには:
# /etc/gitlab/gitlab.rb
# Add a shared token for Gitaly authentication
gitlab_shell['secret_token'] = 'your_secure_token_here'
gitlab_rails['gitaly_token'] = 'your_secure_token_here'
# Gitaly configuration
gitaly['gitlab_secret'] = 'your_secure_token_here'
gitaly['configuration'] = {
listen_addr: '0.0.0.0:8075',
auth: {
token: 'your_secure_token_here',
},
storage: [
{
name: 'default',
path: '/var/opt/gitlab/git-data/repositories',
},
]
}
# Tell Rails where to find Gitaly
gitlab_rails['repositories_storages'] = {
'default' => { 'gitaly_address' => 'tcp://ip_address_here:8075' },
}
# Internal API URL (important for multi-server setups)
gitlab_rails['internal_api_url'] = 'http://ip_address_here'コントロールグループ
コントロールグループの詳細については、Cgroupsを参照してください。
バックグラウンドリポジトリの最適化
Gitリポジトリのオブジェクトデータベースにデータが格納される方法は、時間の経過とともに非効率になる可能性があり、Git操作が遅くなります。これらのアイテムをクリーンアップしてパフォーマンスを向上させるために、最大期間で毎日のバックグラウンドタスクを実行するようにGitalyをスケジュールできます。
バックグラウンドリポジトリの最適化は、実行中にホストに大きな負荷をかける可能性があります。ピーク時以外の時間にスケジュールし、期間を短く(たとえば、30〜60分)してください。
次の2つの方法のいずれかで、バックグラウンドリポジトリの最適化を構成します:
/etc/gitlab/gitlab.rbを編集して、以下を追加します:
gitaly['configuration'] = {
# ...
daily_maintenance: {
# ...
start_hour: 4,
start_minute: 30,
duration: '30m',
storages: ['default'],
},
}/home/git/gitaly/config.tomlを編集して、以下を追加します:
[daily_maintenance]
start_hour = 4
start_minute = 30
duration = '30m'
storages = ["default"]Gitaly認証トークンをローテーションする
本番環境で認証情報をローテーションすると、ダウンタイムが必要になったり、停止が発生したりすることがよくあります。
ただし、サービスを中断することなく、Gitaly認証情報をローテーションできます。Gitaly認証トークンのローテーションには、次のものがあります:
この手順は、単一サーバー上でGitLabを実行している場合にも機能します。その場合、GitalyサーバーとGitalyクライアントは同じマシンを参照します。
認証モニタリングを検証する
Gitaly認証トークンをローテーションする前に、Prometheusを使用してGitLabインストールの認証動作をモニタリングできることを確認してください。
その後、手順の残りを続行できます。
認証移行モードを有効にする
次の手順に従って、Gitalyサーバーを認証移行モードにすることで、GitalyサーバーでのGitaly認証を一時的に無効にします:
# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
# ...
auth: {
# ...
transitioning: true,
},
}この変更を加えた後、Prometheusクエリは次のようなものを返すはずです:
{enforced="false",status="would be ok"} 4424.985419441742enforced="false"のため、新しいトークンのロールアウトを開始しても安全です。
Gitaly認証トークンを更新する
新しいGitaly認証トークンに更新するには、各GitalyクライアントおよびGitalyサーバーで次の手順を実行します:
設定を更新します:
# in /etc/gitlab/gitlab.rb gitaly['configuration'] = { # ... auth: { # ... token: '<new secret token>', }, }Gitalyを再起動します:
gitlab-ctl restart gitaly
この変更のロールアウト中にPrometheusクエリを実行すると、enforced="false",status="denied"カウンターにゼロ以外の値が表示されます。
認証の失敗がないことを確認する
新しいトークンが設定され、関係するすべてのサービスが再起動された後、次のものが一時的に表示されます:
status="would be ok"。status="denied"。
新しいトークンがすべてのGitalyクライアントとGitalyサーバーによってプルされた後、ゼロ以外のレートはenforced="false",status="would be ok"のみになります。
認証移行モードを無効にする
Gitaly認証を再度有効にするには、認証移行モードを無効にします。次の手順に従って、Gitalyサーバーで構成を更新します:
# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
# ...
auth: {
# ...
transitioning: false,
},
}この手順を完了しないと、Gitaly認証は行われません。
認証が適用されていることを確認する
Prometheusクエリを更新します。これで、開始時と同じような結果が表示されるはずです。例:
{enforced="true",status="ok"} 4424.985419441742enforced="true"は、認証が適用されていることを意味します。
Pack-objectsキャッシュ
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
Gitaly(Gitリポジトリのストレージを提供するサービス)は、Gitフェッチ応答の短いローリングウィンドウをキャッシュするように構成できます。これにより、サーバーが大量のCIフェッチトラフィックを受信した場合に、サーバーの負荷を軽減できます。
パックオブジェクトのキャッシュは、Gitの内部的な部分であるgit pack-objectsをラップし、PostUploadPackおよびSSHUploadPack Gitaly RPCを使用して間接的に呼び出されます。ユーザーがHTTPを使用してGitフェッチを実行すると、GitalyはPostUploadPackを実行し、ユーザーがSSHを使用してGitフェッチを実行すると、SSHUploadPackを実行します。キャッシュが有効になっている場合、PostUploadPackまたはSSHUploadPackを使用するものはすべて、そのメリットをプルできます。以下とは無関係で、影響を受けません:
- トランスポート(HTTPまたはSSH)。
- Gitプロトコルバージョン(v0またはv2)。
- フルクローン、増分フェッチ、シャロークローン、または部分クローンなどのフェッチのタイプ。
このキャッシュの強みは、同時実行される同一のフェッチを重複排除できることです。それは:
- ユーザーが多数の同時ジョブでCI/CDパイプラインを実行するGitLabインスタンスに役立ちます。サーバーのCPU使用率が大幅に低下するはずです。
- まったく独自のフェッチにはメリットがありません。たとえば、リポジトリをローカルコンピューターにクローンしてスポットチェックを実行する場合、フェッチはおそらく一意であるため、このキャッシュからメリットが得られる可能性は低いです。
パックオブジェクトのキャッシュはローカルキャッシュです。それは:
- 有効になっているGitalyプロセスのメモリにメタデータを格納します。
- ローカルストレージ上のファイルにキャッシュしている実際のGitデータを格納します。
ローカルファイルを使用すると、オペレーティングシステムがパックオブジェクトのキャッシュファイルの一部をRAMに自動的に保持し、高速化できるというメリットがあります。
パックオブジェクトのキャッシュにより、ディスク書き込みIOが大幅に増加する可能性があるため、デフォルトではオフになっています。
設定を構成
これらの構成設定は、パックオブジェクトのキャッシュで使用できます。各設定については、以下で詳しく説明します。
| 設定 | デフォルト | 説明 |
|---|---|---|
enabled | false | キャッシュをオンにします。オフの場合、Gitalyはリクエストごとに専用のgit pack-objectsプロセスを実行します。 |
dir | <PATH TO FIRST STORAGE>/+gitaly/PackObjectsCache | キャッシュファイルを格納するローカルディレクトリ。 |
max_age | 5m(5分) | これより古いエントリは削除され、ディスクから削除されます。 |
min_occurrences | 1 | キャッシュエントリが作成される前に、キーが発生する必要がある最小回数。 |
/etc/gitlab/gitlab.rbで、次のように設定します:
gitaly['configuration'] = {
# ...
pack_objects_cache: {
enabled: true,
# The default settings for "dir", "max_age" and "min_occurences" should be fine.
# If you want to customize these, see details below.
},
}enabledのデフォルトはfalse
キャッシュは、極端な増加を招く場合があるため、デフォルトで無効になっています。GitLab.comでは、リポジトリストレージディスクがこの追加のワークロードを処理できることを確認していますが、どこでもこれが当てはまるとは限りません。
キャッシュストレージディレクトリdir
キャッシュには、ファイルを格納するためのディレクトリが必要です。このディレクトリは次のようになります:
- 十分なスペースのあるファイルシステム内。キャッシュファイルシステムのスペースがなくなると、すべてのフェッチが失敗し始めます。
- 十分なIO帯域幅を持つディスク上。キャッシュディスクのIO帯域幅がなくなると、すべてのフェッチ、おそらくサーバー全体が遅くなります。
指定されたディレクトリ内の既存のデータはすべて削除されます。既存のデータを含むディレクトリは使用しないように注意してください。
デフォルトでは、キャッシュストレージディレクトリは、設定ファイルで定義されている最初のGitalyストレージのサブディレクトリに設定されます。
複数のGitalyプロセスで、キャッシュストレージに同じディレクトリを使用できます。各Gitalyプロセスは、作成するキャッシュファイル名の一部として、一意のランダム文字列を使用します。これは、次の意味をもちます:
- 衝突しません。
- 別のプロセスのファイルを再利用しません。
デフォルトのディレクトリは、リポジトリデータと同じファイルシステムにキャッシュファイルをパックしますが、これは要件ではありません。インフラストラクチャに適している場合は、キャッシュファイルを別のファイルシステムにパックできます。
ディスクから必要なIO帯域幅の量は、次によって異なります:
- Gitalyサーバー上のリポジトリのサイズと形状。
- ユーザーが生成するタイプのトラフィック。
キャッシュヒット率が0%であると仮定して、gitaly_pack_objects_generated_bytes_totalメトリクスを悲観的な見積もりとして使用できます。
必要なスペースの量は、次によって異なります:
- ユーザーがキャッシュからプルする1秒あたりのバイト数。
max_ageキャッシュ削除ウィンドウのサイズ。
ユーザーが100 MB/秒をプルし、5分のウィンドウを使用すると、平均して5*60*100 MB = 30 GBのデータがキャッシュディレクトリにパックされます。この平均は、保証ではなく、予想される平均です。ピークサイズがこの平均を超える場合があります。
キャッシュ削除ウィンドウmax_age
max_age構成設定を使用すると、キャッシュヒットの可能性と、キャッシュファイルで使用されるストレージの平均量を制御できます。max_ageより古いエントリはディスクから削除されます。
削除は、進行中のリクエストを妨げません。Unixファイルシステムは、削除されたファイルを読み取っているすべてのプロセスがファイルを閉じるまで、ファイルを実際に削除しないため、低速接続でフェッチを実行するのにかかる時間よりもmax_ageが短くても問題ありません。
キーの発生回数min_occurrences
min_occurrences設定は、新しいキャッシュエントリを作成する前に、同一のリクエストが発生する必要がある頻度を制御します。デフォルト値は1で、一意のリクエストはキャッシュに書き込まれません。
次の場合:
- この数値を増やすと、キャッシュヒット率が低下し、キャッシュの使用ディスクスペースが少なくなります。
- この数値を減らすと、キャッシュヒット率が上がり、キャッシュの使用ディスクスペースが増えます。
min_occurrencesを1に設定する必要があります。GitLab.comでは、0から1にすると、キャッシュヒット率にほとんど影響を与えずに、キャッシュディスクスペースが50%節約されました。
キャッシュを監視する
メトリクスを使用して、および次のログに記録された情報でキャッシュを監視できます。これらのログはgRPCログの一部であり、呼び出しが実行されると検出できます。
| フィールド | 説明 |
|---|---|
pack_objects_cache.hit | 現在のパックオブジェクトのキャッシュがヒットしたかどうかを示します(trueまたはfalse)。 |
pack_objects_cache.key | パックオブジェクトのキャッシュに使用されるキーです |
pack_objects_cache.generated_bytes | 書き込まれている新しいキャッシュのサイズ(バイト単位) |
pack_objects_cache.served_bytes | 処理されているキャッシュのサイズ(バイト単位) |
pack_objects.compression_statistics | パックオブジェクトの生成に関する統計 |
pack_objects.enumerate_objects_ms | クライアントから送信されたオブジェクトの列挙に費やされた合計時間(ミリ秒単位) |
pack_objects.prepare_pack_ms | クライアントに送り返す前に、パックファイルの準備に費やされた合計時間(ミリ秒単位) |
pack_objects.write_pack_file_ms | クライアントにパックファイルを送り返すのに費やされた合計時間(ミリ秒単位)。クライアントのインターネット接続に大きく依存します |
pack_objects.written_object_count | Gitalyがクライアントに送り返すオブジェクトの合計数 |
次の場合:
- キャッシュミス、Gitalyは
pack_objects_cache.generated_bytesメッセージとpack_objects_cache.served_bytesメッセージの両方をログに記録します。Gitalyは、パックオブジェクトの生成に関するより詳細な統計もログに記録します。 - キャッシュヒット、Gitalyは
pack_objects_cache.served_bytesメッセージのみをログに記録します。
例:
{
"bytes":26186490,
"correlation_id":"01F1MY8JXC3FZN14JBG1H42G9F",
"grpc.meta.deadline_type":"none",
"grpc.method":"PackObjectsHook",
"grpc.request.fullMethod":"/gitaly.HookService/PackObjectsHook",
"grpc.request.glProjectPath":"root/gitlab-workhorse",
"grpc.request.glRepository":"project-2",
"grpc.request.repoPath":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git",
"grpc.request.repoStorage":"default",
"grpc.request.topLevelGroup":"@hashed",
"grpc.service":"gitaly.HookService",
"grpc.start_time":"2021-03-25T14:57:52.747Z",
"level":"info",
"msg":"finished unary call with code OK",
"peer.address":"@",
"pid":20961,
"span.kind":"server",
"system":"grpc",
"time":"2021-03-25T14:57:53.543Z",
"pack_objects.compression_statistics": "Total 145991 (delta 68), reused 6 (delta 2), pack-reused 145911",
"pack_objects.enumerate_objects_ms": 170,
"pack_objects.prepare_pack_ms": 7,
"pack_objects.write_pack_file_ms": 786,
"pack_objects.written_object_count": 145991,
"pack_objects_cache.generated_bytes": 49533030,
"pack_objects_cache.hit": "false",
"pack_objects_cache.key": "123456789",
"pack_objects_cache.served_bytes": 49533030,
"peer.address": "127.0.0.1",
"pid": 8813,
}cat-fileキャッシュ
多くのGitaly RPCは、リポジトリからGitオブジェクトを検索する必要があります。ほとんどの場合、git cat-file --batchプロセスを使用します。パフォーマンスを向上させるために、Gitalyはこれらのgit cat-fileプロセスをRPC呼び出し全体で再利用できます。以前に使用されたプロセスは、git cat-fileキャッシュに保持されます。システムリソースの消費量を制御するために、キャッシュにパックできるcat-fileプロセスの最大数があります。
デフォルトの制限は100 cat-fileであり、git cat-file --batchおよびgit cat-file --batch-checkプロセスのペアを構成します。“too many open files"に関するエラー、または新しいプロセスを作成できないというエラーが表示される場合は、この制限を下げたい場合があります。
理想的には、この数は標準的なトラフィックを処理するのに十分な大きさである必要があります。制限を引き上げる場合は、前後にキャッシュヒット率を測定する必要があります。ヒット率が向上しない場合、制限を高くしても意味のある違いは生じない可能性があります。ヒット率を確認するためのPrometheusクエリの例を次に示します:
sum(rate(gitaly_catfile_cache_total{type="hit"}[5m])) / sum(rate(gitaly_catfile_cache_total{type=~"(hit)|(miss)"}[5m]))Gitaly構成ファイルでcat-fileキャッシュを設定します。
GitLab UIコミットのコミット署名を構成する
GitLab Self-Managedでは、デフォルトでこの機能を利用できます。この機能を非表示にするために、管理者はgitaly_gpg_signingという名前の機能フラグを無効にできます。GitLab.comでは、この機能は利用できません。GitLab Dedicatedでは、この機能は利用できません。
デフォルトでは、GitalyはGitLab UIを使用して作成されたコミットに署名しません。たとえば、次を使用して作成されたコミット:
- Webエディタ。
- Web IDE。
- マージリクエスト。
Gitalyでコミット署名を有効にすると:
- GitLabは、UIを介して作成されたすべてのコミットに署名します。
- 署名は、作成者のIDではなく、コミッターのIDを検証します。
committer_emailとcommitter_nameを設定することで、コミットがインスタンスによってコミットされたことを反映するようにGitalyを構成できます。たとえば、GitLab.comでは、これらの構成オプションはnoreply@gitlab.comとGitLabに設定されています。
rotated_signing_keysは、検証にのみ使用するキーのリストです。Gitalyは、設定されたsigning_keyを使用してWebコミットを検証しようとし、成功するまでローテーションされたキーを1つずつ使用します。いずれかの場合、rotated_signing_keysオプションを設定します:
- 署名キーがローテーションされます。
- 他のインスタンスからプロジェクトを移行するための複数のキーを指定し、Webコミットを検証済みとして表示する場合。
GitLab UIで作成されたコミットに署名するようにGitalyを構成するには、次の2つの方法があります:
GPGキーを作成してエクスポートするか、SSHキーを作成します。最適なパフォーマンスを得るには、EdDSAキーを使用します。
エクスポートGPGキー:
gpg --export-secret-keys <ID> > signing_key.gpgまたは、(パスフレーズなしで)SSHキーを作成します:
ssh-keygen -t ed25519 -f signing_key.sshGitalyノードで、キーを
/etc/gitlab/gitaly/にコピーし、gitユーザーにファイルを読み取る権限があることを確認します。/etc/gitlab/gitlab.rbを編集し、gitaly['git']['signing_key']を構成します:gitaly['configuration'] = { # ... git: { # ... committer_name: 'Your Instance', committer_email: 'noreply@yourinstance.com', signing_key: '/etc/gitlab/gitaly/signing_key.gpg', rotated_signing_keys: ['/etc/gitlab/gitaly/previous_signing_key.gpg'], # ... }, }ファイルを保存してGitLabを再設定します。
GPGキーを作成してエクスポートするか、SSHキーを作成します。最適なパフォーマンスを得るには、EdDSAキーを使用します。
エクスポートGPGキー:
gpg --export-secret-keys <ID> > signing_key.gpgまたは、(パスフレーズなしで)SSHキーを作成します:
ssh-keygen -t ed25519 -f signing_key.sshGitalyノードで、キーを
/etc/gitlabにコピーします。/home/git/gitaly/config.tomlを編集し、signing_keyを構成します:[git] committer_name = "Your Instance" committer_email = "noreply@yourinstance.com" signing_key = "/etc/gitlab/gitaly/signing_key.gpg" rotated_signing_keys = ["/etc/gitlab/gitaly/previous_signing_key.gpg"]ファイルを保存して、GitLabを再起動します。
外部コマンドを使用して設定を生成する
外部コマンドを使用して、Gitaly構成の一部を生成できます。これは、次の場合に行うことができます:
- 各ノードに完全な構成を配布しなくても、ノードを設定するため。
- ノードの設定の自動検出を使用して構成するため。たとえば、DNSエントリを使用します。
- ノードの起動時にシークレットを設定し、プレーンテキストで表示する必要がないようにするため。
外部コマンドを使用して設定を生成するには、Gitalyノードの目的の設定をJSON形式で標準出力にダンプするスクリプトを提供する必要があります。
たとえば、次のコマンドは、AWSシークレットを使用してGitLab内部APIへの接続に使用されるHTTPパスワードを設定します:
#!/usr/bin/env ruby
require 'json'
JSON.generate({"gitlab": {"http_settings": {"password": `aws get-secret-value --secret-id ...`}}})次に、スクリプトのパスをGitalyに次の2つの方法のいずれかで認識させる必要があります:
/etc/gitlab/gitlab.rbを編集し、config_commandを構成します:
gitaly['configuration'] = {
config_command: '/path/to/config_command',
}/home/git/gitaly/config.tomlを編集し、config_commandを構成します:
config_command = "/path/to/config_command"設定後、Gitalyは起動時にコマンドを実行し、標準出力をJSONとして解析中します。結果として得られる設定は、他のGitaly構成にマージされます。
Gitalyは、次のいずれかの場合に起動に失敗します:
- 構成コマンドが失敗します。
- コマンドによって生成された出力を有効なJSONとして解析できません。
サーバー側のバックアップを構成する
リポジトリバックアップは、各リポジトリをホストするGitalyノードがバックアップの作成とオブジェクトストレージへのストリーミングを担当するように構成できます。これにより、バックアップの作成と復元に必要なネットワークリソースを削減できます。
各Gitalyノードは、バックアップのためにオブジェクトストレージに接続するように構成する必要があります。
サーバー側のバックアップを構成した後、サーバー側のリポジトリバックアップを作成できます。
Azure Blob Storageを設定するには、次の手順に従います。
バックアップのためにAzure BLOBストレージを構成する方法は、お使いのインストールの種類によって異なります。セルフコンパイルインストールでは、AZURE_STORAGE_ACCOUNTとAZURE_STORAGE_KEYの環境変数をGitLabの外部に設定する必要があります。
/etc/gitlab/gitlab.rbを編集し、go_cloud_urlを構成します:
gitaly['env'] = {
'AZURE_STORAGE_ACCOUNT' => 'azure_storage_account',
'AZURE_STORAGE_KEY' => 'azure_storage_key' # or 'AZURE_STORAGE_SAS_TOKEN'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 'azblob://<bucket>'
}
}Helmベースのデプロイについては、Gitalyチャートのサーバー側のバックアップドキュメントを参照してください。
/home/git/gitaly/config.tomlを編集し、go_cloud_urlを構成します:
[backup]
go_cloud_url = "azblob://<bucket>"Google Cloud Storageを構成する
Google Cloud Storage(GCP)は、アプリケーションデフォルトの認証情報を使用して認証します。各Gitalyサーバーで、次のいずれかの方法でアプリケーションデフォルトの認証情報を設定します:
gcloud auth application-default loginコマンド。GOOGLE_APPLICATION_CREDENTIALS環境変数。セルフコンパイルインストールの場合、環境変数をGitLabの外部に設定します。
詳細については、アプリケーションデフォルトの認証情報を参照してください。
宛先バケットは、go_cloud_urlオプションを使用して構成されます。
/etc/gitlab/gitlab.rbを編集し、go_cloud_urlを構成します:
gitaly['env'] = {
'GOOGLE_APPLICATION_CREDENTIALS' => '/path/to/service.json'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 'gs://<bucket>'
}
}Helmベースのデプロイについては、Gitalyチャートのサーバー側のバックアップドキュメントを参照してください。
/home/git/gitaly/config.tomlを編集し、go_cloud_urlを構成します:
[backup]
go_cloud_url = "gs://<bucket>"S3ストレージを構成する
S3ストレージの認証を構成するには、以下を実行します:
- AWS CLIで認証する場合は、デフォルトのAWSセッションを使用できます。
- それ以外の場合は、
AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYの環境変数を使用できます。セルフコンパイルインストールでは、環境変数をGitLabの外部に設定します。
詳細については、AWSセッションのドキュメントを参照してください。
宛先バケットとAWSリージョンは、go_cloud_urlオプションを使用して構成されます。
/etc/gitlab/gitlab.rbを編集し、go_cloud_urlを構成します:
gitaly['env'] = {
'AWS_ACCESS_KEY_ID' => 'aws_access_key_id',
'AWS_SECRET_ACCESS_KEY' => 'aws_secret_access_key'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 's3://<bucket>?region=us-west-1'
}
}Helmベースのデプロイについては、Gitalyチャートのサーバー側のバックアップドキュメントを参照してください。
/home/git/gitaly/config.tomlを編集し、go_cloud_urlを構成します:
[backup]
go_cloud_url = "s3://<bucket>?region=us-west-1"S3互換サーバーを構成する
MinIOなどのS3互換サーバーは、endpointパラメータを追加して、S3と同様に構成されます。
次のパラメータがサポートされています:
region: AWSリージョン。endpoint: は、エンドポイントのURLです。disabledSSL:trueの値は、SSLを無効にします。s3ForcePathStyle:trueの値は、パススタイルのアドレス指定を強制します。
Helmベースのデプロイについては、Gitalyチャートのサーバー側のバックアップドキュメントを参照してください。
/etc/gitlab/gitlab.rbを編集し、go_cloud_urlを構成します:
gitaly['env'] = {
'AWS_ACCESS_KEY_ID' => 'minio_access_key_id',
'AWS_SECRET_ACCESS_KEY' => 'minio_secret_access_key'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 's3://<bucket>?region=minio&endpoint=my.minio.local:8080&disableSSL=true&s3ForcePathStyle=true'
}
}/home/git/gitaly/config.tomlを編集し、go_cloud_urlを構成します:
[backup]
go_cloud_url = "s3://<bucket>?region=minio&endpoint=my.minio.local:8080&disableSSL=true&s3ForcePathStyle=true"