Ceph RGW NFS:基于 NFS-Ganesha 与 librgw 的分布式对象存储文件访问实战指南
2026/9/23 15:42:49 网站建设 项目流程

Ceph RGW NFS:基于 NFS-Ganesha 与 librgw 的分布式对象存储文件访问实战指南

【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph

Ceph Object Gateway(RGW)在传统 S3/Swift HTTP 访问协议之外,提供了将对象存储命名空间通过 NFSv4 协议导出的能力:通过将 RGW 嵌入 NFS-Ganesha 服务器,用户可以像访问本地 POSIX 文件系统一样,用mount直接挂载 S3 桶与对象。本文以 doc/radosgw/nfs.rst 为骨架,结合仓库中 librgw 实现(rgw_lib.cc、rgw_file.cc)与配置定义(rgw.yaml.in),完整讲解命名空间映射规则、支持与限制、混合安全模型、ganesha.conf/ceph.conf 手工配置、NFSv3/NFSv4 客户端挂载以及常见故障排查,让你能在自己的集群上把 RGW 对象存储以文件系统形态交付给应用。

RGW NFS 概述:对象存储的文件访问入口

Ceph RGW 的命名空间可以通过 NFSv4 协议导出,与传统的 HTTP 访问协议(S3 和 Swift)并存。其核心思路是:Ceph Object Gateway 被嵌入到 NFS-Ganesha NFS 服务器中运行,由 Ganesha 负责对外提供标准 NFS 协议服务,由 RGW 负责把 NFS 的文件操作翻译成对 S3 桶和对象的操作。

需要注意:

  • 仅 NFSv4 协议在基于 cephadm 或 Rook 的部署中得到支持(文档原话:Only the NFSv4 protocol is supported when using a cephadm or Rook based deployment);
  • 管理和部署 NFS-Ganesha 集群与 RGW 导出(EXPORT)的最简单、推荐方式是使用ceph nfs ...系列命令,详见 Ceph Manager NFS 模块文档(doc/mgr/nfs.rst);
  • 本文后续的"手工配置"章节适用于理解底层原理、进行实验或非 cephadm/Rook 场景。

底层架构:librgw 与 rgw_file 文件访问 API

整个 RGW NFS 能力的基石是librgw库:

  • librgw提供一个可加载(loadable)的接口来访问 Ceph Object Gateway 服务,在初始化时实例化一个完整的 RGW 实例
  • librgw进一步导出rgw_file——一个面向文件的有状态 API,用于对 RGW 桶和对象进行文件化访问。该 API 具有通用性,但其设计深受 NFS-Ganesha 的文件系统抽象层(FSAL, File System Abstraction Layer)API 影响,最初就是为 FSAL 而设计的;
  • librgw同时提供一套 Python 绑定。

从源码看,librgw 的启动流程在 rgw_lib.cc 中通过RGWLib::init_frontends1(InstanceType::Library, protocol_type)init_frontends2()完成实例初始化与前端(frontend)装配;文件系统层的核心在 rgw_file.cc,其中RGWLibFS::write_completion_interval_s默认值为 10(秒),与配置项rgw_nfs_write_completion_interval_s对应。

Python 绑定定义于 src/pybind/rgw/rgw.pyx,它包装了librgw_t句柄,提供mountunmountcreatemkdirrenameunlinkreaddiropendiropenclosereadwritefsync等与文件操作一一对应的接口,可直接用 Python 对 RGW 命名空间做文件化访问。

命名空间约定:Unix 路径如何映射到 S3 桶与对象

RGW NFS 的实现遵循 AWS 分层命名空间(hierarchical namespace)约定,将 Unix 风格路径映射到 S3 桶和对象上:

  • 挂载命名空间的顶层是 S3 桶,在 NFS 中表现为目录;
  • 桶之下的文件和目录各自表示为对象,遵循 S3 的 prefix 与 delimiter 约定,/是唯一支持的路径分隔符;
  • 例如:NFS 客户端把 RGW 命名空间挂载到/nfs,则 NFS 命名空间中的文件/nfs/mybucket/www/index.html对应桶/容器mybucket中的 RGW 对象www/index.html

关于对象在存储中的物化规则(一般对客户端不可见):

  • NFS 命名空间通过拼接对象路径隐含的对应路径组装而成;
  • 叶子对象(文件或目录)总是被物化为对应的 RGW 对象:文件物化为键名<name>,目录物化为键名<name>/
  • 非叶子目录(如上面的www)可能仅由其出现在一个或多个叶子对象的名称中而隐含存在;
  • 在 NFS 内创建、或由 NFS 客户端直接操作(例如 chown、chmod 等属性设置操作)的目录,始终拥有一个叶子对象表示,用来存储物化后的属性(如 Unix 所有权与权限)。

支持的操作与限制

RGW NFS 接口支持对文件和目录的大多数操作,但有以下限制(务必在规划应用时评估):

限制说明
链接(含符号链接)不支持
NFS ACL不支持;但Unix 用户/组所有权与权限是支持的
目录移动/重命名不允许;文件可以在目录之间移动
写入 I/O仅支持完整、顺序的写入,即写操作被约束为"上传(uploads)"

顺序写入限制带来的实际影响:

  • 许多典型 I/O 操作(如原地编辑文件)必然失败,因为它们执行非顺序存储;
  • 一些看起来顺序写入的文件工具(例如某些版本的 GNU tar)可能因偶发的非顺序存储而失败;
  • 通过 NFS 挂载时,可通过同步挂载选项(Linux 上的-osync)把顺序应用 I/O 约束为顺序写往 NFS 服务器;
  • 无法同步挂载的 NFS 客户端(如 MS Windows)将无法上传文件

安全模型:NFS 协议安全 + RGW 凭据的混合模式

RGW NFS 接口采用混合安全模型,包含两层:

第一层:NFS 协议安全,由 NFS-Ganesha 服务器负责,按 NFS 服务器与客户端的协商结果执行:

  • 客户端可被信任(AUTH_SYS),或被要求出示 Kerberos 用户凭据(RPCSEC_GSS);
  • RPCSEC_GSS线缆安全可以是仅完整性(krb5i),或完整性加隐私/加密(krb5p);
  • 提供多种 NFS 特有的安全与权限规则,例如 root-squashing(root 压缩)。

第二层:RGW/S3 安全凭据,与每个 RGW NFS 挂载点(即 NFS-Ganesha EXPORT)关联:

  • 通过 NFS 服务器执行的所有 RGW 对象操作,都将以导出(export)中存储的凭据所对应的 RGW 用户身份执行;
  • 目前仅支持 RGW 凭据与 RGW LDAP 凭据;其他 RGW 认证类型(如 Keystone)当前不支持。

手工配置一个 NFS-Ganesha 实例

每个 RGW NFS 实例都是一个嵌入了完整 Ceph RGW 实例的 NFS-Ganesha 服务器实例。因此 RGW NFS 配置包含两部分:Ceph 与 Ceph Object Gateway 专属配置(本地ceph.conf),以及 NFS-Ganesha 专属配置(ganesha.conf)。

ceph.conf 配置要求

RGW NFS 必需的ceph.conf配置包括:

  • 有效的[client.rgw.{instance-name}]段;
  • 最小实例配置的有效取值,特别是已安装且正确keyring

其他配置变量(如rgw datargw backend store)是可选的。少数配置变量为 RGW NFS 独有(如rgw_nfs_namespace_expire_secs)。

前端(frontend)选择的特殊处理:前端选择由 librgw.so 运行时特殊处理。默认情况下只启动rgw-nfs前端;额外的前端(如beast)通过rgw nfs frontends配置项启用(其语法与普通rgw frontends选项一致,对应配置项rgw_nfs_frontends)。非默认前端的默认选项按常规通过rgw frontend defaults指定。

重要:HTTP 与 NFS 协议可以共存

当 RGW 以库实例(library instance)方式启动并服务 NFS 协议时,默认不会启动 HTTP 监听器。但 HTTP/S3 与 NFS 可以在同一实例中同时运行:通过rgw_nfs_frontends配置项添加额外的 HTTP 前端,即可在 NFS 之外同时启用 HTTP/S3 访问。

注意:原文档 "RGW vs RGW NFS" 一节同时指出,从同一程序实例同时导出 NFS 命名空间与其他 RGW 命名空间(如经 Civetweb HTTP 前端的 S3 或 Swift)"目前不受支持",这与上文的共存说明存在表述差异——共存能力以rgw_nfs_frontends配置为准,具体以你所使用版本的实现为准。

一份最简 ganesha.conf

一个严格最小化的、用于 RGW NFS 的ganesha.conf,包含一个 EXPORT 块与一个类型为 RGW 的内嵌 FSAL 块:

EXPORT { Export_ID={numeric-id}; Path = "/"; Pseudo = "/"; Access_Type = RW; SecType = "sys"; NFS_Protocols = 4; Transport_Protocols = TCP; # optional, permit unsquashed access by client "root" user #Squash = No_Root_Squash; FSAL { Name = RGW; User_Id = {s3-user-id}; Access_Key_Id ="{s3-access-key}"; Secret_Access_Key = "{s3-secret}"; } }

各字段含义:

字段含义
Export_ID必须是整数值,例如77
Path对 RGW 应为/
Pseudo定义 NFSv4 伪根(pseudo root)名称(仅 NFSv4)
SecType = "sys"允许客户端无需 Kerberos 认证即可挂载
Squash = No_Root_Squash允许客户端 root 用户覆盖权限(Unix 惯例)。启用 root-squashing 时,root 用户发起的操作将以 NFS-Ganesha 服务器本地的nobody(及nogroup)用户身份执行
FSALName = RGW指定文件系统抽象层;User_IdAccess_Key_IdSecret_Access_Key为与该导出关联的 S3 用户凭据(即上文"混合安全模型"中的第二层凭据)

RGW 专属配置段

RGW FSAL 还支持在 RGW 配置段中设置 RGW 专属配置变量:

RGW { cluster = "{cluster name, default 'ceph'}"; name = "client.rgw.{instance-name}"; ceph_conf = "/opt/ceph-rgw/etc/ceph/ceph.conf"; init_args = "-d --debug-rgw=16"; }
  • cluster:设置 Ceph 集群名(必须与所导出的集群一致);
  • name:设置 RGW 实例名(必须与所导出的集群一致,即 ceph.conf 中[client.rgw.{instance-name}]对应的实例名);
  • ceph_conf:给出非默认 ceph.conf 文件的路径。

init_args展示了初始化参数的使用方式——这里是开启前台运行与--debug-rgw=16的调试日志,实际调试时可调整日志级别。

RGW NFS 专属配置项速查

仓库 src/common/options/rgw.yaml.in 集中定义了 RGW NFS(及其他文件客户端)的调优参数,其中核心项如下:

配置项类型默认值说明
rgw_nfs_frontendsstrrgw-nfsRGW 以 librgw/NFS 方式运行时的前端配置;逗号分隔列表,每项为前端类型加可选的空格分隔key=value参数。可在此追加beast等 HTTP 前端实现 HTTP/NFS 共存
rgw_nfs_namespace_expire_secsint5_min(300 秒)NFS 命名空间刷新间隔:在 NFS 之外新增的对象/桶,将在此时间后出现在 NFS 命名空间;最小值 1
rgw_nfs_write_completion_interval_sint10NFSv3 场景下"最后写入后等待多久判定上传完成"的超时(秒)
rgw_nfs_lru_lanesint5NFS 对象缓存的 LRU lane 数
rgw_nfs_lru_lane_hiwatint911LRU lane 高水位
rgw_nfs_fhcache_partitionsint3文件句柄缓存分区数(分区哈希表,建议为小质数)
rgw_nfs_fhcache_sizeint2017每个分区的缓存大小(总缓存约为 分区数 × 大小)
rgw_nfs_max_gcint5_minGC 相关时间间隔
rgw_nfs_s3_fast_attrsboolfalse从 bucket index 使用快速 S3 属性(假定 NFS 挂载不可变)
rgw_nfs_run_gc_threadsboolfalse在 librgw 中运行 GC 线程(默认关闭)
rgw_nfs_run_lc_threadsboolfalse在 librgw 中运行 lifecycle 线程(默认关闭)
rgw_nfs_run_quota_threadsbooltrue在 librgw 中运行配额线程(默认开启)
rgw_nfs_run_restore_threadsboolfalse在 librgw 中运行对象恢复线程(默认关闭)
rgw_nfs_run_dedup_threadsboolfalse在 librgw 中运行去重线程(默认关闭)
rgw_nfs_run_sync_threadboolfalse在 librgw 中运行同步线程(默认关闭)

这些参数在 rgw_lib.cc 中被读取:rgw_nfs_write_completion_interval_srgw_nfs_namespace_expire_secs在初始化时被载入并用于文件系统的超时与刷新控制;rgw_file.cc 中的RGWLibFS则在命名空间过期(expire)与写完成判定逻辑中消费这两个配置。需要调整这些高级参数时,在 Ceph 配置文件的 RGW 段(如[client.rgw.{instance-name}])中设置即可。

其他有用的 NFS-Ganesha 配置

启用 NFSv3 与 UDP

任何需要支持 NFSv3 的 EXPORT 块都应在NFS_Protocols中包含版本 3。此外,NFSv3 是最后一个支持 UDP 传输的主要版本;要启用 UDP,把它加入Transport_Protocols。例如:

EXPORT { ... NFS_Protocols = 3,4; Transport_Protocols = UDP,TCP; ... }

Linux idmapper 集成

有一类重要选项与 Linux idmapping 服务相关,用于跨系统归一化用户与组名。本文档不展开 idmapper 集成细节,但提示:在使用 Linux NFS 客户端时,NFS-Ganesha 可以配置为接受客户端提供的数字用户与组标识符——而 NFSv4 默认会将其字符串化。这在小型实验环境很有用:

NFSV4 { Allow_Numeric_Owners = true; Only_Numeric_Owners = true; }

故障排查:NFS-Ganesha 日志配置

NFS-Ganesha 的配置问题通常通过以调试选项运行服务器来排查,由 LOG 配置段控制。NFS-Ganesha 日志消息按组件分组,可对每个组件单独开启日志。组件日志级别的合法取值:

  • FATAL:仅严重错误
  • WARN:异常情况
  • DEBUG:轻度冗长的跟踪输出
  • FULL_DEBUG:详细冗长的跟踪输出

示例(调试时把INITMAIN设为DEBUG,其余组件保持FATAL以减少噪音;还可通过Facility把日志重定向到文件):

LOG { Components { MEMLEAKS = FATAL; FSAL = FATAL; NFSPROTO = FATAL; NFS_V4 = FATAL; EXPORT = FATAL; FILEHANDLE = FATAL; DISPATCH = FATAL; CACHE_INODE = FATAL; CACHE_INODE_LRU = FATAL; HASHTABLE = FATAL; HASHTABLE_CACHE = FATAL; DUPREQ = FATAL; INIT = DEBUG; MAIN = DEBUG; IDMAPPER = FATAL; NFS_READDIR = FATAL; NFS_V4_LOCK = FATAL; CONFIG = FATAL; CLIENTID = FATAL; SESSIONS = FATAL; PNFS = FATAL; RW_LOCK = FATAL; NLM = FATAL; RPC = FATAL; NFS_CB = FATAL; THREAD = FATAL; NFS_V4_ACL = FATAL; STATE = FATAL; FSAL_UP = FATAL; DBUS = FATAL; } # optional: redirect log output # Facility { # name = FILE; # destination = "/tmp/ganesha-rgw.log"; # enable = active; # } }

调试完成后记得把INIT/MAIN等恢复为FATAL,避免生产环境日志膨胀。

运行多个 NFS 网关与扩展性

每个 NFS-Ganesha 实例都充当一个完整的网关端点,当前限制是一个 NFS-Ganesha 实例不能配置为导出 HTTP 服务。与普通网关实例一样,可以启动任意数量的 NFS-Ganesha 实例,导出集群中的相同或不同资源,从而实现对 NFS-Ganesha 实例的集群化(clustering)。

需要明确:集群化并不等于高可用(HA)。当普通网关实例与 NFS-Ganesha 实例覆盖同一数据资源时,这些资源将既能通过标准 S3 API 访问,也能通过导出的 NFS-Ganesha 实例访问。可以将 NFS-Ganesha 实例与 Ceph Object Gateway 实例共置在同一主机上。

RGW 与 RGW NFS 的互操作注意事项

  • 从同一程序实例同时导出 NFS 命名空间与其他 RGW 命名空间(如经 HTTP 前端的 S3/Swift)目前不被支持(见上文"HTTP 与 NFS 共存"说明);
  • 在 NFS 之外新增对象与桶时,这些对象将在rgw_nfs_namespace_expire_secs设定的时间后出现在 NFS 命名空间中,默认 300 秒(5 分钟)。在 Ceph 配置文件中覆盖该默认值即可改变刷新频率;
  • 如果导出的 Swift 容器不符合合法 S3 桶命名要求,需在 Ceph 配置文件的[client.rgw]段设置rgw_relaxed_s3_bucket_names为 true。例如:Swift 容器名包含下划线就不是合法的 S3 桶名,除非设置rgw_relaxed_s3_bucket_names为 true,否则会被拒绝。

配置 NFSv4 客户端

要访问命名空间,把配置好的 NFS-Ganesha 导出挂载到本地 POSIX 命名空间的期望位置即可。本实现有几个独特限制需要注意:

  • 优先使用 NFS 4.1 及更高版本的协议风格——RGW NFS 用 NFSv4 的 OPEN 与 CLOSE 操作来跟踪上传事务;
  • 要成功上传数据,客户端必须保持写顺序——在 Linux 及多数 Unix NFS 客户端上,使用-osync挂载选项。

挂载 NFS 资源的约定因平台而异,以下约定适用于 Linux 及部分 Unix 平台。

命令行挂载:

mount -t nfs -o nfsvers=4.1,noauto,soft,sync,proto=tcp <ganesha-host-name>:/ <mount-point>

写入/etc/fstab

<ganesha-host-name>:/ <mount-point> nfs noauto,soft,nfsvers=4.1,sync,proto=tcp 0 0

其中<ganesha-host-name>为 NFS-Ganesha 主机名,<mount-point>为客户端上的挂载点路径。nfsvers=4.1强制使用 4.1 及以上协议,sync保证写入顺序,proto=tcp指定 TCP 传输。

配置 NFSv3 客户端

Linux 客户端可通过提供nfsvers=3noacl挂载选项以 NFSv3 挂载。要使用 UDP 传输,在挂载选项中追加proto=udp;但TCP 是首选传输

<ganesha-host-name>:/ <mount-point> nfs noauto,noacl,soft,nfsvers=3,sync,proto=tcp 0 0

若挂载使用版本 3 加 UDP,需要在 NFS-Ganesha 的 EXPORT 块中将Protocols设置为版本 3、Transports设置为 UDP(参考上文"启用 NFSv3 与 UDP")。

NFSv3 语义:上传事务的判定方式

由于 NFSv3 不会向文件服务器传递客户端的 OPEN 与 CLOSE 操作,RGW NFS 无法用这些操作标记文件上传事务的开始与结束。取而代之:

  • 第一个写请求以偏移量 0 写入文件时,RGW NFS 开始一次新的上传;
  • 一段时间内没有对该文件的新写入时,上传被判定完成,默认超时为10 秒
  • 要修改此超时,在 Ceph 配置文件的 RGW 段中为rgw_nfs_write_completion_interval_s设置其他值。

这正是"仅支持完整顺序写入"限制在 NFSv3 下的体现:非顺序、中断式的写入可能被判定为多次上传或直接失败。

Python 绑定:用脚本做文件化访问

除 NFS 客户端外,librgw提供的 Python 绑定(src/pybind/rgw/rgw.pyx 中的LibRGWFS类)可让脚本直接以文件 API 操作 RGW 命名空间。LibRGWFS在构造时通过librgw_create实例化集群句柄,随后提供mount/unmountcreatemkdirrenameunlinkopendirreaddiropenclosereadwritefsyncfstatstatfsversion等方法——接口设计同样源自 FSAL 风格,适合在集成测试或工具链中以编程方式验证 RGW NFS 行为。

深入阅读路径

  • RGW NFS 官方文档:doc/radosgw/nfs.rst
  • 通过ceph nfs命令管理 NFS-Ganesha 集群与导出:doc/mgr/nfs.rst
  • librgw 实例初始化与前端装配:src/rgw/rgw_lib.cc
  • RGW 文件系统层(RGWLibFS、命名空间过期与写完成判定):src/rgw/rgw_file.cc
  • 全部 RGW NFS 配置项定义与默认值:src/common/options/rgw.yaml.in
  • librgw Python 绑定:src/pybind/rgw/rgw.pyx

【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询