{{< details >}}

  • Tier: 基础版, 专业版, 旗舰版
  • Offering: 私有化部署

{{< /details >}}

NFS 可以用作对象存储的替代方案,但由于性能原因,通常不推荐这样做。

对于像 LFS、Uploads 和 Artifacts 这样的数据对象,建议使用 对象存储服务 而不是 NFS,因为其性能更好。当取消使用 NFS 时,除了迁移到对象存储之外,还有其他步骤需要执行

NFS 不能用于存储库存储。

有关可用于测试文件系统性能的步骤,请参阅文件系统性能基准测试

快速查找授权的 SSH 密钥

快速 SSH 密钥查找 功能可以提高极狐GitLab 实例的性能,即使它们使用块存储。

快速 SSH 密钥查找authorized_keys(在 /var/opt/gitlab/.ssh 中)的替代方案,使用极狐GitLab 数据库。

NFS 增加了延迟,因此如果 /var/opt/gitlab 被移动到 NFS,建议使用快速查找。

我们正在研究将快速查找作为默认设置 的使用。

NFS 服务器

安装 nfs-kernel-server 软件包可以允许您与运行极狐GitLab 应用程序的客户端共享目录:

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

必需的功能

文件锁定:极狐GitLab 需要顾问文件锁定,这仅在 NFS 版本 4 中本机支持。只要使用 Linux Kernel 2.6.5+,NFSv3 也支持锁定。我们推荐使用版本 4,并且不专门测试 NFSv3。

推荐选项

在定义 NFS 导出时,我们建议您还添加以下选项:

  1. no_root_squash - NFS 通常会将 root 用户更改为 nobody。这是一个良好的安全措施,当 NFS 共享被许多不同用户访问时。然而,在这种情况下,只有极狐GitLab 使用 NFS 共享,因此是安全的。极狐GitLab 推荐使用 no_root_squash 设置,因为我们需要自动管理文件权限。如果没有设置,当 Linux 包尝试更改权限时可能会收到错误。极狐GitLab 和其他捆绑组件root 身份运行,而是以非特权用户身份运行。推荐使用 no_root_squash 是为了允许 Linux 包根据需要设置文件的所有权和权限。在某些情况下,如果 no_root_squash 选项不可用,可以使用 root 标志实现相同的结果。
  2. sync - 强制同步行为。默认是异步的,在某些情况下,如果在数据同步之前发生故障,可能会导致数据丢失。

由于使用 Linux 包的复杂性以及在没有 LDAP 的情况下维护 ID 映射的复杂性,在大多数情况下,您应该启用数字 UID 和 GID(在某些情况下默认关闭)以简化系统之间的权限管理:

  1. NetApp 指南
  2. 对于非 NetApp 设备,通过执行与启用 NFSv4 idmapper 相反的操作来禁用 NFSv4 idmapping

禁用 NFS 服务器委派

我们建议所有 NFS 用户禁用 NFS 服务器委派功能。这是为了避免一个已知的 Linux 内核错误,该错误导致由于大量 TEST_STATEID NFS 消息的过多网络流量而导致 NFS 客户端急剧变慢。

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

  1. 在 NFS 服务器上,运行:

    echo 0 > /proc/sys/fs/leases-enable
    sysctl -w fs.leases-enable=0
    
  2. 重启 NFS 服务器进程。例如,在 CentOS 上运行 service nfs restart

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.1 应使用 NFS v4.1 而不是 v4.0,因为在 v4.0 中存在一个 Linux NFS 客户端错误,可能由于陈旧数据导致严重问题。
nofail 不要在等待此挂载变得可用时中止启动过程。
lookupcache=positive 告诉 NFS 客户端承认 positive 缓存结果,但无效化任何 negative 缓存结果。负缓存结果会导致 Git 出现问题。具体来说,git push 可能无法在所有 NFS 客户端之间一致注册。负缓存导致客户端“记住”这些文件以前不存在。
hard 而不是 soft更多详情
cto cto 是默认选项,您应该使用它。不要使用 nocto更多详情
_netdev 等待挂载文件系统直到网络上线。另请参阅 high_availability['mountpoint'] 选项。

soft 挂载选项

建议在挂载选项中使用 hard,除非您有特定原因使用 soft

当 JihuLab.com 使用 NFS 时,我们使用 soft,因为有时我们需要重启 NFS 服务器,soft 提高了可用性,但每个人的基础设施都不同。例如,如果您的 NFS 是由具有冗余控制器的本地存储阵列提供的,您不必担心 NFS 服务器的可用性。

NFS 手册页指出:

“soft” 超时在某些情况下可能导致静默数据损坏

阅读 Linux 手册页以了解差异,如果您确实使用 soft,请确保已采取措施来缓解风险。

如果您遇到可能由 NFS 服务器上的磁盘写入未发生引起的行为,例如提交丢失,请使用 hard 选项,因为(来自手册页):

只有当客户端响应性比数据完整性更重要时才使用 soft 选项

其他供应商也有类似的建议,包括读写目录的推荐挂载选项和 NetApp 的知识库,他们强调如果 NFS 客户端驱动程序缓存数据,soft 意味着无法确定极狐GitLab 的写入是否实际上在磁盘上。

使用 hard 选项设置的挂载点可能性能不佳,如果 NFS 服务器宕机,hard 会导致在与挂载点交互时进程挂起。使用 SIGKILL (kill -9) 处理挂起的进程。intr 选项在 2.6 内核中停止工作。

nocto 挂载选项

不要使用 nocto。相反,使用 cto,这是默认设置。

使用 nocto 时,dentry 缓存始终使用,最多 acdirmax 秒(属性缓存时间)从创建时算起。

这会导致多个客户端的陈旧 dentry 缓存问题,其中每个客户端可以看到目录的不同(缓存)版本。

Linux 手册页 中,重要部分:

如果指定了 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 挂载上。

绑定挂载提供了一种仅指定一个 NFS 挂载的方法,然后将默认的极狐GitLab 数据位置绑定到 NFS 挂载。首先像通常那样在 /etc/fstab 中定义您的单个 NFS 挂载点。假设您的 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/builds 极狐GitLab 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 通信。

来自 The Linux Documentation Project (TDLP) 的指南涵盖了在防火墙环境中使用 NFS 的基础知识。此外,我们鼓励您搜索和查看您的操作系统或发行版以及防火墙软件的特定文档。

Ubuntu 示例:

通过运行命令 sudo ufw status 检查防火墙是否允许来自客户端的 NFS 流量。如果它被阻止,您可以使用以下命令允许来自特定客户端的流量。

sudo ufw allow from <client_ip_address> to any port nfs

已知问题

避免使用基于云的文件系统

极狐GitLab 强烈建议不要使用基于云的文件系统,如:

  • AWS 弹性文件系统 (EFS)。
  • Google Cloud Filestore。
  • Azure 文件。

我们的支持团队无法协助解决与基于云的文件系统访问相关的性能问题。

客户和用户报告说,这些文件系统在极狐GitLab 所需的文件系统访问方面表现不佳。许多小文件以串行方式写入的工作负载(如 git)不适合基于云的文件系统。

如果您选择使用这些,请避免将极狐GitLab 日志文件(例如 /var/log/gitlab 中的那些)存储在那里,因为这也会影响性能。我们建议将日志文件存储在本地卷上。

避免使用 CephFS 和 GlusterFS

极狐GitLab 强烈建议不要使用 CephFS 和 GlusterFS。这些分布式文件系统不适合极狐GitLab 的输入/输出访问模式,因为 Git 使用许多小文件,并且访问时间和文件锁定时间导致 Git 活动非常缓慢。

避免使用 PostgreSQL 与 NFS

极狐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)