注意
本文档适用于 Ceph 的开发版本。
CephFS 和 RGW 通过 NFS 导出
可以使用 NFS-Ganesha NFS 服务器 通过 NFS 协议导出 CephFS 命名空间和 RGW 存储桶。
nfs 管理器模块提供了用于管理 CephFS 目录或 RGW 存储桶的 NFS 导出的通用接口。可以通过 CLI ceph nfs export ... 命令或通过仪表板来管理导出。
如果启用了 Cephadm 或 Rook 协调器,也可以自动管理 nfs-ganesha 守护程序的部署。如果两者都未在使用(例如,Ceph 通过像 Ansible 或 Puppet 这样的外部协调器部署),则必须手动部署 nfs-ganesha 守护程序;有关更多信息,请参阅 手动 Ganesha 部署。
注意
从 Ceph Pacific 开始,必须启用 nfs mgr 模块。
NFS 集群管理
创建 NFS Ganesha 集群
ceph nfs cluster create <cluster_id> [<placement>] [--ingress] [--virtual_ip <value>] [--ingress-mode {default|keepalive-only|haproxy-standard|haproxy-protocol}] [--port <int>]
这将为所有 NFS Ganesha 守护程序创建一个公共恢复池,创建基于 cluster_id 的新用户,以及一个公共 NFS Ganesha 配置 RADOS 对象。
注意
由于此命令还会使用 ceph-mgr 协调器模块(请参阅 协调器 CLI),例如 cephadm 或 rook,启动 NFS Ganesha 守护程序,因此必须至少启用一个此类模块才能使其工作。
目前,cephadm 部署的 NFS Ganesha 守护程序侦听标准端口。因此,每个主机上只会部署一个守护程序。
<cluster_id> 是一个任意字符串,用于标识此 NFS Ganesha 集群(例如,mynfs)。
<placement> 是一个可选字符串,表示哪些主机应运行 NFS Ganesha 守护程序容器,以及(可选)集群中 NFS Ganesha 守护程序的总数(如果您希望每个节点运行多个 NFS Ganesha 守护程序)。例如,以下 placement 字符串表示“在主机 host1 和 host2 上部署 NFS Ganesha 守护程序”(每个主机一个守护程序)
"host1,host2"
此 placement 规范表示在主机 host1 和 host2 上各部署一个 NFS Ganesha 守护程序(集群中总共有两个 NFS Ganesha 守护程序)
"2 host1,host2"
可以使用 --port <port> 将 NFS 部署到非默认端口 2049。
要部署具有高可用性前端(虚拟 IP 和负载均衡器)的 NFS,请添加 --ingress 标志并指定虚拟 IP 地址。这将部署 keepalived 和 haproxy 的组合,为 NFS 服务提供高可用性 NFS 前端。
注意
Ingress 实现尚未完成。启用 ingress 将部署多个 ganesha 实例并在它们之间平衡负载,但在 NFS 宽限期到期之前,主机故障不会立即导致 cephadm 部署替换守护程序。此高可用性功能预计将在 Quincy 版本(2022 年 3 月)完成。
有关更多详细信息,请参阅 守护程序 placement,但请记住,不支持通过 YAML 文件指定 placement。
NFS 守护程序和 ingress 服务的部署是异步的:命令返回时服务可能尚未完全启动。您可能需要检查这些服务是否成功启动并保持运行。使用 cephadm 协调时,这些命令会检查服务状态
ceph orch ls --service_name=nfs.<cluster_id>
ceph orch ls --service_name=ingress.nfs.<cluster_id>
Ingress
核心 nfs 服务将部署一个或多个 nfs-ganesha 守护程序,每个守护程序都将提供一个可用的 NFS 端点。每个 NFS 端点的 IP 将取决于 nfs-ganesha 守护程序部署在哪个主机上。默认情况下,守护程序是半随机放置的,但用户也可以显式控制守护程序的放置位置;请参阅 守护程序 placement。
使用 --ingress 创建集群时,还会部署一个 ingress 服务,为 NFS 服务器提供负载均衡和高可用性。虚拟 IP 用于提供一个已知、稳定的 NFS 端点,所有客户端都可以使用它进行挂载。Ceph 将处理 NFS 虚拟 IP 上的流量重定向到适当的后端 NFS 服务器的细节,并在 NFS 服务器发生故障时重新部署它们。
可以提供一个可选的 --ingress-mode 参数来选择如何配置 ingress 服务
设置
--ingress-mode keepalive-only会部署一个简化的 ingress 服务,它提供一个虚拟 IP,nfs 服务器直接绑定到该虚拟 IP,并省略任何形式的负载均衡或流量重定向。此设置将限制用户只能部署 1 个 nfs 守护程序,因为多个守护程序无法绑定到虚拟 IP 上的同一端口。设置
--ingress-mode haproxy-standard会部署一个完整的 ingress 服务,使用 HAProxy 和 keepalived 提供负载均衡和高可用性。客户端 IP 地址对于后端 NFS 服务器不可见,并且 NFS 导出的 IP 级别限制将不起作用。设置
--ingress-mode haproxy-protocol会部署一个完整的 ingress 服务,使用 HAProxy 和 keepalived 提供负载均衡和高可用性。客户端 IP 地址对于后端 NFS 服务器可见,并且 NFS 导出的 IP 级别限制可用。此模式需要 NFS Ganesha 版本 5.0 或更高版本。设置
--ingress-mode default等同于未按名称提供任何其他 ingress 模式。当未按名称指定任何其他 ingress 模式时,使用的默认 ingress 模式为haproxy-standard。
Ingress 可以添加到现有的 NFS 服务(例如,最初创建时没有 --ingress 标志的服务),并且基本 NFS 服务也可以在事后修改以包含非默认选项,方法是直接修改服务。有关更多信息,请参阅 高可用性 NFS。
显示 NFS 集群 IP
要检查 NFS 集群的 IP 端点,包括单个 NFS 守护程序的 IP 以及 ingress 服务的虚拟 IP(如果有),
ceph nfs cluster info [<cluster_id>]
注意
这不适用于 rook 后端。相反,使用 kubectl patch 命令公开端口,并使用 kubectl get services 命令获取端口详细信息
kubectl patch service -n rook-ceph -p '{"spec":{"type": "NodePort"}}' rook-ceph-nfs-<cluster-name>-<node-id>
kubectl get services -n rook-ceph rook-ceph-nfs-<cluster-name>-<node-id>
删除 NFS Ganesha 集群
ceph nfs cluster rm <cluster_id>
这将删除已部署的集群。
NFS 守护程序和 ingress 服务的删除是异步的:命令返回时服务可能尚未完全删除。您可能需要检查这些服务是否不再报告。使用 cephadm 协调时,这些命令会检查服务状态
ceph orch ls --service_name=nfs.<cluster_id>
ceph orch ls --service_name=ingress.nfs.<cluster_id>
更新 NFS 集群
为了修改集群参数(例如,端口或 placement),请使用协调器接口更新 NFS 服务规范。最安全的方法是导出当前规范,对其进行修改,然后重新应用它。例如,要修改 nfs.foo 服务,请运行以下形式的命令
ceph orch ls --service-name nfs.foo --export > nfs.foo.yaml
emacs nfs.foo.yaml
ceph orch apply -i nfs.foo.yaml
有关 NFS 服务规范的更多信息,请参阅 NFS 服务。
列出 NFS Ganesha 集群
ceph nfs cluster ls
这将列出已部署的集群。
设置自定义 NFS Ganesha 配置
ceph nfs cluster config set <cluster_id> -i <config_file>
通过此操作,nfs 集群将使用指定的配置,并且它将优先于默认配置块。
示例用例包括
更改日志级别。可以使用以下配置片段调整日志级别
LOG { COMPONENTS { ALL = FULL_DEBUG; } }
添加自定义导出块。
以下示例块创建了一个导出。此导出将不由
ceph nfs export接口管理EXPORT { Export_Id = 100; Transports = TCP; Path = /; Pseudo = /ceph/; Protocols = 4; Access_Type = RW; Attr_Expiration_Time = 0; Squash = None; FSAL { Name = CEPH; Filesystem = "filesystem name"; User_Id = "user id"; Secret_Access_Key = "secret key"; } }
注意
FSAL 块中指定的用户应具有适当的权限,以便 NFS-Ganesha 守护程序可以访问 ceph 集群。可以使用 auth get-or-create 按如下方式创建用户
ceph auth get-or-create client.<user_id> mon 'allow r' osd 'allow rw pool=.nfs namespace=<nfs_cluster_name>, allow rw tag cephfs data=<fs_name>' mds 'allow rw path=<export_path>'
查看自定义 NFS Ganesha 配置
ceph nfs cluster config get <cluster_id>
这将输出用户定义的配置(如果有)。
重置 NFS Ganesha 配置
ceph nfs cluster config reset <cluster_id>
这将删除用户定义的配置。
注意
对于 rook 部署,必须显式重启 ganesha pod 才能使新的配置块生效。
导出管理
警告
目前,nfs 接口尚未与仪表板集成。仪表板和 nfs 接口都有不同的导出要求并以不同的方式创建导出。不支持管理仪表板创建的导出。
创建 CephFS 导出
ceph nfs export create cephfs --cluster-id <cluster_id> --pseudo-path <pseudo_path> --fsname <fsname> [--readonly] [--path=/path/in/cephfs] [--client_addr <value>...] [--squash <value>] [--sectype <value>...] [--cmount_path <value>]
这将创建包含导出块的导出 RADOS 对象,其中
<cluster_id> 是 NFS Ganesha 集群 ID。
<pseudo_path> 是导出在 NFS v4 伪文件系统中的位置,服务器上的导出将可用。它必须是绝对路径且唯一。
<fsname> 是 NFS Ganesha 集群用于提供此导出的 FS 卷的名称。
<path> 是 cephfs 中的路径。应提供有效路径,默认路径为 '/'。它不需要是唯一的。子卷路径可以使用以下命令获取
ceph fs subvolume getpath <vol_name> <subvol_name> [--group_name <subvol_group_name>]
<client_addr> 是将应用这些导出权限的客户端地址列表。默认情况下,所有客户端都可以根据指定的导出权限访问导出。有关允许的值,请参阅 NFS-Ganesha 导出示例。
<squash> 定义要执行的用户 ID 压缩类型。默认值为 no_root_squash。有关允许的值,请参阅 NFS-Ganesha 导出示例。
<sectype> 指定连接到导出时将使用的身份验证方法。有效值包括 “krb5p”、“krb5i”、“krb5”、“sys”、“tls”、“mtls” 和 “none”。可以提供多个值。可以多次指定该标志(示例:--sectype=krb5p --sectype=krb5i),或者多个值可以用逗号分隔(示例:--sectype krb5p,krb5i)。服务器将与客户端协商支持的安全类型,优先考虑从左到右提供的方法。
<cmount_path> 指定在 CephFS 中挂载此导出的路径。它允许是 / 和 EXPORT {path} 之间的任何完整路径层次结构。(即,如果 EXPORT { Path } 参数是 /foo/bar,则 cmount_path 可以是 /、/foo 或 /foo/bar)。
注意
如果此选项和其他 EXPORT { FSAL {} } 选项在多个导出之间相同,则这些导出将共享一个 CephFS 客户端。如果未指定,默认值为 /。
注意
指定需要 Kerberos 的 sectype 值仅在配置为支持 Kerberos 的服务器上才起作用。设置 NFS-Ganesha 以支持 Kerberos 可以在此处找到 Ceph 中 NFS Ganesha 的 Kerberos 设置。
注意
仅支持使用 nfs 接口部署的 NFS Ganesha 集群创建导出。
创建 RGW 导出
有两种 RGW 导出
一个 user 导出将导出 RGW 用户拥有的所有存储桶,其中导出的顶层目录是存储桶列表。
一个 bucket 导出将导出单个存储桶,其中顶层目录包含存储桶中的对象。
RGW 存储桶导出
要导出 bucket
ceph nfs export create rgw --cluster-id <cluster_id> --pseudo-path <pseudo_path> --bucket <bucket_name> [--user-id <user-id>] [--readonly] [--client_addr <value>...] [--squash <value>] [--sectype <value>...]
例如,要通过 NFS 集群 mynfs 在伪路径 /bucketdata 处将 mybucket 导出到 192.168.10.0/24 网络中的任何主机
ceph nfs export create rgw --cluster-id mynfs --pseudo-path /bucketdata --bucket mybucket --client_addr 192.168.10.0/24
注意
仅支持使用 nfs 接口部署的 NFS Ganesha 集群创建导出。
<cluster_id> 是 NFS Ganesha 集群 ID。
<pseudo_path> 是导出在 NFS v4 伪文件系统中的位置,服务器上的导出将可用。它必须是绝对路径且唯一。
<bucket_name> 是将要导出的存储桶的名称。
<user_id> 是可选的,指定将用于对存储桶执行读写操作的 RGW 用户。如果未指定,将使用拥有该存储桶的用户。
注意
目前,如果启用了多站点 RGW,Ceph 只能导出默认 realm 中的 RGW 存储桶。
<client_addr> 是将应用这些导出权限的客户端地址列表。默认情况下,所有客户端都可以根据指定的导出权限访问导出。有关允许的值,请参阅 NFS-Ganesha 导出示例。
<squash> 定义要执行的用户 ID 压缩类型。默认值为 no_root_squash。有关允许的值,请参阅 NFS-Ganesha 导出示例。
<sectype> 指定连接到导出时将使用的身份验证方法。有效值包括 “krb5p”、“krb5i”、“krb5”、“sys” 和 “none”。可以提供多个值。可以多次指定该标志(示例:--sectype=krb5p --sectype=krb5i),或者多个值可以用逗号分隔(示例:--sectype krb5p,krb5i)。服务器将与客户端协商支持的安全类型,优先考虑从左到右提供的方法。
注意
指定需要 Kerberos 的 sectype 值仅在配置为支持 Kerberos 的服务器上才起作用。设置 NFS-Ganesha 以支持 Kerberos 超出了本文档的范围。
RGW 用户导出
要导出 RGW user
ceph nfs export create rgw --cluster-id <cluster_id> --pseudo-path <pseudo_path> --user-id <user-id> [--readonly] [--client_addr <value>...] [--squash <value>]
例如,要通过 NFS 集群 mynfs 在伪路径 /myuser 处将 myuser 导出到 192.168.10.0/24 网络中的任何主机
ceph nfs export create rgw --cluster-id mynfs --pseudo-path /bucketdata --user-id myuser --client_addr 192.168.10.0/24
删除导出
ceph nfs export rm <cluster_id> <pseudo_path>
这将删除 NFS Ganesha 集群中的导出,其中
<cluster_id> 是 NFS Ganesha 集群 ID。
<pseudo_path> 是伪根路径(必须是绝对路径)。
列出导出
ceph nfs export ls <cluster_id> [--detailed]
它列出了集群的导出,其中
<cluster_id> 是 NFS Ganesha 集群 ID。
启用 --detailed 选项后,它会显示整个导出块。
获取导出
ceph nfs export info <cluster_id> <pseudo_path>
这将根据伪根名称显示集群的导出块,其中
<cluster_id> 是 NFS Ganesha 集群 ID。
<pseudo_path> 是伪根路径(必须是绝对路径)。
通过 JSON 规范创建或更新导出
可以使用以下命令将现有导出转储为 JSON 格式
ceph nfs export info *<cluster_id>* *<pseudo_path>*
可以通过导入相同格式的 JSON 描述来创建或修改导出
ceph nfs export apply *<cluster_id>* -i <json_file>
例如
ceph nfs export info mynfs /cephfs > update_cephfs_export.json
cat update_cephfs_export.json
{
"export_id": 1,
"path": "/",
"cluster_id": "mynfs",
"pseudo": "/cephfs",
"access_type": "RW",
"squash": "no_root_squash",
"security_label": true,
"protocols": [
4
],
"transports": [
"TCP"
],
"fsal": {
"name": "CEPH",
"fs_name": "a",
"sec_label_xattr": "",
"cmount_path": "/"
},
"clients": []
}
导入的 JSON 可以是描述单个导出的单个 dict,也可以是包含多个导出 dict 的 JSON 列表。
导出的 JSON 可以修改然后重新应用。下面,修改了 pseudo 和 access_type。修改导出时,提供的 JSON 应完整描述导出_新状态_(就像创建新导出一样),但身份验证凭据除外,在可能的情况下,这些凭据将从导出的_先前状态_沿用。
注意
fsal 块中的 user_id 不应在 JSON 文件中修改或提及,因为它是为 CephFS 导出自动生成的。它的格式是 nfs.<cluster_id>.<fs_name>.<hash_id>。
ceph nfs export apply mynfs -i update_cephfs_export.json
cat update_cephfs_export.json
{
"export_id": 1,
"path": "/",
"cluster_id": "mynfs",
"pseudo": "/cephfs_testing",
"access_type": "RO",
"squash": "no_root_squash",
"security_label": true,
"protocols": [
4
],
"transports": [
"TCP"
],
"fsal": {
"name": "CEPH",
"fs_name": "a",
"sec_label_xattr": "",
"cmount_path": "/"
},
"clients": []
}
还可以通过注入 Ganesha NFS EXPORT 配置片段来创建或更新导出。例如
ceph nfs export apply mynfs -i update_cephfs_export.conf
cat update_cephfs_export.conf
EXPORT {
FSAL {
name = "CEPH";
filesystem = "a";
}
export_id = 1;
path = "/";
pseudo = "/a";
access_type = "RW";
squash = "none";
attr_expiration_time = 0;
security_label = true;
protocols = 4;
transports = "TCP";
}
挂载
成功创建导出并部署 NFS Ganesha 守护程序后,可以使用以下命令挂载导出
mount -t nfs <ganesha-host-name>:<pseudo_path> <mount-point>
例如,如果 NFS 集群是使用 --ingress --virtual-ip 192.168.10.10 创建的,并且导出的伪路径是 /foo,则可以通过运行以下命令将导出挂载到 /mnt
mount -t nfs 192.168.10.10:/foo /mnt
如果 NFS 服务在非标准端口号上运行
mount -t nfs -o port=<ganesha-port> <ganesha-host-name>:<ganesha-pseudo_path> <mount-point>
注意
仅支持 NFS v4.0+。
注意
截至本文撰写之时(2024 年 1 月 1 日),没有版本的 Microsoft Windows 原生支持挂载 NFS v4.x 导出。
故障排除
有两种方法可以检查 NFS-Ganesha 日志
cephadm:通过运行以下命令列出 NFS 守护程序ceph orch ps --daemon-type nfs您可以使用以下命令在相关主机上搜索特定守护程序(例如,
nfs.mynfs.0.0.myhost.xkfzal)的日志cephadm logs --fsid <fsid> --name nfs.mynfs.0.0.myhost.xkfzalrook:kubectl logs -n rook-ceph rook-ceph-nfs-<cluster_id>-<node_id> nfs-ganesha
可以使用 nfs cluster config set 命令调整 NFS 日志级别(请参阅 设置自定义 NFS Ganesha 配置)。
手动 Ganesha 部署
可以在没有 cephadm 或 rook 等协调框架的情况下部署和管理 NFS ganesha 守护程序。
注意
手动配置未经测试或完全记录;您的体验可能会有所不同。如果这能奏效,请通过更新此文档来帮助我们。
限制
如果没有为 Ceph Manager 启用协调器模块,则 NFS 集群管理命令(例如以 ceph nfs cluster 开头的命令)将无法运行。但是,管理 NFS 导出的命令(例如以 ceph nfs export 为前缀的命令)预计会起作用,前提是必要的 RADOS 对象已经创建。所需的确切 RADOS 对象目前没有记录,因为对此功能的支持尚不完整。好奇的读者可以通过阅读 mgr/nfs 模块的源代码(在 ceph 源代码树中的 src/pybind/mgr/nfs 下找到)来找到有关该对象的一些详细信息。
要求
需要以下软件包才能使用 nfs-ganesha 启用 CephFS 和 RGW 导出
nfs-ganesha、nfs-ganesha-ceph、nfs-ganesha-rados-grace和nfs-ganesha-rados-urls软件包(版本 3.3 及以上)
Ganesha 配置层级
Cephadm 和 rook 启动每个 nfs-ganesha 守护程序时都带有一个最小的 bootstrap 配置文件,该文件从存储在 .nfs RADOS 池中的共享 common 配置中提取,并监视 common 配置的更改。每个导出都写入一个单独的 RADOS 对象,该对象通过 URL 从 common 配置中引用。