# NFS

> 原文：[https://docs.gitlab.com/ee/administration/high_availability/nfs.html](https://docs.gitlab.com/ee/administration/high_availability/nfs.html)

*   [Known kernel version incompatibilities](#known-kernel-version-incompatibilities)
*   [NFS Server features](#nfs-server-features)
    *   [Required features](#required-features)
    *   [Recommended options](#recommended-options)
    *   [Disable NFS server delegation](#disable-nfs-server-delegation)
        *   [Important notes](#important-notes)
    *   [Improving NFS performance with GitLab](#improving-nfs-performance-with-gitlab)
        *   [Improving NFS performance with Unicorn](#improving-nfs-performance-with-unicorn)
        *   [Improving NFS performance with Puma](#improving-nfs-performance-with-puma)
    *   [Known issues](#known-issues)
        *   [Avoid using AWS’s Elastic File System (EFS)](#avoid-using-awss-elastic-file-system-efs)
        *   [Avoid using CephFS and GlusterFS](#avoid-using-cephfs-and-glusterfs)
        *   [Avoid using PostgreSQL with NFS](#avoid-using-postgresql-with-nfs)
*   [NFS Client mount options](#nfs-client-mount-options)
    *   [soft mount option](#soft-mount-option)
*   [A single NFS mount](#a-single-nfs-mount)
*   [Bind mounts](#bind-mounts)
*   [Multiple NFS mounts](#multiple-nfs-mounts)

# NFS[](#nfs "Permalink")

您可以通过运行`nfsstat -m`和`cat /etc/fstab`来查看每个已安装的 NFS 文件系统的信息和选项集.

**注意：**从 GitLab 13.0 开始，不建议将 NFS 用于 Git 存储库. 在 GitLab 14.0 中，计划删除对 Nit for Git 存储库的支持. 尽快升级到[Gitaly Cluster](../gitaly/praefect.html) .**注意：**文件系统的性能对整体 GitLab 的性能有很大的影响，特别是对于读取或写入 Git 存储库的操作. 有关测试文件系统性能的步骤，请参见[文件系统性能基准](../operations/filesystem_benchmarking.html)测试.

## Known kernel version incompatibilities[](#known-kernel-version-incompatibilities "Permalink")

RedHat Enterprise Linux（RHEL）和 CentOS v7.7 和 v7.8 附带了内核版本`3.10.0-1127` ，该版本[包含一个错误](https://bugzilla.redhat.com/show_bug.cgi?id=1783554) ， [该错误](https://bugzilla.redhat.com/show_bug.cgi?id=1783554)会导致[上传无法通过 NFS 复制](https://gitlab.com/gitlab-org/gitlab/-/issues/218999) . 以下 GitLab 版本包含一个可与该内核版本一起正常使用的修复程序：

1.  [12.10.12](https://about.gitlab.com/releases/2020/06/25/gitlab-12-10-12-released/)
2.  [13.0.7](https://about.gitlab.com/releases/2020/06/25/gitlab-13-0-7-released/)
3.  [13.1.1](https://about.gitlab.com/releases/2020/06/24/gitlab-13-1-1-released/)
4.  13.2 以上

如果使用的是该内核版本，请确保升级 GitLab 以避免错误.

## NFS Server features[](#nfs-server-features "Permalink")

### Required features[](#required-features "Permalink")

**文件锁定** ：GitLab **需要**咨询性文件锁定，只有 NFS 版本 4 才支持该功能.只要使用 Linux Kernel 2.6.5 +，NFSv3 还支持锁定. 我们建议使用版本 4，并且不要专门测试 NFSv3.

### Recommended options[](#recommended-options "Permalink")

定义 NFS 导出时，建议您还添加以下选项：

*   `no_root_squash` -NFS 通常将`root`用户更改为`nobody` . 当许多不同的用户将访问 NFS 共享时，这是一个很好的安全措施. 但是，在这种情况下，只有 GitLab 会使用 NFS 共享，因此很安全. GitLab 建议使用`no_root_squash`设置，因为我们需要自动管理文件权限. 如果没有该设置，则当 Omnibus 软件包尝试更改权限时，您可能会收到错误消息. 请注意，GitLab 和其他捆绑组件**不是**以`root`用户身份运行，而是以非特权用户身份运行. 对于`no_root_squash`的建议是允许 Omnibus 软件包根据需要设置文件的所有权和权限. 在`no_root_squash`选项不可用的某些情况下， `root`标志可以实现相同的结果.
*   `sync`强制同步行为. 默认值是异步的，在某些情况下，如果在同步数据之前发生故障，则可能导致数据丢失.

由于使用 LDAP 运行 Omnibus 的复杂性和不使用 LDAP 维护 ID 映射的复杂性，在大多数情况下，应启用数字 UID 和 GID（在某些情况下默认情况下处于禁用状态），以简化系统之间的权限管理：

*   [NetApp instructions](https://library.netapp.com/ecmdocs/ECMP1401220/html/GUID-24367A9F-E17B-4725-ADC1-02D86F56F78E.html)
*   对于非 NetApp 设备，请执行与[启用 NFSv4 idmapper](https://wiki.archlinux.org/index.php/NFS#Enabling_NFSv4_idmapping)相反的`idmapping`来禁用[NFSv4 idmapping](https://wiki.archlinux.org/index.php/NFS#Enabling_NFSv4_idmapping)

### Disable NFS server delegation[](#disable-nfs-server-delegation "Permalink")

我们建议所有 NFS 用户禁用 NFS 服务器委派功能. 这是为了避免[Linux 内核错误](https://bugzilla.redhat.com/show_bug.cgi?id=1552203) ，该[错误](https://bugzilla.redhat.com/show_bug.cgi?id=1552203)会由于[来自大量`TEST_STATEID` NFS 消息的过多网络流量](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52017)而导致 NFS 客户端急剧减速.

要禁用 NFS 服务器委派，请执行以下操作：

1.  在 NFS 服务器上，运行：

    ```
    echo 0 > /proc/sys/fs/leases-enable
    sysctl -w fs.leases-enable=0 
    ```

2.  重新启动 NFS 服务器进程. 例如，在 CentOS 上运行`service nfs restart` .

#### Important notes[](#important-notes "Permalink")

[此提交](https://github.com/torvalds/linux/commit/95da1b3a5aded124dd1bda1e3cdb876184813140)可能会在[较新的内核中](https://github.com/torvalds/linux/commit/95da1b3a5aded124dd1bda1e3cdb876184813140)修复内核错误.

Red Hat Enterprise 7 于 2019 年 8 月 6 日[发布了内核更新](https://access.redhat.com/errata/RHSA-2019:2029) ， [该更新](https://access.redhat.com/errata/RHSA-2019:2029)也可能已解决了该问题.

如果您知道使用的是已修复的 Linux 内核版本，则可能不需要禁用 NFS 服务器委派. 也就是说，GitLab 仍然鼓励实例管理员保持 NFS 服务器委派禁用.

### Improving NFS performance with GitLab[](#improving-nfs-performance-with-gitlab "Permalink")

#### Improving NFS performance with Unicorn[](#improving-nfs-performance-with-unicorn "Permalink")

**注意：**从 GitLab 12.1 开始，如果可以并且应该为每个存储使用 Rugged，它将自动检测到它.

如果先前使用功能标记启用了 Rugged，则需要使用以下方法取消设置功能标记：

```
sudo gitlab-rake gitlab:features:unset_rugged 
```

如果将 Rugged 功能标志显式设置为 true 或 false，则 GitLab 将使用显式设置的值.

#### Improving NFS performance with Puma[](#improving-nfs-performance-with-puma "Permalink")

**注意：**从 GitLab 12.7 开始，如果 Puma 线程数大于 1，则将禁用 Rugged 自动检测.

如果要将 Rugged 与 Puma 一起使用，建议[将 Puma 线程数设置为 1](https://docs.gitlab.com/omnibus/settings/puma.html) .

如果您想使用 Rugged 且 Puma 线程数大于 1，则可以使用[功能标志](../../development/gitaly.html#legacy-rugged-code)启用 Rugged

如果将 Rugged 功能标志显式设置为 true 或 false，则 GitLab 将使用显式设置的值.

### Known issues[](#known-issues "Permalink")

#### Avoid using AWS’s Elastic File System (EFS)[](#avoid-using-awss-elastic-file-system-efs "Permalink")

GitLab 强烈建议您不要使用 AWS Elastic File System（EFS）. 我们的支持团队将无法协助解决与文件系统访问相关的性能问题.

客户和用户报告说，AWS EFS 在 GitLab 的用例中表现不佳. 以串行化方式写入许多小文件的工作负载（例如`git` ）不适合 EFS. 顶部带有 NFS 服务器的 EBS 的性能会好得多.

如果确实选择使用 EFS，请避免在其中存储 GitLab 日志文件（例如`/var/log/gitlab` ），因为这也会影响性能. 我们建议将日志文件存储在本地卷上.

有关其他人使用 EFS 的经验的更多详细信息，请参阅此[Commit Brooklyn 2019 视频](https://youtu.be/K6OS8WodRBQ?t=313) .

#### Avoid using CephFS and GlusterFS[](#avoid-using-cephfs-and-glusterfs "Permalink")

GitLab 强烈建议不要使用 CephFS 和 GlusterFS. 这些分布式文件系统不适用于 GitLab 的输入/输出访问模式，因为 Git 使用许多小文件，并且传播的访问时间和文件锁定时间会使 Git 活动非常缓慢.

#### Avoid using PostgreSQL with NFS[](#avoid-using-postgresql-with-nfs "Permalink")

GitLab 强烈建议不要跨 NFS 运行 PostgreSQL 数据库. GitLab 支持团队将无法协助解决与该配置有关的性能问题.

此外，该配置在[PostgreSQL 文档中](https://s0www0postgresql0org.icopy.site/docs/current/creating-cluster.html)特别警告：

> PostgreSQL does nothing special for NFS file systems, meaning it assumes NFS behaves exactly like locally-connected drives. If the client or server NFS implementation does not provide standard file system semantics, this can cause reliability problems. Specifically, delayed (asynchronous) writes to the NFS server can cause data corruption problems.

有关受支持的数据库体系结构，请参阅有关[为 GitLab HA 配置数据库的](../postgresql/replication_and_failover.html)文档.

## NFS Client mount options[](#nfs-client-mount-options "Permalink")

这是添加到`/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,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,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,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,lookupcache=positive 0 2
   10.1.0.1:/var/opt/gitlab/git-data /var/opt/gitlab/git-data nfs4 defaults,vers=4.1,hard,rsize=1048576,wsize=1048576,noatime,nofail,lookupcache=positive 0 2 
```

请注意，您应该考虑使用几个选项：

| Setting | Description |
| --- | --- |
| `vers=4.1` | 应该使用 NFS v4.1 代替 v4.0，因为 v4.0 中存在一个 Linux [NFS 客户端错误，](https://gitlab.com/gitlab-org/gitaly/-/issues/1339)由于过时的数据可能导致严重的问题. |
| `nofail` | 不要停止启动过程，等待此挂载可用 |
| `lookupcache=positive` | Tells the NFS client to honor `positive` cache results but invalidates any `negative` cache results. Negative cache results cause problems with Git. Specifically, a `git push` can fail to register uniformly across all NFS clients. The negative cache causes the clients to ‘remember’ that the files did not exist previously. |
| `hard` | 而不是`soft` . [进一步的细节](#soft-mount-option) . |

### soft mount option[](#soft-mount-option "Permalink")

我们建议您在安装选项中使用`hard` ，除非您出于特殊原因使用`soft` .

在 GitLab.com，我们使用`soft` ，因为有些时候我们不得不 NFS 服务器重新启动和`soft`改进的可用性，但每个人的基础不同. 例如，如果您的 NFS 由带有冗余控制器的本地存储阵列提供，则无需担心 NFS 服务器的可用性.

NFS 手册页指出：

> 在某些情况下，"软"超时可能会导致无提示数据损坏

阅读[Linux 手册页](https://linux.die.net/man/5/nfs)以了解它们之间的区别，如果您确实使用`soft` ，请确保已采取步骤减轻风险.

如果您遇到的问题可能是由于未发生对 NFS 服务器的磁盘写入而导致的，例如丢失了提交，请使用`hard`选项，因为（在手册页中）：

> 仅当客户端响应能力比数据完整性更重要时才使用 soft 选项

其他供应商也提出了类似的建议，包括[SAP](http://wiki.scn.sap.com/wiki/x/PARnFQ)和 NetApp 的[知识库](https://kb.netapp.com/Advice_and_Troubleshooting/Data_Storage_Software/ONTAP_OS/What_are_the_differences_between_hard_mount_and_soft_mount) ，他们强调说，如果 NFS 客户端驱动程序缓存数据，则`soft`意味着无法确定 GitLab 的写操作是否确实在磁盘上.

使用`hard`选项设置的安装点可能无法正常运行，并且如果 NFS 服务器关闭，则`hard`会导致与安装点进行交互时挂起进程. 使用`SIGKILL` （ `kill -9` ）处理挂起的进程. `intr`选项[在 2.6 内核中停止工作](https://access.redhat.com/solutions/157873) .

## A single NFS mount[](#a-single-nfs-mount "Permalink")

建议将所有 GitLab 数据目录嵌套在一个装载中，这样可以自动还原备份而无需手动移动现有数据.

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

为此，我们需要使用嵌套在安装点中的每个目录的路径来配置 Omnibus，如下所示：

然后挂载`/gitlab-nfs`使用以下 Omnibus 配置将每个数据位置移动到子目录：

```
git_data_dirs({"default" => { "path" => "/gitlab-nfs/gitlab-data/git-data"} })
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`以开始使用中心位置. 请注意，如果您已有数据，则需要手动将其复制/同步到这些新位置，然后重新启动 GitLab.

## Bind mounts[](#bind-mounts "Permalink")

除了更改 Omnibus 中的配置外，绑定挂载还可用于将数据存储在 NFS 挂载上.

绑定挂载提供一种仅指定一个 NFS 挂载，然后将默认的 GitLab 数据位置绑定到 NFS 挂载的方法. 首先定义您的单个 NFS 挂载点，就像通常在`/etc/fstab` . 假设您的 NFS 挂载点是`/gitlab-nfs` . 然后，在`/etc/fstab`添加以下绑定安装：

```
/gitlab-nfs/gitlab-data/git-data /var/opt/gitlab/git-data none bind 0 0
/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 
```

使用绑定安装将需要手动确保数据目录为空，然后再尝试还原. 阅读有关[还原先决条件的](../../raketasks/backup_restore.html)更多信息.

## Multiple NFS mounts[](#multiple-nfs-mounts "Permalink")

使用默认的 Omnibus 配置时，您将需要在所有 GitLab 群集节点之间共享 4 个数据位置. 没有其他位置可以共享. 以下是需要共享的四个位置：

| Location | Description | 默认配置 |
| --- | --- | --- |
| `/var/opt/gitlab/git-data` | Git 存储库数据. 这将占您数据的很大一部分 | `git_data_dirs({"default" => { "path" => "/var/opt/gitlab/git-data"} })` |
| `/var/opt/gitlab/gitlab-rails/uploads` | 用户上传的附件 | `gitlab_rails['uploads_directory'] = '/var/opt/gitlab/gitlab-rails/uploads'` |
| `/var/opt/gitlab/gitlab-rails/shared` | Build artifacts, GitLab Pages, LFS objects, temp files, etc. If you’re using LFS this may also account for a large portion of your data | `gitlab_rails['shared_path'] = '/var/opt/gitlab/gitlab-rails/shared'` |
| `/var/opt/gitlab/gitlab-ci/builds` | GitLab CI / CD 构建跟踪 | `gitlab_ci['builds_directory'] = '/var/opt/gitlab/gitlab-ci/builds'` |

其他 GitLab 目录不应在节点之间共享. 它们包含特定于节点的文件和不需要共享的 GitLab 代码. 要将日志发送到中央位置，请考虑使用远程 syslog. Omnibus GitLab 软件包提供了[UDP 日志传送的](https://docs.gitlab.com/omnibus/settings/logs.html)配置.

具有多个 NFS 挂载将需要手动确保数据目录为空，然后再尝试还原. 阅读有关[还原先决条件的](../../raketasks/backup_restore.html)更多信息.

* * *

阅读更多有关高可用性配置的信息：

1.  [Configure the database](../postgresql/replication_and_failover.html)
2.  [Configure Redis](redis.html)
3.  [Configure the GitLab application servers](gitlab.html)
4.  [Configure the load balancers](load_balancer.html)