Gitalyの設定

Gitalyの設定は2つの方法があります:

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集し、Gitalyの設定を追加または変更します。
  2. ファイルを保存し、GitLabを再設定してください。
Self-compiled (source)
  1. /home/git/gitaly/config.toml を編集し、Gitalyの設定を追加または変更します。
  2. ファイルを保存し、GitLabを再起動します。

以下の設定オプションも利用できます:

Gitalyトークンについて

Gitalyのドキュメント全体で言及されているトークンは、管理者によって選択された任意のパスワードに過ぎません。GitLab APIのために作成されたトークンや、他の同様のWeb APIトークンとは無関係です。

独自のサーバーでGitalyを実行します。

デフォルトでは、GitalyはGitalyクライアントと同じサーバー上で実行され、上記のように設定されています。単一サーバーでのインストールには、このデフォルト設定が最適です:

しかし、Gitalyは独自のサーバーにデプロイすることができ、複数のマシンにまたがるGitLabインストールに役立ちます。

note
独自のサーバーで実行するように設定した場合、Gitalyサーバーはクラスター内のGitalyクライアントより先にアップグレードする必要があります。
note
ディスク要件はGitalyノードに適用されます。

Gitalyを独自のサーバーにセットアップする手順は以下の通りです:

  1. Gitalyをインストールします。
  2. 認証設定を行います。
  3. Gitalyサーバの設定
  4. Gitalyクライアントの設定
  5. Gitalyが必要ない場合は無効にしてください(オプション)。

ネットワークアーキテクチャ

Gitalyのネットワークアーキテクチャを以下に示します:

  • GitLab Railsはリポジトリをリポジトリストレージに分割します。
  • /config/gitlab.yml コンテナには、ストレージ名から(Gitaly address, Gitaly token) ペアへのマップが含まれています。
  • /config/gitlab.ymlstorage 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) ペアを使用することで、自身に対してRPCコールを行うことができなければなりません。
  • 認証はGitalyとGitLab Railsノード間で共有される静的トークンを使って行われます。

次の図は、GitalyサーバーとGitLab Rails間の通信を示すもので、HTTPとHTTPs通信のデフォルトポートを示しています。

Gitaly network architecture diagram

caution
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サーバーを設定するには、以下の手順が必要です:

  • 認証を設定します。
  • ストレージパスの設定
  • ネットワークリスナーを有効にします。

git ユーザーは、設定されたストレージパスの読み取り、書き込み、および権限設定ができる必要があります。

Gitalyトークンをローテーションしている間のダウンタイムを避けるために、gitaly['auth_transitioning'] の設定を使って一時的に認証を無効にすることができます。詳しくは、“auth transitioning mode “を有効にするドキュメントをご覧ください。

認証の設定

GitalyとGitLabは、認証に2つの共有シークレットを使います:

  • Gitalyトークン: GitalyへのgRPCリクエストを認証するために使用します。
  • _GitLab Shellトー_クン: GitLab ShellからGitLab内部APIへの認証コールバックに使用します。

認証の設定は以下の2つの方法のどちらかで行います:

Linux package (Omnibus)

_Gitaly トークンを_設定するには、/etc/gitlab/gitlab.rb を編集します:

gitaly['configuration'] = {
   # ...
   auth: {
     # ...
     token: 'abc123secret',
   },
}

_GitLab Shellトーク_ンを設定するには、以下の2つの方法があります。

方法1(推奨):

/etc/gitlab/gitlab-secrets.json 、GitalyクライアントからGitalyサーバ(および他のGitalyクライアント)の同じパスにコピーします。

方法2:

/etc/gitlab/gitlab.rb を編集します:

gitlab_shell['secret_token'] = 'shellsecret'
Self-compiled (source)
  1. /home/git/gitlab/.gitlab_shell_secret をGitalyクライアントからGitalyサーバ(および他のGitalyクライアント)の同じパスにコピーします。
  2. Gitalyクライアント上で、/home/git/gitlab/config/gitlab.yml を編集します:

    gitlab:
      gitaly:
        token: 'abc123secret'
    
  3. ファイルを保存し、GitLabを再起動します。
  4. Gitalyサーバー上で、/home/git/gitaly/config.toml

    [auth]
    token = 'abc123secret'
    
  5. ファイルを保存し、GitLabを再起動します。

Gitalyサーバーの設定

Gitalyサーバーの設定は以下の2つの方法があります:

Linux package (Omnibus)
  1. /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
    grafana['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',
       },
    }
    
  2. 各 Gitaly サーバの/etc/gitlab/gitlab.rb に以下を追加してください:

    gitaly1.internal にて:

    gitaly['configuration'] = {
       # ...
       storage: [
          {
             name: 'default',
             path: '/var/opt/gitlab/git-data',
          },
          {
             name: 'storage1',
             path: '/mnt/gitlab/git-data',
          },
       ],
    }
    

    gitaly2.internal にて:

    gitaly['configuration'] = {
       # ...
       storage: [
          {
             name: 'storage2',
             path: '/srv/gitlab/git-data',
          },
       ],
    }
    
  3. ファイルを保存し、GitLabを再設定してください。
  4. GitalyがGitLab内部APIへのコールバックを実行できることを確認します:
    • GitLab 15.3以降では、sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml.
    • GitLab 15.2 以前については、sudo /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml を実行してください。
Self-compiled (source)
  1. /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'
    

    GitLab 14.9以前の場合は、runtime_dir の代わりにinternal_socket_dir = '/var/opt/gitlab/gitaly' を設定してください。

  2. それぞれの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'
    
  3. /home/git/gitlab-shell/config.yml を編集します:

    gitlab_url: https://gitlab.example.com
    
  4. ファイルを保存し、GitLabを再起動します。
  5. GitalyがGitLab内部APIへのコールバックを実行できることを確認します:
    • GitLab 15.3以降では、sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml.
    • GitLab 15.2 以前については、sudo /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml を実行してください。
caution
GitLabサーバーからGitalyにリポジトリデータを直接コピーする場合、メタデータファイル(デフォルトパス/var/opt/gitlab/git-data/repositories/.gitaly-metadata )が転送に含まれていないことを確認してください。このファイルをコピーすると、Gitalyサーバーでホストされているリポジトリに対してGitLabがRuggedパッチを使用するようになり、Error creating pipelineCommit not found のエラーや古いデータの原因となります。

Gitalyクライアントの設定

最後のステップとして、Gitalyクライアントを更新し、ローカルのGitalyサービスを使用することから、先ほど設定したGitalyサーバーを使用することに切り替える必要があります。

note
GitLabはdefault リポジトリストレージを設定する必要があります。この制限についてはこちらをご覧ください。

GitalyクライアントがGitalyサーバーに到達するのを妨げるものは、すべてのGitalyリクエストを失敗させるので、これは危険です。例えば、ネットワーク、ファイアウォール、名前解決の問題などです。

Gitalyでは、以下のような前提を置いています:

  • あなたのgitaly1.internal Gitaly サーバは、あなたの Gitaly クライアントからgitaly1.internal:8075 に到達でき、Gitaly サーバは/var/opt/gitlab/git-data/mnt/gitlab/git-data の読み書きと権限設定が可能です。
  • あなたのgitaly2.internal Gitalyサーバーは、あなたのGitalyクライアントからgitaly2.internal:8075 に到達することができ、そのGitalyサーバーは、/srv/gitlab/git-data に対する権限の読み取り、書き込み、設定が可能です。
  • あなたのgitaly1.internalgitaly2.internal Gitaly サーバは、お互いにアクセスすることができます。

あるGitalyサーバーをローカルGitalyサーバー(なしgitaly_address) gitaly_addressとしてgitaly_address、あるGitalyサーバーをリモートサーバー(あり gitaly_address)として定義することは、混合設定を使用しない限りできません。

Gitalyクライアントの設定は、以下の2つの方法があります:

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集します:

    # Use the same token value configured on all Gitaly servers
    gitlab_rails['gitaly_token'] = '<AUTH_TOKEN>'
       
    git_data_dirs({
      'default'  => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage1' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
      'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
    })
    

    また、Gitalyサーバごとに異なる認証トークンを使用する設定になっている場合は、その認証トークンを使用することもできます:

    git_data_dirs({
      '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>' },
    })
    
  2. ファイルを保存し、GitLabを再設定してください。
  3. Gitalyクライアント(例えば、Railsアプリケーション)でsudo gitlab-rake gitlab:gitaly:check を実行し、Gitalyサーバーに接続できることを確認します。
  4. リクエストを確認するためにログを見てください:

    sudo gitlab-ctl tail gitaly
    
Self-compiled (source)
  1. /home/git/gitlab/config/gitlab.yml を編集します:

    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tcp://gitaly1.internal:8075
            gitaly_token: AUTH_TOKEN_1
            path: /some/local/path
          storage1:
            gitaly_address: tcp://gitaly1.internal:8075
            gitaly_token: AUTH_TOKEN_1
            path: /some/local/path
          storage2:
            gitaly_address: tcp://gitaly2.internal:8075
            gitaly_token: AUTH_TOKEN_2
            path: /some/local/path
    
    note
    /some/local/path は存在するローカルフォルダに設定する必要がありますが、このフォルダにはデータは保存されません。このイシューが解決された場合、この要件は削除される予定です。
  2. ファイルを保存し、GitLabを再起動します。
  3. sudo -u git -H bundle exec rake gitlab:gitaly:check RAILS_ENV=production を実行し、Gitaly クライアントが Gitaly サーバーに接続できることを確認します。
  4. リクエストを確認するためにログを見てください:

    tail -f /home/git/gitlab/log/gitaly.log
    

GitalyサーバーのGitalyログを追跡すると、リクエストが入ってくるのがわかるはずです。Gitalyのリクエストをトリガーする確実な方法の1つは、GitLabからHTTPまたはHTTPSでリポジトリをクローンすることです。

caution
リポジトリごと、またはグローバルにサーバーフックを設定している場合は、これらをGitalyサーバーに移動する必要があります。複数のGitalyサーバーがある場合、サーバーフックをすべてのGitalyサーバーにコピーしてください。

混合設定

GitLabは多くのGitalyサーバーと同じサーバー上に置くことができますが、ローカルとリモートを混在させる設定はサポートしていません。以下の設定は正しくありません:

  • すべてのアドレスが他のGitalyサーバーから到達可能でなければなりません。
  • storage1 は、gitaly_address の Unix ソケットが割り当てられていますが、Gitaly サーバによっては無効です。
git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
  'storage1' => { 'path' => '/mnt/gitlab/git-data' },
  'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
})

ローカルとリモートのGitalyサーバーを組み合わせるには、ローカルのGitalyサーバーに外部アドレスを使用します。例えば

git_data_dirs({
  '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',
    },
  ],
}

path は、ローカルGitalyサーバー上のストレージシャードに対してのみ含めることができます。除外された場合、デフォルトのGitストレージ・ディレクトリがそのストレージ・シャードに使用されます。

GitLabはデフォルトのリポジトリストレージを必要とします。

環境にGitalyサーバーを追加するとき、元のdefault Gitaly defaultサービスを置き換えたくなるかもしれません。default しかし、GitLabアプリケーションサーバを再設定して defaultエントリをdefault 削除 defaultすることはできませんgit_data_dirs 。なぜなら、GitLabは git_data_dirs defaultというエントリをgit_data_dirs 必要と git_data_dirsするからです。この制限についてもっと読む

この制限を回避するには

  1. 新しい Gitaly サービスに追加のストレージを定義し、defaultに設定します。
  2. 管理エリアでは、リポジトリがそこに保存されるのを防ぐために、default のウェイトをゼロに設定します。

不要なGitalyを無効にする(オプション)

Gitalyをリモートサービスとして実行する場合は、GitLabサーバー上でデフォルトで実行されるローカルのGitalyサービスを無効にし、必要な場所でのみ実行することを検討してください。

GitLabインスタンス上でGitalyを無効にすることは、GitLabインスタンスとは別のマシンでGitalyを実行する、カスタムクラスタ設定でGitLabを実行する場合にのみ意味があります。クラスター内のすべてのマシンでGitalyを無効にするのは有効な設定とは言えません(Gitalyサーバーとして動作するマシンもあります)。

GitLabサーバーでGitalyを無効にするには、2つの方法があります:

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集します:

    gitaly['enable'] = false
    
  2. ファイルを保存し、GitLabを再設定してください。

Self-compiled (source)
  1. /etc/default/gitlab を編集します:

    gitaly_enabled=false
    
  2. ファイルを保存し、GitLabを再起動します。

TLSサポートを有効にします

GitalyはTLS暗号化をサポートしています。安全な接続をリッスンするGitalyインスタンスと通信するには、GitLab設定の対応するストレージエントリのgitaly_addresstls:// URLスキームを使用します。

GitalyはGitLabへのTLS接続において、クライアント証明書と同じサーバー証明書を提供します。これは、GitLabへのアクセスを許可するためにクライアント証明書を検証するリバースプロキシ(例えばNGINX)と組み合わせたときに、相互TLS認証戦略の一部として使用することができます。

これは自動的には提供されないので、自分で証明書を用意する必要があります。各Gitalyサーバーに対応する証明書をインストールする必要があります。

さらに、証明書(またはその作成者)は全てにインストールされている必要があります:

  • Gitalyサーバー。
  • それと通信するGitalyクライアント。

ロードバランサーを使用する場合は、ALPN TLSエクステンションを使用してHTTP/2をネゴシエートできなければなりません。

証明書の要件

  • 証明書には、Gitalyサーバーへのアクセスに使用するアドレスを指定する必要があります。ホスト名またはIPアドレスを証明書のサブジェクト代替名として追加する必要があります。
  • 暗号化されていないリスニング・アドレスlisten_addr と暗号化されたリスニング・アドレスtls_listen_addr の両方を持つGitalyサーバーを同時に設定することができます。これにより、必要に応じて暗号化されていないトラフィックから暗号化されたトラフィックへ徐々に移行することができます。
  • 証明書のCommon Nameフィールドは無視されます。

TLSによるGitalyの設定

GitalyをTLSで設定するには、以下の2つの方法があります:

Linux package (Omnibus)
  1. Gitalyサーバー用の証明書を作成します。
  2. Gitalyクライアント上で、証明書(またはその作成者)を/etc/gitlab/trusted-certs にコピーします:

    sudo cp cert.pem /etc/gitlab/trusted-certs/
    
  3. Gitalyクライアント上で、/etc/gitlab/gitlab.rbgit_data_dirs を以下のように編集してください:

    git_data_dirs({
      'default' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage1' => { 'gitaly_address' => 'tls://gitaly1.internal:9999' },
      'storage2' => { 'gitaly_address' => 'tls://gitaly2.internal:9999' },
    })
    
  4. ファイルを保存し、GitLabを再設定してください。
  5. Gitalyサーバー上で、/etc/gitlab/ssl ディレクトリを作成し、そこに鍵と証明書をコピーします:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
    
  6. 全てのGitalyサーバ証明書(またはその作成者)を、全てのGitalyサーバとクライアントの/etc/gitlab/trusted-certs にコピーし、Gitalyサーバとクライアントが、自分自身や他のGitalyサーバを呼び出す際に証明書を信頼できるようにします:

    sudo cp cert1.pem cert2.pem /etc/gitlab/trusted-certs/
    
  7. /etc/gitlab/gitlab.rb を編集し、追加してください:

    gitaly['configuration'] = {
       # ...
       tls_listen_addr: '0.0.0.0:9999',
       tls: {
         certificate_path: '/etc/gitlab/ssl/cert.pem',
         key_path: '/etc/gitlab/ssl/key.pem',
       },
    }
    
  8. ファイルを保存し、GitLabを再設定してください。
  9. Gitaly接続のタイプを観察することで、GitalyトラフィックがTLS経由で提供されていることを確認してください。
  10. オプション。以下の方法でセキュリティを向上させてください:
    1. /etc/gitlab/gitlab.rbgitaly['configuration'][:listen_addr] をコメントアウトまたは削除して、非 TLS 接続を無効にします。
    2. ファイルを保存します。
    3. GitLab を再設定します。
Self-compiled (source)
  1. Gitalyサーバー用の証明書を作成します。
  2. Gitalyクライアント上で、証明書をシステム信頼済み証明書にコピーします:

    sudo cp cert.pem /usr/local/share/ca-certificates/gitaly.crt
    sudo update-ca-certificates
    
  3. Gitalyクライアント上で、/home/git/gitlab/config/gitlab.ymlstorages を以下のように編集してください:

    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tls://gitaly1.internal:9999
            path: /some/local/path
          storage1:
            gitaly_address: tls://gitaly1.internal:9999
            path: /some/local/path
          storage2:
            gitaly_address: tls://gitaly2.internal:9999
            path: /some/local/path
    
    note
    /some/local/path は存在するローカルフォルダに設定されるべきですが、このフォルダにはデータは保存されません。この要件は、Gitalyのイシュー#1282が解決された時点で削除される予定です。
  4. ファイルを保存し、GitLabを再起動します。
  5. Gitalyサーバー上で、/etc/default/gitlab を作成または編集し、追加します:

    export SSL_CERT_DIR=/etc/gitlab/ssl
    
  6. Gitalyサーバー上で、/etc/gitlab/ssl ディレクトリを作成し、そこに鍵と証明書をコピーしてください:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
    
  7. 全てのGitalyサーバ証明書(またはその作成者)をシステム信頼済み証明書フォルダにコピーし、Gitalyサーバが自身または他のGitalyサーバを呼び出す際に証明書を信頼するようにします。

    sudo cp cert.pem /usr/local/share/ca-certificates/gitaly.crt
    sudo update-ca-certificates
    
  8. /home/git/gitaly/config.toml を編集し、追加してください:

    tls_listen_addr = '0.0.0.0:9999'
       
    [tls]
    certificate_path = '/etc/gitlab/ssl/cert.pem'
    key_path = '/etc/gitlab/ssl/key.pem'
    
  9. ファイルを保存し、GitLabを再起動します。
  10. Gitaly接続のタイプを観察することで、GitalyトラフィックがTLS経由で提供されていることを確認してください。
  11. オプション。以下の方法でセキュリティを向上させてください:
    1. /home/git/gitaly/config.tomllisten_addr をコメントアウトまたは削除して、非 TLS 接続を無効にします。
    2. ファイルを保存します。
    3. GitLabを再起動します。

Gitaly接続の種類を見る

Gitaly接続の種類を確認する方法については、関連ドキュメントをご覧ください。

RPCの同時実行の制限

caution
環境に制限を設けることは、予期しないトラフィックから保護するためなど、特定の状況でのみ慎重に行う必要があります。制限に達すると_、_ユーザーに悪影響を与える切断が発生します。一貫した安定したパフォーマンスを得るには、まずノードの仕様を調整したり、大規模なリポジトリやワークロードをレビューしたりするなど、他のオプションを検討する必要があります。

リポジトリをクローンしたりプルしたりする際には、さまざまな RPC がバックグラウンドで実行されます。特に、Git pack RPCです:

  • SSHUploadPackWithSidechannel (Git SSH用)。
  • PostUploadPackWithSidechannel (Git HTTP用)。

これらの RPC は大量のリソースを消費する可能性があり、以下のような状況で大きな影響を与える可能性があります:

Gitaly設定ファイルの同時実行数制限を使用することで、このようなシナリオでGitalyサーバーを圧倒するプロセスを制限することができます。例えば

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
   # ...
   concurrency: [
      {
         rpc: '/gitaly.SmartHTTPService/PostUploadPackWithSidechannel',
         max_per_repo: 20,
         max_queue_time: '1s',
         max_queue_size: 10,
      },
      {
         rpc: '/gitaly.SSHService/SSHUploadPackWithSidechannel',
         max_per_repo: 20,
         max_queue_time: '1s',
         max_queue_size: 10,
      },
   ],
}
  • rpc は、リポジトリごとの同時実行数制限を設定するRPCの名前です。
  • max_per_repo はリポジトリごとに指定された RPC のインフライト RPC 呼び出しの最大数です。
  • max_queue_time は、リクエストがGitalyによってピックアップされるために同時実行キューで待つことができる最大時間です。
  • max_queue_size は、Gitalyによってリクエストが拒否される前に、(RPCメソッドごとに)同時実行キューが成長できる最大サイズです。

これは、指定されたRPCのインフライトRPC呼び出しの数を制限します。制限はリポジトリごとに適用されます。上の例では

  • Gitalyサーバーによって提供される各リポジトリは、最大20の同時PostUploadPackWithSidechannelSSHUploadPackWithSidechannel RPCコールを飛行中に持つことができます。
  • 20のスロットを使い切ったリポジトリに別のリクエストが来た場合、そのリクエストはキューに入れられます。
  • リクエストがキューで1秒以上待たされると、エラーで拒否されます。
  • もしキューが10を超えた場合、それ以降のリクエストはエラーで拒否されます。
note
これらの制限に達すると、ユーザーは切断されます。

GitalyのログやPrometheusを使って、このキューの動作を観察することができます。詳細については、関連ドキュメントを参照してください。

パックオブジェクトの同時実行の制限

Gitalyは、リポジトリのクローンやプルのためにSSHとHTTPSの両方のトラフィックを処理する際に、git-pack-objects プロセスをトリガーします。これらのプロセスはpack-file を生成し、特に予期せぬ高トラフィックや大規模なリポジトリからの同時プルなどの状況では、大量のリソースを消費する可能性があります。GitLab.comでは、インターネット接続が遅いクライアントでの問題も確認されています。

Gitalyの設定ファイルでpack-objects concurrency limitsを設定することで、これらのプロセスがGitalyサーバーを圧倒するのを制限することができます。この設定は、リモートIPアドレスあたりのインフライトpack-objectプロセス数を制限します。

caution
この制限は、予期せぬトラフィックから保護するためなど、特定の状況でのみ注意して有効にしてください。これらの制限に達すると、ユーザーが切断されます。一貫した安定したパフォーマンスを得るには、まずノードの仕様を調整したり、大規模なリポジトリやワークロードをレビューしたりするなど、他のオプションを検討する必要があります。

設定例

# in /etc/gitlab/gitlab.rb
gitaly['pack_objects_limiting'] = {
   'max_concurrency' => 15,
   'max_queue_length' => 200,
   'max_queue_wait' => '60s',
}
  • max_concurrency は、キーごとのインフライト・パック・オブジェクト・プロセスの最大数です。
  • max_queue_length は、Gitalyによってリクエストが拒否される前に、 (キーごとに)同時実行キューが成長できる最大サイズです。
  • max_queue_wait は、リクエストがGitalyによってピックアップされるために、同時実行キューで待つことができる最大時間です。

上記の例では、以下の項目を出力します。

  • 各リモートIPは、Gitalyノード上で最大15個の同時パックオブジェクトプロセスを持つことができます。
  • 15個のスロットを使い切ったIPから別のリクエストが来た場合、 そのリクエストはキューに入れられます。
  • リクエストがキューで1分以上待たされると、エラーで拒否されます。
  • キューが200を超えた場合、それ以降のリクエストはエラーで拒否されます。

パックオブジェクトキャッシュが有効になっている場合、パックオブジェクトの制限はキャッシュが取りこぼされた場合にのみ有効になります。詳細はPack-objects cacheを参照してください。

GitalyのログとPrometheusを使って、このキューの動作を観察することができます。詳細については、Gitaly pack-objects concurrency limitingの監視を参照してください。

制御グループ

caution
環境に制限を設けることは、予期しないトラフィックから保護するためなど、特定の状況でのみ慎重に行う必要があります。制限に達すると_、_ユーザーに悪影響を与える切断が発生します。一貫した安定したパフォーマンスを得るには、まずノードの仕様を調整したり、大規模なリポジトリやワークロードをレビューしたりするなど、他のオプションを検討する必要があります。

メモリのcgroupsを有効にする場合、プロセスが終了する代わりにスワップを使用するように切り替わる可能性があるため、Gitalyノードにスワップが設定されていないことを確認する必要があります。このような状況では、パフォーマンスが著しく低下する可能性があります。

Linuxでは、コントロール・グループ(cgroups)を使用して、Gitalyプロセスによって消費されるメモリとCPUの量に制限をかけることができます。詳細については、cgroups Linux man page を参照してください。cgroupsは、メモリとCPUの過剰消費による予期せぬリソースの枯渇からシステムを保護するのに役立ちます。

Gitオペレーションの中には、以下のような状況でリソースを使い果たすほど消費するものがあります:

  • 予期せぬ高トラフィック
  • ベストプラクティスに従わない大規模リポジトリに対するオペレーション。

ハード的な保護として、カーネルを設定するcgroupsを使用して、これらのオペレーションがすべてのシステムリソースを占有し、不安定になる前に終了させることが可能です。

Gitalyには組み込みのcgroups制御があります。設定すると、GitalyはGitコマンドのオペレーションが行われているリポジトリに基づいて、Gitプロセスをcgroupに割り当てます。これらのcgroupはリポジトリcgroupと呼ばれます。それぞれのリポジトリcgroupは

  • メモリとCPUの制限があります。
  • 単一のリポジトリの Git プロセスをコンテナで管理します。
  • 一貫したハッシュを使うことで、指定したリポジトリの Git プロセスが常に同じ cgroup に収まるようにします。

リポジトリの cgroup がその長さに達すると、その cgroup は終了します:

  • メモリ制限に達すると、カーネルは kill する候補のプロセスを探します。
  • CPU制限、プロセスは強制終了されませんが、プロセスが許容以上のCPUを消費しないようにします。
note
これらの制限に達すると、パフォーマンスが低下し、ユーザーが切断されることがあります。

リポジトリ cgroups の設定(新方式)

  • このリポジトリ cgroups の設定方法は GitLab 15.1 で導入されました。
  • cpu_quota_usGitLab 15.10 で導入されました。

新しい方法でGitalyのリポジトリcgroupsを設定するには、/etc/gitlab/gitlab.rb の新しい設定方法gitaly['configuration'][:cgroups] に以下の設定を使用します:

  • mountpoint は親 cgroup ディレクトリがマウントされる場所です。デフォルトは/sys/fs/cgroup です。
  • hierarchy_root は、Gitalyがグループを作成する親cgroupであり、Gitalyが実行するユーザーとグループによって所有されることが期待されます。Linuxのパッケージ・インストールは、Gitalyの起動時に、mountpoint/<cpu|memory>/hierarchy_root ディレクトリのセットを作成します。
  • memory_bytes は、Gitalyが生成するすべてのGitプロセスに対して一括して課される合計メモリ制限です。0は制限なしを意味します。
  • cpu_shares は、Gitalyがスポーンする全てのGitプロセスに一括して課されるCPU制限です。0は制限なしを意味します。最大は1024シェアで、これはCPUの100%に相当します。
  • cpu_quota_us は、cgroupsのプロセスがこのクォータ値を超えた場合にスロットルするためのcfs_quota_uscfs_period_us100ms に設定しているので、1 Core は100000です。0 は制限なしを意味します。
  • repositories.count は cgroups プール内の cgroups の数です。新しいGitコマンドが生成されるたびに、Gitalyはコマンドが対象とするリポジトリに基づいて、これらのcgroupsのいずれかに割り当てます。循環ハッシュアルゴリズムによってGitコマンドがこれらのcgroupに割り当てられるので、あるリポジトリに対するGitコマンドは常に同じcgroupに割り当てられます。
  • repositories.memory_bytes は、リポジトリ cgroup に含まれるすべての Git プロセスに課される合計メモリ制限です。0 は制限なしを意味します。この値は、トップレベルmemory_bytes の値を超えることはできません。
  • repositories.cpu_shares は、リポジトリ cgroup に含まれるすべての Git プロセスに課される CPU の制限です。0 は制限なしを意味します。最大値は 1024 個で、CPU の 100% に相当します。この値は、トップレベルcpu_shares の値を超えることはできません。
  • repositories.cpu_quota_us は、リポジトリ cgroup に含まれるすべての Git プロセスに課されるcfs_quota_us です。Git プロセスは、指定されたクォータを超えて使用することはできません。cfs_period_us100ms に設定したので、1 core は100000です。0 は制限なしを意味します。

使用例:

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
  # ...
  cgroups: {
    mountpoint: '/sys/fs/cgroup',
    hierarchy_root: 'gitaly',
    memory_bytes: 64424509440, # 60gb
    cpu_shares: 1024,
    cpu_quota_us: 400000 # 4 cores
    repositories: {
      count: 1000,
      memory_bytes: 32212254720, # 20gb
      cpu_shares: 512,
      cpu_quota_us: 200000 # 2 cores
    },
  },
}

リポジトリcgroupsの設定(従来の方法)

レガシー方式でGitalyのリポジトリcgroupを設定するには、/etc/gitlab/gitlab.rb

  • cgroups_count は作成されるcgroupsの数です。新しいコマンドが生成されるたびに、Gitalyはコマンドのコマンドライン引数に基づいて、これらのcグループのいずれかに割り当てます。循環ハッシュ・アルゴリズムがコマンドをこれらのcgroupに割り当てます。
  • cgroups_mountpoint は親 cgroup ディレクトリがマウントされる場所です。デフォルトは/sys/fs/cgroup です。
  • cgroups_hierarchy_root は、Gitalyがグループを作成する親cgroupであり、Gitalyが実行するユーザーとグループによって所有されることが期待されます。Linuxのパッケージ・インストールは、Gitalyの起動時に、mountpoint/<cpu|memory>/hierarchy_root ディレクトリのセットを作成します。
  • cgroups_memory_enabled cgroupsのメモリ制限を有効または無効にします。
  • cgroups_memory_bytes は、各 cgroup が追加されたプロセスに課すメモリ制限の合計です。
  • cgroups_cpu_enabled cgroups の CPU 制限を有効または無効にします。
  • cgroups_cpu_shares は、各 cgroup がその cgroup に追加されるプロセスに課す CPU 制限です。最大は 1024 共有で、CPU の 100% に相当します。

使用例:

# in /etc/gitlab/gitlab.rb
gitaly['cgroups_count'] = 1000
gitaly['cgroups_mountpoint'] = "/sys/fs/cgroup"
gitaly['cgroups_hierarchy_root'] = "gitaly"
gitaly['cgroups_memory_limit'] = 32212254720
gitaly['cgroups_memory_enabled'] = true
gitaly['cgroups_cpu_shares'] = 1024
gitaly['cgroups_cpu_enabled'] = true

オーバーサブスクリプションの設定

前の例では、新しい設定方法を使用しました:

  • トップレベルのメモリ上限は 60 GB です。
  • リポジトリプールの 1000 個の cgroup のそれぞれの上限は 20 GB です。

この設定は「オーバーサブスクリプション」につながります。プール内の各cgroupは、トップレベルのメモリ制限の1/1000よりもはるかに大きな容量を持っています。

この戦略には主に 2 つの利点があります:

  • 最上位の cgroup のメモリ制限をホストの容量より小さいしきい値に設定できるため、全体的なメモリ飢餓(OOM)からホストを保護できます。その cgroup の外のプロセスは OOM のリスクはありません。
  • プール内の個々の cgroup は、親 cgroup のリミットより小さいが、親のリミットの 1/N よりもかなり大きい、余裕のある上限(この例では 20GB)までバーストできます。この例では、最大 3 つの子 cgroup が同時に最大までバーストできます。一般的に、1000 個の cgroup すべてが使用する容量は 20 GB よりもはるかに少なくなります。

バックグラウンドリポジトリの最適化

空のディレクトリや不要な設定がリポジトリに蓄積され、Gitオペレーションが遅くなることがあります。Gitalyは、これらのアイテムをクリーンアップし、パフォーマンスを向上させるために、最大期間を持つ毎日のバックグラウンドタスクをスケジュールすることができます。

caution
バックグラウンドリポジトリ最適化は実験的な機能であり、実行中はホストに大きな負荷をかける可能性があります。必ずオフピーク時にスケジュールを組み、実行時間を短く(例えば30~60分)してください。

バックグラウンドリポジトリ最適化を設定するには、2つの方法があります:

Linux package (Omnibus)

/etc/gitlab/gitlab.rb を編集し、追加してください:

gitaly['configuration'] = {
  # ...
  daily_maintenance: {
    # ...
    start_hour: 4,
    start_minute: 30,
    duration: '30m',
    storages: ['default'],
  },
}
Self-compiled (source)

/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サーバを “auth transitioning “モードにすることで、Gitaly認証を一時的に無効化します:

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
  # ...
  auth: {
    # ...
    transitioning: true,
  },
}

この変更を行った後、Prometheusクエリは以下のような結果を返すはずです:

{enforced="false",status="would be ok"}  4424.985419441742

なぜならenforced="false" 、新しいトークンのロールアウトを開始しても安全だからです。

Gitaly認証トークンの更新

新しいGitaly認証トークンに更新するには、各GitalyクライアントとGitalyサーバー上で行います:

  1. 設定を更新します:

    # in /etc/gitlab/gitlab.rb
    gitaly['configuration'] = {
       # ...
       auth: {
          # ...
          token: '<new secret token>',
       },
    }
    
  2. 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認証を再度有効にするには、”auth transitioning “モードを無効にします。Gitalyサーバーの設定を以下のように更新してください:

# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
  # ...
  auth: {
    # ...
    transitioning: false,
  },
}
caution
この操作を行わないと、Gitaly認証は有効になりません。

認証が有効であることを確認

クエリをリフレッシュしてください。先ほどと同じような結果が表示されるはずです。例えば

{enforced="true",status="ok"}  4424.985419441742

enforced="true" は認証が実行されていることを意味します。

パック・オブジェクト・キャッシュ

Git リポジトリのストレージを提供するサービスであるGitaly は、Git フェッチレスポンスの短いローリングウィンドウをキャッシュするように設定できます。これは、あなたのサーバーが多くのCIフェッチトラフィックを受け取ったときにサーバーの負荷を軽減することができます。

pack-objectsキャッシュはgit pack-objects をラップしています。これはGitの内部で、GitalyのRPCであるPostUploadPackやSSHUploadPackを介して間接的に呼び出されるものです。Gitalyは、ユーザーがHTTP経由でGitをフェッチしたときにPostUploadPackを実行し、ユーザーがSSH経由でGitをフェッチしたときにSSHUploadPackを実行します。キャッシュを有効にすると、PostUploadPackやSSHUploadPackを使うものはすべてその恩恵を受けることができます。とは直交します:

  • トランスポート (HTTP あるいは SSH)。
  • Git プロトコルのバージョン(v0 または v2)。
  • フルクローン、インクリメンタルフェッチ、シャロークローン、パーシャルクローンなど。

このキャッシュの長所は、同一のフェッチを同時に重複排除できることです。それは

  • GitLabインスタンスでユーザーがCI/CDパイプラインを実行し、多くのジョブを同時に実行している場合に役立ちます。サーバーのCPU使用率が顕著に減少するはずです。
  • ユニークなフェッチには全くメリットがありません。例えば、リポジトリをローカルにクローンして抜き打ちチェックを行う場合、フェッチはおそらく一意であるため、このキャッシュの恩恵は受けにくいでしょう。

pack-objectsキャッシュはローカルキャッシュです。これは

  • メタデータを、それが有効になっているGitalyプロセスのメモリに格納します。
  • キャッシュしている実際のGitデータをローカル・ストレージ上のファイルに保存します。

ローカルファイルを使うことで、オペレーションシステムが自動的に pack-objects キャッシュファイルの一部を RAM に保持し、高速化できるという利点があります。

pack-objectsキャッシュはディスクへの書き込みIOを大幅に増加させる可能性があるため、デフォルトではオフになっています。GitLab 15.11以降では、書き込み作業量は約50%減少していますが、キャッシュはデフォルトで無効のままです。

キャッシュの設定

これらの設定は pack-objects キャッシュで使用できます。それぞれの設定について、以下で詳しく説明します。

設定デフォルト説明
enabledfalseキャッシュをオンにします。オフの場合、Gitalyは各リクエストに対して専用のgit pack-objects プロセスを実行します。
dir<PATH TO FIRST STORAGE>/+gitaly/PackObjectsCacheキャッシュファイルが保存されるローカルディレクトリ。
max_age 5m (5分)これより古いキャッシュ・エントリーはディスクから削除されます。
min_occurrences1キャッシュ・エントリが作成される前にキーが発生する最小回数。

/etc/gitlab/gitlab.rb で設定します:

gitaly['configuration'] = {
  # ...
  pack_objects_cache: {
    # ...
    enabled: true,
    # dir: '/var/opt/gitlab/git-data/repositories/+gitaly/PackObjectsCache',
    # max_age: '5m',
    # min_occurrences: 1,
  },
}

enabled のデフォルトはfalse

キャッシュがデフォルトで無効になっているのは、場合によってはディスクへの書き込みバイト数が極端に増えることがあるからです。GitLab.comでは、リポジトリストレージのディスクがこの余分な作業負荷を処理できることを確認していますが、どこでもそうだと決めつけることはできないと考えました。

キャッシュストレージディレクトリdir

キャッシュはファイルを保存するディレクトリが必要です。このディレクトリは

  • 十分なスペースのあるファイル・システム。キャッシュ・ファイル・システムの容量が不足すると、すべてのフェッチが失敗します。
  • 十分な IO 帯域幅のあるディスク。キャッシュ・ディスクのIO帯域幅が不足すると、すべてのフェッチ、そしておそらくサーバ全体が遅くなります。

デフォルトでは、キャッシュストレージディレクトリは、設定ファイルで定義された最初のGitalyストレージのサブディレクトリに設定されます。

複数のGitalyプロセスが同じディレクトリをキャッシュ・ストレージとして使用することができます。各Gitalyプロセスは、作成するキャッシュ・ファイル名の一部として、ユニークなランダム文字列を使用します。つまり

  • これらは衝突しません。
  • 他のプロセスのファイルを再利用することはありません。

デフォルトのディレクトリでは、リポジトリデータと同じファイルシステムにキャッシュファイルを置きますが、これは必須ではありません。インフラストラクチャに適していれば、キャッシュファイルを別のファイルシステムに置くこともできます。

ディスクに必要なIO帯域幅は、以下に依存します:

  • Gitalyサーバー上のリポジトリのサイズと形状。
  • ユーザーが生成するトラフィックの種類。

gitaly_pack_objects_generated_bytes_total 、キャッシュヒット率が0%であると仮定して、悲観的な見積もりとしてメトリクスを使用することができます。

必要なスペースは以下によって異なります:

  • ユーザーがキャッシュから引き出す1秒あたりのバイト数。
  • max_age キャッシュ退避ウィンドウのサイズ。

ユーザーが100 MB/sを引き出し、5分間のウィンドウを使用する場合、平均してキャッシュ・ディレクトリに5*60*100MB = 30GB 。この平均は予想される平均であり、保証ではありません。ピーク・サイズはこの平均を超える可能性があります。

キャッシュ消去ウィンドウmax_age

max_age 設定を使用すると、キャッシュ・ヒットの確率とキャッシュ・ファイルが使用するストレージの平均量を制御できます。max_age より古いエントリはディスクから削除されます。

消去は進行中のリクエストの邪魔をしません。max_age Unix ファイルシステムは、削除されたファイルを読んでいるすべてのプロセスがそのファイルを閉じるまで、ファイルを本当の意味で削除しないからです。

最小キー出現回数min_occurrences

GitLab 15.11 で導入

min_occurrences の設定は、新しいキャッシュエントリを作成する前に同じリクエストが何回発生するかを制御します。デフォルト値は1 で、ユニークなリクエストはキャッシュに書き込まれません。

もし

  • この数値を大きくすると、キャッシュのヒット率が下がり、キャッシュが使用するディスク容量が少なくなります。
  • この数値を下げると、キャッシュヒット率が上がり、キャッシュが使用するディスク容量が増えます。

min_occurrences1に設定するとよいでしょう。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パックファイルをクライアントに送り返すのにかかる合計時間(ms)クライアントのインターネット接続に大きく依存します。
pack_objects.written_object_countGitalyがクライアントに送り返すオブジェクトの総数。

の場合

  • キャッシュミスの場合、Gitalyはpack_objects_cache.generated_bytespack_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,
}

リポジトリの一貫性チェック

Gitalyはリポジトリの整合性チェックを行います:

  • リポジトリチェックをトリガーする場合。
  • ミラーされたリポジトリから変更が取得されたとき。
  • ユーザーがリポジトリに変更をプッシュしたとき。

これらの整合性チェックは、リポジトリに必要なオブジェクトがすべてあり、これらのオブジェクトが有効なオブジェクトであることを検証します。これらは次のように分類できます:

  • リポジトリが破損していないことを保証する基本的なチェック。これには、接続性チェックやオブジェクトが解析可能かどうかのチェックが含まれます。
  • Git の過去のセキュリティ関連のバグを悪用するのに適したオブジェクトを認識するセキュリティチェック。
  • すべてのオブジェクトのメタデータが有効であることを確認するための外観チェック。古いGitのバージョンや他のGitの実装では、無効なメタデータを持つオブジェクトが生成されることがあります。

一貫性チェックに失敗した不正なオブジェクトを削除するには、リポジトリの履歴を書き換える必要があります。そのため、Gitalyではデフォルトで、リポジトリの一貫性に悪影響を与えない、さまざまな外観上の問題に対する一貫性チェックを無効にしています。

Gitalyのデフォルトでは、Gitクライアントの既知の脆弱性を誘発するオブジェクトをディストリビューションしないように、基本的なチェックやセキュリティ関連のチェックは無効にしません。これは、プロジェクトに悪意がない場合でも、そのようなオブジェクトを含むリポジトリのインポートを制限します。

リポジトリの一貫性チェックの上書き

インスタンス管理者は、整合性チェックを通過しないリポジトリを処理する必要がある場合、整合性チェックをオーバーライドできます。

Linux パッケージインストールの場合、/etc/gitlab/gitlab.rb を編集し、以下のキーを設定します(この例では、hasDotgit 整合性チェックを無効にします):

  • GitLab 15.10以降の場合:

     ignored_blobs = "/etc/gitlab/instance_wide_ignored_git_blobs.txt"
       
     gitaly['configuration'] = {
       # ...
       git: {
         # ...
         config: [
           # Populate a file with one unabbreviated SHA-1 per line.
           # See https://git-scm.com/docs/git-config#Documentation/git-config.txt-fsckskipList
           { key: "fsck.skipList", value: ignored_blobs },
           { key: "fetch.fsck.skipList", value: ignored_blobs },
           { key: "receive.fsck.skipList", value: ignored_blobs },
       
           { key: "fsck.hasDotgit", value: "ignore" },
           { key: "fetch.fsck.hasDotgit", value: "ignore" },
           { key: "receive.fsck.hasDotgit", value: "ignore" },
           { key: "fsck.missingSpaceBeforeEmail", value: "ignore" },
         ],
       },
     }
    
  • GitLab 15.3からGitLab 15.9の場合:

     ignored_blobs = "/etc/gitlab/instance_wide_ignored_git_blobs.txt"
       
     gitaly['gitconfig'] = [
       
      # Populate a file with one unabbreviated SHA-1 per line.
      # See https://git-scm.com/docs/git-config#Documentation/git-config.txt-fsckskipList
      { key: "fsck.skipList", value: ignored_blobs },
      { key: "fetch.fsck.skipList", value: ignored_blobs },
      { key: "receive.fsck.skipList", value: ignored_blobs },
       
      { key: "fsck.hasDotgit", value: "ignore" },
      { key: "fetch.fsck.hasDotgit", value: "ignore" },
      { key: "receive.fsck.hasDotgit", value: "ignore" },
      { key: "fsck.missingSpaceBeforeEmail", value: "ignore" },
     ]
    
  • GitLab 15.2以前(レガシー方式)の場合:

     ignored_git_errors = [
       "hasDotgit = ignore",
       "missingSpaceBeforeEmail = ignore",
     ]
     omnibus_gitconfig['system'] = {
       
      # Populate a file with one unabbreviated SHA-1 per line.
      # See https://git-scm.com/docs/git-config#Documentation/git-config.txt-fsckskipList
       "fsck.skipList" => ignored_blobs
       "fetch.fsck.skipList" => ignored_blobs,
       "receive.fsck.skipList" => ignored_blobs,
       
       "fsck" => ignored_git_errors,
       "fetch.fsck" => ignored_git_errors,
       "receive.fsck" => ignored_git_errors,
     }
    

セルフコンパイルインストールの場合は、Gitaly設定(gitaly.toml)を編集して同等のことを行ってください:

[[git.config]]
key = "fsck.hasDotgit"
value = "ignore"

[[git.config]]
key = "fetch.fsck.hasDotgit"
value = "ignore"

[[git.config]]
key = "receive.fsck.hasDotgit"
value = "ignore"

[[git.config]]
key = "fsck.missingSpaceBeforeEmail"
value = "ignore"

[[git.config]]
key = "fetch.fsck.missingSpaceBeforeEmail"
value = "ignore"

[[git.config]]
key = "receive.fsck.missingSpaceBeforeEmail"
value = "ignore"

[[git.config]]
key = "fsck.skipList"
value = "/etc/gitlab/instance_wide_ignored_git_blobs.txt"

[[git.config]]
key = "fetch.fsck.skipList"
value = "/etc/gitlab/instance_wide_ignored_git_blobs.txt"

[[git.config]]
key = "receive.fsck.skipList"
value = "/etc/gitlab/instance_wide_ignored_git_blobs.txt"

GitLab UI のコミットに対するコミット署名の設定

  • GitLab 15.4で導入されました
  • GitLab 16.3 で導入された署名済み GitLab UI コミットのVerifiedバッジをgitaly_gpg_signingというフラグで表示。デフォルトでは無効。

フラグ: セルフマネジメントのGitLabでは、デフォルトではこの機能は利用できません。利用可能にするには、管理者がgitaly_gpg_signingという機能フラグを有効にします。GitLab.comでは、この機能は利用できません。

デフォルトでは、GitalyはGitLab UIを使って行われたコミットには署名しません。例えば

  • ウェブエディタ。
  • Web IDE.
  • マージリクエスト

GitLab UIで行ったコミットに署名するようにGitalyを設定できます。コミットは未検証で不明なユーザーによって署名されたと表示されます。改善のためのサポートはイシュー19185で提案されています。

GitLab UIで行ったコミットに署名するようにGitalyを設定するには、以下の2つの方法があります:

Linux package (Omnibus)
  1. GPGキーを作成してエクスポートするか、SSHキーを作成します。最適なパフォーマンスを得るには、EdDSA鍵を使用してください。

    GPG鍵をエクスポートします:

    gpg --export-secret-keys <ID> > signing_key.gpg
    

    またはSSHキー(パスフレーズなし)を作成します:

    ssh-keygen -t ed25519 -f signing_key.ssh
    
  2. Gitalyノード上で、鍵を/etc/gitlab/gitaly/ にコピーします。
  3. /etc/gitlab/gitlab.rb を編集し、gitaly['gpg_signing_key_path'] を設定します:

    gitaly['configuration'] = {
       # ...
       git: {
         # ...
         signing_key: '/etc/gitlab/gitaly/signing_key.gpg',
       },
    }
    
  4. ファイルを保存し、GitLabを再設定してください。
Self-compiled (source)
  1. GPGキーを作成してエクスポートするか、SSHキーを作成します。最適なパフォーマンスを得るには、EdDSA鍵を使用してください。

    GPG鍵をエクスポートします:

    gpg --export-secret-keys <ID> > signing_key.gpg
    

    またはSSHキー(パスフレーズなし)を作成します:

    ssh-keygen -t ed25519 -f signing_key.ssh
    
  2. Gitalyノード上で、鍵を/etc/gitlab にコピーします。
  3. /home/git/gitaly/config.toml を編集し、signing_key を設定します:

    [git]
    signing_key = "/etc/gitlab/gitaly/signing_key.gpg"
    
  4. ファイルを保存し、GitLabを再起動します。

外部コマンドを使った設定の生成

GitLab 15.11 で導入

外部コマンドを使って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つの方法があります:

Linux package (Omnibus)

/etc/gitlab/gitlab.rb を編集し、config_command を設定します:

gitaly['configuration'] = {
    config_command: '/path/to/config_command',
}
Self-compiled (source)

/home/git/gitaly/config.toml を編集し、config_command を設定します:

config_command = "/path/to/config_command"

設定後、Gitalyは起動時にコマンドを実行し、その標準出力をJSONとして解析します。設定結果は、他のGitalyの設定にマージされます。

Gitalyは、以下のどちらかの場合、起動に失敗します:

  • 設定コマンドに失敗した場合。
  • コマンドによって生成された出力は、有効な JSON として解析できません。

サーバー側バックアップの設定

GitLab 16.3 で導入されました

リポジトリのバックアップは、各リポジトリをホストするGitalyノードがバックアップの作成とオブジェクトストレージへのストリーミングを担当するように設定できます。これにより、バックアップの作成と復元に必要なネットワークリソースを削減することができます。

各Gitalyノードは、バックアップのためにオブジェクトストレージに接続するように設定する必要があります。

サーバー側バックアップの設定後、サーバー側リポジトリバックアップを作成することができます。

Azure Blobストレージの設定

バックアップ用のAzure Blobストレージをどのように設定するかは、インストールの種類によって異なります。セルフコンパイルインストールの場合、GitLabの外部でAZURE_STORAGE_ACCOUNTAZURE_STORAGE_KEY 環境変数を設定する必要があります。

Linux package (Omnibus)

/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://gitaly-backups'
    }
}
Self-compiled (source)

/home/git/gitaly/config.toml を編集し、go_cloud_url を設定します:

[backup]
go_cloud_url = "azblob://gitaly-backups"

Googleクラウドストレージの設定

Google Cloud storage(GCP) は、アプリケーションデフォルト認証情報を使用して認証を行います。各Gitalyサーバーにアプリケーションデフォルト認証情報を設定します:

  • gcloud auth application-default login コマンド。
  • GOOGLE_APPLICATION_CREDENTIALS 環境変数。セルフコンパイルでインストールする場合は、GitLabの外で環境変数を設定してください。

詳しくは、アプリケーションのデフォルト認証情報をご覧ください。

保存先バケットはgo_cloud_url オプションで設定します。

Linux package (Omnibus)

/etc/gitlab/gitlab.rb を編集し、go_cloud_url を設定します:

gitaly['env'] = {
    'GOOGLE_APPLICATION_CREDENTIALS' => '/path/to/service.json'
}
gitaly['configuration'] = {
    backup: {
        go_cloud_url: 'gs://gitaly-backups'
    }
}
Self-compiled (source)

/home/git/gitaly/config.toml を編集し、go_cloud_url を設定します:

[backup]
go_cloud_url = "gs://gitaly-backups"

S3ストレージの設定

S3ストレージの認証を設定します:

  • AWS CLIで認証する場合は、デフォルトのAWSセッションを使用できます。
  • そうでなければ、AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 環境変数を使うことができます。セルフコンパイルでインストールする場合は、GitLabの外で環境変数を設定してください。

詳細については、AWS Session ドキュメントを参照してください。

デスティネーションバケットとリージョンはgo_cloud_url オプションを使って設定します。

Linux package (Omnibus)

/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://gitaly-backups?region=us-west-1'
    }
}
Self-compiled (source)

/home/git/gitaly/config.toml を編集し、go_cloud_url を設定します:

[backup]
go_cloud_url = "s3://gitaly-backups?region=us-west-1"

S3対応サーバの設定

MinIOのようなS3互換サーバーは、endpoint パラメータを追加して、S3と同様に設定します。

以下のパラメータがサポートされています。

  • region:AWS リージョン。
  • endpoint:エンドポイント URL。
  • disabledSSL:値がtrue の場合、SSL は無効になります。
  • s3ForcePathStyle:true の値はパススタイルのアドレスを強制します。
Linux package (Omnibus)

/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://gitaly-backups?region=minio&endpoint=my.minio.local:8080&disableSSL=true&s3ForcePathStyle=true'
    }
}
Self-compiled (source)

/home/git/gitaly/config.toml を編集し、go_cloud_url を設定します:

[backup]
go_cloud_url = "s3://gitaly-backups?region=minio&endpoint=my.minio.local:8080&disableSSL=true&s3ForcePathStyle=true"