一台 Linux 机器加入 VPN,挂载一个远程 NFS 导出,再把该挂载提供给另一组客户端。这种安排 看起来像是多了几步的路由,而这是第一个错误假设。中间机器既是上游服务器的客户端,又是下游客户端的服务器,并同时参与这两种文件服务关系。数据包转发对文件句柄、锁定或文件系统身份没有任何主张;再导出则不然。

先问一个问题:下游客户端能否直接访问原始服务器。如果能,中间机器就是可选的。

三种模型,三种一致性叙事

直接挂载最简单:每个客户端通过隧道挂载原始服务器,由该服务器的导出策略管控访问。再导出是中间机器呈现不同的服务边界,当面向客户端的网络不应直接访问服务器时,这很有用。复制是第三种模型,它把问题从一致性转向同步与冲突解决。

不要把复制副本描述成实时的再导出。两者的故障模式不同,期待每次操作都抵达原始文件系统的用户,会在链路中断时感到意外。

身份比挂载命令活得更久

再导出需要显式的文件系统 ID,而该身份必须在重启和配置重建后依然成立。内核文档对此要求写得很清楚。它还警告:crossmnt并不能免除用各自 ID 导出子文件系统的必要。对用户看起来连续的目录树,可能跨越多个文件系统边界。当前的 nfs-utils 可以为受支持的配置自动分配 ID,一旦这样做,其数据库就成了网关状态的一部分。请把这些 ID 当作服务身份,而不是可丢弃的文件。

文件句柄是另一条身份边界:再导出包装原始句柄,使其更大,并可能超出客户端的限制。挂载成功并不能证明每种导出布局都兼容。

并非每项 NFS 功能都能穿过中间机器

内核的再导出指南指出,再导出的服务器不支持锁定或委托请求。依赖这些操作的应用程序需要另一条路径,或一套针对它们验证过的设计。挂载成功和可用的目录列表,并不能说明应用程序的真实操作可用。

用户身份与导出策略在每一跳上都很重要。VPN 登录证明某个网络参与者通过了认证;它并不授权 NFS 用户,也不会把客户端凭据传过网关。

网关有两个上游依赖

网关依赖 VPN 完成上游挂载,又依赖上游服务器提供文件系统本身。仍在运行的本地导出进程无法让不可用的存储恢复健康。要规划启动顺序、重连行为和服务器重启,包括客户端已持有的文件句柄会怎样。通过网关挂载后丢失句柄的客户端需要重新挂载,这是运维事件,而不是透明的恢复。

如果需求自始至终只需要私有 IP 可达性,那么直接路由到原始服务器是更简单的架构。再导出的存在应当有一个经得起写下来的理由。

测试工作负载,而不是挂载

在受控环境中演练真实的文件工作负载:应用程序执行的操作、使用的文件大小以及预期的并发度。关注功能缺口,而不只是传输错误。然后记录你选择了哪种模型以及原因,否则下一个人会默认网关就是路由器。

再导出在有明确理由时是合理的,例如隔离的客户端网络或受控的版本边界。它若只是意外产物就很糟糕,区别在于是否有人做过决定。

相关文章