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用またはその他の類似のWeb 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インデクサー。
- Gitaly自体。
- Gitalyサーバーは、
/config/gitlab.ymlで指定されている独自の(Gitaly address, Gitaly token)ペアを使用して、それ自体にRPCsコールを行うことができる必要があります。 - 認証は、GitalyノードとGitLab Railsノード間で共有される静的トークンを介して行われます。
次の図は、GitalyサーバーとGitLab Rails間の通信を、HTTPおよびHTTPs通信のデフォルトポートと共に示しています。
Gitalyサーバーは、Gitalyのネットワークトラフィックがデフォルトで暗号化されていないため、パブリックインターネットに公開してはなりません。Gitalyサーバーへのアクセスを制限するために、ファイアウォールの使用を強くお勧めします。別のオプションは、TLSを使用することです。
次のセクションでは、シークレットトークンabc123secretを使用して2つのGitalyサーバーを設定する方法について説明します:
gitaly1.internal。gitaly2.internal。
GitLabインストールには3つのリポジトリストレージがあるものとします:
default。storage1。storage2。
必要に応じて、1つのサーバーで1つのリポジトリストレージを使用することも可能です。
Gitalyをインストールする
各Gitalyサーバーに次のいずれかの方法でGitalyをインストールします:
- Linuxパッケージのインストール。目的のLinuxパッケージをダウンロードしてインストールしますが、
EXTERNAL_URL=の値を指定しないでください。 - セルフコンパイルインストール。Gitalyのインストールの手順に従ってください。
Gitalyサーバーの設定
Gitalyサーバーを設定するには、次の手順を実行する必要があります:
- 認証を設定します。
- ストレージパスを設定します。
- ネットワークリスナーを有効にします。
The git user must be able to読み取り, 書き込み、および設定されたストレージパス上の権限を設定できる必要があります。
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(推奨):
/etc/gitlab/gitlab-secrets.jsonをGitalyクライアントからGitalyサーバーおよびその他のGitalyクライアントの同じパスにコピーします。方法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
/home/git/gitlab/.gitlab_shell_secretをGitalyクライアントからGitalyサーバー(およびその他のGitalyクライアント)の同じパスにコピーします。Gitalyクライアントで、
/home/git/gitlab/config/gitlab.ymlを編集します:gitlab: gitaly: token: 'abc123secret'ファイルを保存し、GitLabを再起動します。
Gitalyサーバーで、
/home/git/gitaly/config.tomlを編集します:[auth] token = 'abc123secret'ファイルを保存し、GitLabを再起動します。
Gitalyサーバーを設定する
Gitalyサーバーを設定します。
Gitalyには、クライアント(RailsやSidekiqなど)によって提供されるアドレスを使用して、それ自体にRPCsコールを行うネットワーク呼び出しがいくつかあります。
ネットワーク設定が原因でGitalyがこの方法でそれ自体に到達できない場合(たとえば、Gitalyがヘアピン接続をサポートしないロードバランサーの背後にある場合):
- Gitalyサーバーの
/etc/hostsファイルを編集します。 - クライアントが使用するGitalyアドレスをGitalyサーバー自身のIPアドレスにリダイレクトするためのエントリを追加します。例:
127.0.0.1 gitaly.example.com、<local-ip> gitaly.example.com。
/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サーバーを定義することはできません。
Gitalyクライアントを次の2つの方法のいずれかで設定します。これらの手順は暗号化されていない接続用ですが、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を再起動します。
GitalyクライアントがGitalyサーバーに接続できることを確認するために
sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=productionを実行します。ログを追跡してリクエストを確認します。
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サーバーに外部アドレスを使用します。例:
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というストレージを必要とするため、GitLabアプリケーションサーバーを再設定してdefaultストレージを削除することはできません。この制限については、詳細をご覧ください。
この制限を回避するには:
- 新しいGitalyサービスで追加のストレージの場所を定義し、その追加ストレージを
defaultに設定します。ストレージの場所には、動作するストレージを期待するデータベース移行の問題を回避するために、Gitalyサービスが実行され、利用可能である必要があります。 - 管理者エリアで、
defaultのウェイトをゼロに設定して、リポジトリがそこに保存されないようにします。
Gitalyが不要な場所で無効化する(オプション)
Gitalyをリモートサービスとして実行している場合、デフォルトでGitLabサーバー上で実行されるローカルGitalyサービスを無効にし、必要な場所でのみ実行することを検討してください。
GitLabインスタンスでGitalyを無効にすることは、GitalyがGitLabインスタンスとは別のマシンで実行されるカスタムクラスター設定でGitLabを実行している場合にのみ意味があります。クラスター内のすべてのマシンでGitalyを無効にすることは、有効な設定ではありません(一部のマシンはGitalyサーバーとして機能する必要があります)。
GitLabサーバーでGitalyを次の2つの方法のいずれかで無効にします:
/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認証を一時的に無効にするには、次のように認証遷移モードに設定します:
# 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フェッチトラフィックを受信したときのサーバーの負荷を軽減できます。
Pack-objectsキャッシュは、PostUploadPackおよびSSHUploadPack Gitaly RPCsを使用することで間接的に実行されるGitの内部部分であるgit pack-objectsをラップします。Gitalyは、ユーザーがHTTPを使用してGitフェッチを実行するときにPostUploadPackを、ユーザーがSSHを使用してGitフェッチを実行するときにSSHUploadPackを実行します。キャッシュが有効になっている場合、PostUploadPackまたはSSHUploadPackを使用するものはすべて、その恩恵を受けることができます。それは独立しており、次の影響を受けません:
- トランスポート(HTTPまたはSSH)。
- Gitプロトコルバージョン(v0またはv2)。
- フルクローン、インクリメンタルフェッチ、シャロークローン、または部分クローンなどのフェッチの種類。
このキャッシュの強みは、同時に行われる同一のフェッチを重複排除する機能です。これは次のとおりです:
- 多くの並行ジョブを持つCI/CDパイプラインを実行するGitLabインスタンスにメリットがあります。サーバーのCPU使用率が著しく低下するはずです。
- ユニークなフェッチにはまったくメリットがありません。例えば、リポジトリをローカルコンピューターにクローンしてスポットチェックを実行しても、あなたのフェッチはユニークである可能性が高いため、このキャッシュによるメリットは期待できません。
Pack-objectsキャッシュはローカルキャッシュです。これは次のとおりです:
- 有効になっているGitalyプロセスのメモリにメタデータを保存します。
- キャッシュしている実際のGitデータをローカルストレージ上のファイルに保存します。
ローカルファイルを使用すると、オペレーティングシステムがpack-objectsキャッシュファイルの一部を自動的にRAMに保持できるため、処理が高速になるというメリットがあります。
Pack-objectsキャッシュはディスク書き込みIOを大幅に増加させる可能性があるため、デフォルトで無効になっています。
キャッシュを設定する
これらの設定設定は、pack-objectsキャッシュで利用できます。各設定については、以下で詳しく説明します。
| 設定 | デフォルト | 説明 |
|---|---|---|
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サーバー上のリポジトリのサイズと形状。
- ユーザーが生成するトラフィックの種類。
gitaly_pack_objects_generated_bytes_totalメトリクスを、キャッシュヒット率が0%であると仮定した悲観的な推定値として使用できます。
必要なスペースの量は、次のものに依存します:
- ユーザーがキャッシュからプルする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%削減できました。
キャッシュを監視する
Prometheusメトリクスとログフィールドを使用してキャッシュを監視できます。
Prometheusメトリクス
Gitalyは、pack-objectsキャッシュをモニタリングするための次のPrometheusメトリクスをエクスポートします:
| メトリック | 種類 | 説明 |
|---|---|---|
gitaly_pack_objects_served_bytes_total | カウンター | git-pack-objectsデータからクライアントに提供されたバイトの合計数。 |
gitaly_pack_objects_cache_lookups_total | カウンター | キャッシュルックアップの数。resultラベルはhitまたはmissを示します。 |
gitaly_pack_objects_generated_bytes_total | カウンター | git-pack-objectsを実行することによって生成されたバイトの合計数。 |
Example Prometheus queries:
キャッシュヒット率:
sum(rate(gitaly_pack_objects_cache_lookups_total{result="hit"}[5m])) /
sum(rate(gitaly_pack_objects_cache_lookups_total[5m]))キャッシュから提供された1秒あたりのバイト数:
rate(gitaly_pack_objects_served_bytes_total[5m])生成されたバイト(キャッシュミス)1秒あたり:
rate(gitaly_pack_objects_generated_bytes_total[5m])キャッシュ効率性(提供されたバイト数と生成されたバイト数):
rate(gitaly_pack_objects_served_bytes_total[5m]) /
rate(gitaly_pack_objects_generated_bytes_total[5m])ログフィールド
これらのログはgRPCログの一部であり、呼び出しが実行されたときに検出できます。
| フィールド | 説明 |
|---|---|
pack_objects_cache.hit | 現在のpack-objectsキャッシュがヒットしたかどうかを示します(trueまたはfalse) |
pack_objects_cache.key | pack-objectsキャッシュに使用されるキャッシュキー |
pack_objects_cache.generated_bytes | 書き込まれている新しいキャッシュのサイズ(バイト単位) |
pack_objects_cache.served_bytes | 提供されているキャッシュのサイズ(バイト単位) |
pack_objects.compression_statistics | pack-objects生成に関する統計。 |
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は、pack-object生成に関するより詳細な統計もログに記録します。 - キャッシュヒットの場合、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 RPCsは、リポジトリからGitオブジェクトをルックアップする必要があります。ほとんどの場合、これにはgit cat-file --batchプロセスを使用します。パフォーマンスを向上させるために、Gitalyはこれらのgit cat-fileプロセスをRPCs呼び出し間で再利用できます。以前に使用されたプロセスは、git cat-fileキャッシュに保持されます。これが使用するシステムリソースの量を制御するために、キャッシュに入れることができるcat-ファイルプロセスの最大数があります。
デフォルトの制限は100 cat-fileであり、これはgit cat-file --batchとgit cat-file --batch-checkプロセスのペアを構成します。「開いているファイルが多すぎます」というエラーや、新しいプロセスを作成できないというエラーが表示される場合は、この制限を下げたいと考えるかもしれません。
理想的には、この数は標準的なトラフィックを処理するのに十分な大きさであるべきです。制限を上げた場合、前後でキャッシュヒット率を測定する必要があります。ヒット率が改善しない場合、より高い制限は意味のある違いを生み出していない可能性が高いです。ヒット率を確認するための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を再起動します。
カスタムGit設定を設定する
GitalyはシステムまたはユーザーレベルのGit設定ファイルを読み取りません。GitalyサーバーでカスタムGit設定を提供するには、git.config設定を使用します。
/etc/gitlab/gitlab.rbを編集します:
gitaly['configuration'] = {
# ...
git: {
# ...
config: [
{ key: "fsck.badDate", value: "ignore" },
...
],
},
}/home/git/gitaly/config.tomlを編集します:
[[git.config]]
key = "fsck.badDate"
value = "ignore"Gitalyによって設定されるGit設定
Gitalyは次のGit設定値を設定します。これらはgit.config設定を使用してオーバーライドすることはできません:
advice.fetchShowForcedUpdatesattr.treebundle.heuristicbundle.modebundle.versioncore.alternateRefsCommandcore.autocrlfcore.bigFileThresholdcore.filesRefLockTimeoutcore.fsynccore.fsyncMethodcore.hooksPathcore.packedRefsTimeoutcore.useReplaceRefsdiff.noprefixfetch.fsck.badTimezonefetch.fsck.missingSpaceBeforeDatefetch.fsck.zeroPaddedFilemodefetch.fsckObjectsfetch.negotiationAlgorithmfetch.recurseSubmodulesfetch.writeCommitGraphfsck.badTimezonefsck.missingSpaceBeforeDatefsck.zeroPaddedFilemodegc.autogrep.threadshttp.<url>.extraHeaderhttp.curloptResolvehttp.extraHeaderhttp.followRedirectsinit.defaultBranchinit.templateDirmaintenance.autopack.allowPackReusepack.islandpack.islandCorepack.threadspack.windowMemorypack.writeBitmapLookupTablepack.writeReverseIndexreceive.advertisePushOptionsreceive.autogcreceive.fsck.badTimezonereceive.fsck.missingSpaceBeforeDatereceive.fsck.zeroPaddedFilemodereceive.hideRefsreceive.procReceiveRefsremote.inmemory.fetchremote.inmemory.urlremote.origin.fetchremote.origin.urlrepack.updateServerInforepack.writeBitmapstransfer.bundleURItransfer.fsckObjectsuploadpack.advertiseBundleURIsuploadpack.allowAnySHA1InWantuploadpack.allowFilteruploadpack.hideRefs
外部コマンドを使用して設定を生成する
外部コマンドを使用して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 ...`}}})その後、スクリプトパスを次の2つの方法のいずれかでGitalyに認識させる必要があります:
/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ストレージの設定
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セッションドキュメントを参照してください。
宛先バケットとリージョンは、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互換サーバーの設定
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' => '<your_access_key_id>',
'AWS_SECRET_ACCESS_KEY' => '<your_secret_access_key>'
}
gitaly['configuration'] = {
backup: {
go_cloud_url: 's3://<bucket>?region=us-east-1&endpoint=s3.example.com:9000&disableSSL=true&s3ForcePathStyle=true'
}
}/home/git/gitaly/config.tomlを編集し、go_cloud_urlを設定します:
[backup]
go_cloud_url = "s3://<bucket>?region=us-east-1&endpoint=s3.example.com:9000&disableSSL=true&s3ForcePathStyle=true"