正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

GitLabでのNFSの使用

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab Self-Managed

NFSはオブジェクトストレージの代替として使用できますが、通常、パフォーマンス上の理由から推奨されません。

LFS、アップロード、アーティファクトなどのデータオブジェクトの場合、可能な限り、パフォーマンスが向上するため、NFSよりもObject Storage serviceが推奨されます。NFSの使用をなくす場合は、オブジェクトストレージに移行するだけでなく、追加の手順を実行する必要があります。

NFSはリポジトリストレージには使用できません。

ファイルシステムのパフォーマンスをテストするために使用できる手順については、ファイルシステムのパフォーマンスベンチマークを参照してください。

承認されたSSHキーの高速検索

高速SSHキー検索機能を使用すると、ブロックストレージを使用している場合でも、GitLabインスタンスのパフォーマンスを向上させることができます。

高速SSHキー検索は、GitLabデータベースを使用するauthorized_keys/var/opt/gitlab/.ssh内)の代替です。

NFSはレイテンシーを増加させるため、/var/opt/gitlabをNFSに移動する場合は、高速検索をお勧めします。

現在、デフォルトとしての高速検索の使用を検討しています。

NFSサーバー

nfs-kernel-serverパッケージをインストールすると、GitLabアプリケーションを実行しているクライアントとディレクトリを共有できます:

sudo apt-get update
sudo apt-get install nfs-kernel-server

必要な機能

ファイルロッキング: GitLabでは、アドバイザリファイルのロックが必要です。これはNFSバージョン4でのみネイティブでサポートされています。NFSv3は、Linuxカーネル2.6.5以降を使用している限り、ロックもサポートしています。バージョン4を使用することをお勧めしますが、NFSv3は特にテストしていません。

NFSエクスポートを定義するときは、次のオプションも追加することをお勧めします:

  • no_root_squash - NFSは通常、rootユーザーをnobodyに変更します。これは、NFS共有が多くの異なるユーザーによってアクセスされる場合の優れたセキュリティ対策です。ただし、この場合、GitLabのみがNFS共有を使用するため、安全です。GitLabは、ファイル権限を自動的に管理する必要があるため、no_root_squash設定をお勧めします。この設定がないと、Linuxパッケージが権限を変更しようとしたときにエラーが発生する可能性があります。GitLabおよびその他のバンドルされたコンポーネントは、rootとしてではなく、特権のないユーザーとして実行されませんno_root_squashの推奨事項は、必要に応じて、Linuxパッケージがファイルの所有権と権限を設定できるようにすることです。no_root_squashオプションが使用できない場合、rootフラグで同じ結果を得ることができます。
  • sync - 同期動作を強制します。デフォルトは非同期であり、特定の状況下では、データが同期される前に障害が発生した場合、データ損失につながる可能性があります。

LinuxパッケージをLDAPで実行することの複雑さと、LDAPなしでIDマッピングを維持することの複雑さにより、ほとんどの場合、システム間の権限管理を簡素化するために、数値UIDとGIDを有効にする必要があります(場合によってはデフォルトでオフになっています):

NFSサーバー委任を無効にする

すべてのNFSユーザーがNFSサーバー委任機能を無効にすることをお勧めします。これは、多数のTEST_STATEID NFSメッセージからの過剰なネットワーキングトラフィックが原因で、NFSクライアントの速度が急激に低下するLinuxカーネルのバグを回避するためです。

NFSサーバーの委任を無効にするには、次の手順を実行します:

  1. NFSサーバーで、次を実行します:

    echo 0 > /proc/sys/fs/leases-enable
    sysctl -w fs.leases-enable=0
  2. NFSサーバープロセスを再起動します。たとえば、CentOSでservice nfs restartを実行します。

カーネルのバグは、このコミットを含むより新しいカーネルで修正されている可能性があります。Red Hat Enterprise 7は、この問題も解決している可能性のある、2019年8月6日にカーネルアップデートをリリースしました。修正されたLinuxカーネルのバージョンを使用していることがわかっている場合は、NFSサーバーの委任を無効にする必要はない場合があります。そうは言っても、GitLabは、インスタンスの管理者がNFSサーバーの委任を無効にしておくことを引き続き推奨しています。

NFSクライアント

nfs-commonは、アプリケーションノードで実行する必要のないサーバーコンポーネントをインストールせずに、NFS機能を提供します。

apt-get update
apt-get install nfs-common

マウントオプション

/etc/fstabに追加するスニペットの例を次に示します:

10.1.0.1:/var/opt/gitlab/.ssh /var/opt/gitlab/.ssh nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
10.1.0.1:/var/opt/gitlab/gitlab-rails/uploads /var/opt/gitlab/gitlab-rails/uploads nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
10.1.0.1:/var/opt/gitlab/gitlab-rails/shared /var/opt/gitlab/gitlab-rails/shared nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2
10.1.0.1:/var/opt/gitlab/gitlab-ci/builds /var/opt/gitlab/gitlab-ci/builds nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive 0 2

nfsstat -mcat /etc/fstabを実行して、マウントされた各NFSファイルシステムに設定された情報とオプションを表示できます。

使用を検討する必要があるオプションがいくつかあります:

設定説明
vers=4.1v4.0には、古いデータが原因で重大な問題を引き起こす可能性のあるLinux NFSクライアントのバグがv4.0にあるため、NFS v4.1を使用する必要があります。
nofailこのマウントが使用可能になるのを待機しているブートプロセスを停止しないでください。
lookupcache=positiveNFSクライアントにpositiveキャッシュ結果を優先するように指示しますが、negativeキャッシュ結果は無効にします。ネガティブキャッシュの結果は、Gitで問題を引き起こします。具体的には、git pushは、すべてのNFSクライアント間で均一に登録できない場合があります。ネガティブキャッシュにより、クライアントはファイルが以前に存在しなかったことを「記憶」します。
hardsoftの代わりに。詳細
ctoctoはデフォルトのオプションであり、使用する必要があります。noctoは使用しないでください。詳細
_netdevネットワークがオンラインになるまで、ファイルシステムのマウントを待ちます。「high_availability['mountpoint']」オプションも参照してください。

softマウントオプション

softを使用する特定の理由がない限り、マウントオプションでhardを使用することをお勧めします。

GitLab.comがNFSを使用していたとき、NFSサーバーの再起動とsoft可用性が向上したことがあったため、softを使用しましたが、すべてのインフラストラクチャが異なります。たとえば、NFSが冗長コントローラーを備えたオンプレミスストレージ配列によって提供されている場合、NFSサーバーの可用性を心配する必要はありません。

NFSのmanレポートには、次のように記載されています:

“soft” タイムアウトは、特定の場合にサイレントデータ破損を引き起こす可能性があります

Linux manレポートを読んで違いを理解し、softを使用する場合は、リスクを軽減するための手順を講じていることを確認してください。

コミット終了など、NFSサーバーでのディスクへの書き込みが発生していないことが原因である可能性がある動作が発生した場合は、hardオプションを使用してください(manレポートから):

クライアントの応答性がデータの整合性よりも重要な場合にのみ、softオプションを使用してください

他のベンダーも同様の推奨事項を作成しています。読み取り/書き込みディレクトリに推奨されるマウントオプションやNetAppのナレッジベースなどです。softは、NFSクライアントドライバーがデータをキャッシュする場合、GitLabによる書き込みが実際にディスク上にあるかどうかは不明であることを意味することを強調しています。

オプションhardで設定されたマウントポイントは、パフォーマンスが低下する可能性があり、NFSサーバーがダウンすると、hardによってプロセスがハングアップし、マウントポイントとのやり取りが発生します。ハングしたプロセスを処理するには、SIGKILLkill -9)を使用します。intrオプションは2.6カーネルでは動作しなくなりました

noctoマウントオプション

noctoは使用しないでください。代わりに、デフォルトであるctoを使用してください。

noctoを使用すると、dentryキャッシュは、作成時から最大acdirmax秒(属性キャッシュ時間)まで常に使用されます。

これにより、複数のクライアントでdentryキャッシュの問題が発生し、各クライアントはディレクトリの異なる(キャッシュされた)バージョンを表示できます。

Linux manレポートからの重要な部分を次に示します:

noctoオプションが指定されている場合、クライアントは標準外のヒューリスティックを使用して、サーバー上のファイルがいつ変更されたかを判断します。

noctoオプションを使用すると、読み取り専用マウントのパフォーマンスが向上する可能性がありますが、サーバー上のデータがごくまれにしか変更されない場合にのみ使用する必要があります。

プッシュ後にrefsが見つからない]という問題でこの動作に気付きました。新しく追加された緩いrefsは、ローカルのdentryキャッシュを持つ別のクライアントで見つからないものと見なされる可能性があります(このイシューで説明されているとおり)。

単一のNFSマウント

既存のデータを手動で移動せずにバックアップを自動的に復元することができるように、すべてのGitLabデータディレクトリをマウント内にネストされた状態にすることをお勧めします。

mountpoint
└── gitlab-data
    ├── builds
    ├── shared
    └── uploads

これを行うには、マウントポイント内にネストされた各ディレクトリへのパスを使用して、Linuxパッケージを次のように設定します:

/gitlab-nfsをマウントし、次のLinuxパッケージの設定を使用して、各データの場所をサブディレクトリに移動します:

gitlab_rails['uploads_directory'] = '/gitlab-nfs/gitlab-data/uploads'
gitlab_rails['shared_path'] = '/gitlab-nfs/gitlab-data/shared'
gitlab_ci['builds_directory'] = '/gitlab-nfs/gitlab-data/builds'

sudo gitlab-ctl reconfigureを実行して、中心的な場所の使用を開始します。既存のデータがある場合は、これらの新しい場所に手動でコピーまたはrsyncしてから、GitLabを再起動する必要があることに注意してください。

バインドマウント

Linuxパッケージの設定を変更する代わりに、バインドマウントを使用して、NFSマウントにデータを保存できます。

バインドマウントは、1つのNFSマウントのみを指定し、デフォルトのGitLabデータロケーションをNFSマウントにバインドする方法を提供します。まず、通常行うように、単一のNFSマウントポイントを/etc/fstabで定義します。NFSマウントポイントが/gitlab-nfsであると仮定しましょう。次に、次のバインドマウントを/etc/fstabに追加します:

/gitlab-nfs/gitlab-data/.ssh /var/opt/gitlab/.ssh none bind 0 0
/gitlab-nfs/gitlab-data/uploads /var/opt/gitlab/gitlab-rails/uploads none bind 0 0
/gitlab-nfs/gitlab-data/shared /var/opt/gitlab/gitlab-rails/shared none bind 0 0
/gitlab-nfs/gitlab-data/builds /var/opt/gitlab/gitlab-ci/builds none bind 0 0

バインドマウントを使用するには、復元を試みる前に、データディレクトリが空であることを手動で確認する必要があります。復元の前提条件の詳細をお読みください。

複数のNFSマウント

デフォルトのLinuxパッケージの設定を使用する場合、すべてのGitLabクラスタリングノード間で3つのデータロケーションを共有する必要があります。他の場所は共有しないでください。共有する必要がある3つの場所を次に示します:

場所説明デフォルトの設定
/var/opt/gitlab/gitlab-rails/uploadsユーザーがアップロードした添付ファイルgitlab_rails['uploads_directory'] = '/var/opt/gitlab/gitlab-rails/uploads'
/var/opt/gitlab/gitlab-rails/sharedビルドアーティファクト、GitLab Pages、LFSオブジェクト、一時ファイルなどのオブジェクト。LFSを使用している場合、これはデータの大部分を占める可能性もありますgitlab_rails['shared_path'] = '/var/opt/gitlab/gitlab-rails/shared'
/var/opt/gitlab/gitlab-ci/buildsGitLab CI/CDビルドトレースgitlab_ci['builds_directory'] = '/var/opt/gitlab/gitlab-ci/builds'

他のGitLabディレクトリは、ノード間で共有しないでください。これらには、ノード固有のファイルと、共有する必要のないGitLabコードが含まれています。ログを中央の場所に送信するには、リモートsyslogの使用を検討してください。Linuxパッケージは、UDPログシッピングの設定を提供します。

複数のNFSマウントを使用するには、復元を試みる前に、データディレクトリが空であることを手動で確認する必要があります。復元の前提条件の詳細をお読みください。

NFSのテスト

NFSサーバーとクライアントをセットアップしたら、次のコマンドをテストして、NFSが正しく設定されていることを確認できます:

sudo mkdir /gitlab-nfs/test-dir
sudo chown git /gitlab-nfs/test-dir
sudo chgrp root /gitlab-nfs/test-dir
sudo chmod 0700 /gitlab-nfs/test-dir
sudo chgrp gitlab-www /gitlab-nfs/test-dir
sudo chmod 0751 /gitlab-nfs/test-dir
sudo chgrp git /gitlab-nfs/test-dir
sudo chmod 2770 /gitlab-nfs/test-dir
sudo chmod 2755 /gitlab-nfs/test-dir
sudo -u git mkdir /gitlab-nfs/test-dir/test2
sudo -u git chmod 2755 /gitlab-nfs/test-dir/test2
sudo ls -lah /gitlab-nfs/test-dir/test2
sudo -u git rm -r /gitlab-nfs/test-dir

Operation not permittedエラーが発生した場合は、NFSサーバーのエクスポートオプションを調査する必要があります。

ファイアウォール環境でのNFS

NFSサーバーとNFSクライアント間のトラフィックがファイアウォールによるポートフィルタリングの対象となる場合は、NFS通信を許可するようにそのファイアウォールを再設定する必要があります。

Linux Documentation Project(TDLP)のこのガイドでは、ファイアウォール環境でのNFSの使用の基本について説明します。さらに、オペレーティングシステムまたはディストリビューションおよびファイアウォールソフトウェアの特定のドキュメントを検索して確認することをお勧めします。

Ubuntuの例:

コマンドsudo ufw statusを実行して、ホスト上のファイアウォールでクライアントからのNFSトラフィックが許可されていることを確認します。ブロックされている場合は、次のコマンドを使用して、特定のクライアントからのトラフィックを許可できます。

sudo ufw allow from <client_ip_address> to any port nfs

既知の問題

クラウドベースのファイルシステムの使用を避ける

GitLabは、次のようなクラウドベースのファイルシステムの使用を強く推奨していません:

  • Amazon Elastic File System(EFS)。
  • Google Cloud Filestore。
  • Azure Files。

当社のサポートチームは、クラウドベースのファイルシステムアクセスに関連するパフォーマンスの問題を支援できません。

お客様とユーザーから、これらのファイルシステムは、GitLabが要求するファイルシステムアクセスに対して十分に機能しないというレポートが寄せられています。gitのように、多くの小さなファイルがシリアル化された方法で書き込まれるワークロードは、クラウドベースのファイルシステムには適していません。

これらを使用する場合は、GitLabログファイル(たとえば、/var/log/gitlabにあるログファイル)をそこに保存しないでください。パフォーマンスにも影響するためです。ログファイルはローカルボリュームに保存することをお勧めします。

GitLabでのクラウドベースのファイルシステムの使用経験の詳細については、このCommit Brooklyn 2019ビデオをご覧ください。

CephFSおよびGlusterFSの使用を避ける

GitLabは、CephFSおよびGlusterFSの使用を強く推奨していません。これらの分散ファイルシステムは、Gitが多くの小さなファイルを使用し、アクセス時間とファイルのロック時間が伝播するためにGitアクティビティーが非常に遅くなるため、GitLabの入力/出力アクセスパターンには適していません。

NFSでPostgreSQLデータベースを使用しないでください

GitLabは、NFS経由でPostgreSQLデータベースを実行することを強く推奨していません。GitLabサポートチームは、この設定に関連するパフォーマンスの問題を支援できません。

さらに、この設定は、PostgreSQLのドキュメントで特に警告されています:

PostgreSQLはNFSファイルシステムに対して特別なことは何もしません。つまり、NFSはローカル接続されたドライブとまったく同じように動作すると想定しています。クライアントまたはサーバーのNFS実装が標準のファイルシステムセマンティクスを提供しない場合、信頼性の問題が発生する可能性があります。具体的には、NFSサーバーへの遅延(非同期)書き込みは、データ破損の問題を引き起こす可能性があります。

サポートされているデータベースアーキテクチャについては、レプリケーションとフェイルオーバーのためにデータベースを設定するに関するドキュメントを参照してください。

トラブルシューティング

NFSに対して行われているリクエストの検索

NFS関連の問題が発生した場合は、perfを使用して行われているファイルシステムリクエストをトレーシングすると役立つ場合があります:

sudo perf trace -e 'nfs4:*' -p $(pgrep -fd ',' puma)

Ubuntu 16.04では、次を使用します:

sudo perf trace --no-syscalls --event 'nfs4:*' -p $(pgrep -fd ',' puma)