本文介绍了两种方式将 Ceph 导出为 NFS,一种通过 RGW,一种通过 CephFS,通过 FSAL 模块 连接到 RGW 或者 CephFS, 其中,FSAL_RGW 调用 librgw2 将 NFS 协议转义为 S3 协议再通过 RGW 存入到 Ceph 中,FSAL_CEPH 调用 libcephfs1 将 NFS 转义为 Cephfs 协议再存入到 Ceph 中。所以需要额外安装这两个包。
经过测试发现,FSAL_RGW 模块在压测是很不稳定,对大文件的写入经常报 io error (5)
,FSAL_CEPH 模块比较稳定。
声明
本文只是介绍 ganesha-nfs 的部署方式,不代表其能否在生产环境使用。另外,本文部署环境为,Ceph -> Jewel, ganesha-nfs -> V2.4-stable, OS -> CentOS 7。
对于 Jewel
版本的 Ceph,前往 nfs-ganesha 的Git,下载 V2.4-stable
,安装一些依赖后,通过源码部署,操作系统是CentOS-7.2.1511, Ceph 版本是 Jewel:
下载
1 | git clone -b V2.4-stable https://github.com/nfs-ganesha/nfs-ganesha.git --recursive |
安装依赖
1 2 3 4 5 6 7 | yum install gcc git cmake autoconf libtool bison flex doxygen openssl-devel gcc-c++ libuuid-devel nfs-utils -y # 如果要生成 FSAL_RGW 模块,需要安装 librgw2-devel yum install librgw2-devel -y # 如果要生成 FSAL_CEPH 模块,需要安装 libcephfs1-devel yum install libcephfs1-devel -y |
编译 nfs-ganesha, 注意打开对应的模块:
-DUSE_FSAL_RGW=ON
。-DUSE_FSAL_CEPH=ON
。 1 2 3 | mkdir /tmp/build/ cd /tmp/build/ cmake -DUSE_FSAL_RGW=ON -DUSE_FSAL_CEPH=ON /tmp/nfs-ganesha/src/ |
注意,在 cmake 的输出中,会有如下输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 | -- Looking for ceph_ll_lookup_root in cephfs - found -- Found cephfs libraries: /usr/lib64/libcephfs.so -- Found CEPHFS: /usr/include -- Looking for rgw_mount in rgw -- Looking for rgw_mount in rgw - found -- Found rgw libraries: /usr/lib64/librgw.so -- Found RGW: /usr (found suitable version "1.1", minimum required is "1.1") ... -- USE_FSAL_CEPH = ON -- USE_FSAL_CEPH_MKNOD = OFF -- USE_FSAL_CEPH_SETLK = OFF -- USE_FSAL_CEPH_LL_LOOKUP_ROOT = ON -- USE_FSAL_RGW = ON |
确保,确保,确保: -- USE_FSAL_CEPH
为 ON,以及 -- USE_FSAL_RGW
为 ON。
如果是 OFF,请检查下librgw2-devel
或者libcephfs1-devel
是否有安装,如果这两个包都已经安装了,还显示为 OFF, 可以尝试下清空编译目录:rm -rf /tmp/build/*
,再进行编译,如果依旧为 OFF,可以尝试下删除所有的 Ceph 包,再重新 yum install ceph librgw2-devel libcephfs1-devel -y
。
这两项编译输出为 OFF 的输出可能如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | -- Looking for ceph_ll_lookup in cephfs -- Looking for ceph_ll_lookup in cephfs - not found -- Found cephfs libraries: CEPHFS_LIBRARY-NOTFOUND -- Could NOT find CEPHFS (missing: CEPHFS_INCLUDE_DIR CEPHFS_LIBRARY_DIR) CMake Warning at CMakeLists.txt:564 (message): Cannot find CEPH runtime. Disabling CEPH fsal build -- Looking for rgw_mount in rgw -- Looking for rgw_mount in rgw - not found -- Found rgw libraries: RGW_LIBRARY-NOTFOUND -- Could NOT find RGW: Found unsuitable version "0.0", but required is at least "1.1" (found ) CMake Warning at CMakeLists.txt:577 (message): Cannot find supported RGW runtime. Disabling RGW fsal build ... -- USE_FSAL_CEPH = OFF ... -- USE_FSAL_RGW = OFF |
编译,安装
1 2 3 | cd /tmp/build/ make make install |
TIP
在make install
生成的输出中,可以看到:
1
2
3
4
> -- Up-to-date: /usr/share/doc/ganesha/config_samples/rgw.conf
> ...
> -- Up-to-date: /usr/share/doc/ganesha/config_samples/ceph.conf
>
这两个文件就是配置将 RGW 和 CephFS 配置为 ganesha-nfs 的配置模板。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | cat /etc/ganesha/ganesha.conf EXPORT { Export_ID=1; Path = /; Pseudo = /cephfs; Access_Type = RW; NFS_Protocols = 4; Transport_Protocols = TCP; FSAL { Name = CEPH; } } EXPORT { Export_ID=2; Path = /; Pseudo = /rgw; Access_Type = RW; Squash = No_root_squash; NFS_Protocols = 4; Transport_Protocols = TCP; FSAL { Name = RGW; User_Id = "admin"; Access_Key_Id ="M54WD1J33ZRZA7D6YX8E"; Secret_Access_Key = "lXu1DgwO1YLoV8IPlbH9FpaCIZyHcOBIrMLQ2xUi"; } } RGW { ceph_conf = "/etc/ceph/ceph.conf"; } |
上面配置的为 CephFS 的配置,下面的配置为 RGW 的配置。
其中,User_Id , Access_Key_Id, Secret_Access_Key 根据自己的环境进行修改。
librgw init failed (-5)
解决方法经过多次尝试,包括在ganesha.conf
内添加init_args
指定秘钥和Ceph的用户,ganesha-nfs 均无法启动,报的错如标题,解决方法就是关闭CephX,将/etc/ceph/ceph.conf
内的三个 cephx
改为none
,然后重启 ceph-mon,ceph-osd,ceph-radosgw, ceph-mds 进程,再启动ganesha-nfs,即可正常运行。
完整报错信息如下:
1 2 | RGW-1 : nfs-ganesha-2232083[main] create_export :FSAL :CRIT :RGW module: librgw init failed (-5) RGW-1 : nfs-ganesha-2232083[main] mdcache_fsal_create_export :FSAL :MAJ :Failed to call create_export on underlying FSAL |
1 | ganesha.nfsd -L /var/log/ganesha.log |
如果一切顺利,你应该可以看到 ganesha.nfsd 进程在那,如果进程不在,那么查看Log,记得在启动进程前,关闭所有 CephX 配置。
1 | mount -t nfs4 {$ganesha-server-ip}:/ /mnt |
此时,ll /mnt/
如果顺利的话,会看到:
1 2 3 4 | ll /mnt/ 总用量 1 drwxr-xr-x 1 root root 5295308800 3月 30 23:30 ceph drwxrwxrwx 3 root root 0 1月 1 1970 rgw |
说明 CephFS 和 RGW 都已经正常对接。不过,我在操作过程中,看到了一个报错信息:
1 2 | ls /mnt/ ls: 正在读取目录/mnt/: 远程 I/O 错误 |
这个现象是可以复现的,复现指令如下:
1 2 3 4 5 6 7 8 | [root@node ~]# ps -ef|grep ganesha root 51719 1 0 23:28 ? 00:00:01 ganesha.nfsd -L /var/log/ac root 52838 50284 0 23:39 pts/4 00:00:00 grep --color=auto ganesha [root@node ~]# kill -9 51719 [root@node ~]# ganesha.nfsd -L /var/log/ganesha.log [root@node ~]# mount -t nfs4 10.4.0.104:/ /mnt/ [root@node ~]# ls /mnt/ ls: 正在读取目录/mnt/: 远程 I/O 错误 |
目前找到的一个比较笨的解决方法是,具体原因还不太清楚,但是目录显示正确后,不会再发生远程I/O 错误
:
1 2 3 4 5 6 7 | # mkdir /root/a # ceph-fuse -m 10.4.0.101:6789,10.4.0.102:6789,10.4.0.103:6789 /root/a # umount /root/a # ll /mnt/ 总用量 1 drwxr-xr-x 1 root root 5295308800 3月 30 23:43 ceph drwxrwxrwx 3 root root 0 1月 1 1970 rgw |
如果,你所使用的admin
用户名下有很多的桶,那么这些桶都会以/mnt/rgw/xxbucket
的结构显示出来,如果你在/mnt/rgw/
下建立的一个目录,那么就相当于通过 RGW 建立了一个桶,所以,你执行touch /mnt/rgw/123
是会报错的,因为不符合S3的对象必须位于桶内的规定,简单点说,就是把/mnt/rgw/
和S3的根目录一一对应即可。
同样, CephFS 内的内容都会显示在/mnt/cephfs/
目录下。可以开始愉快的玩耍了!!!
我将 ganesha-nfs 部署到一个较大的集群中去,然后挂载NFS,对挂载目录进行压力测试,测试指令如下:
1 | for i in {0..1000} ;do dd if=/dev/zero of=./$i bs=4k count=$i; done; |
目的是,快速写入4KB~4MB不同大小的对象,现象是:
也就是说,对于几十KB的小文件写入,没有见到过ioerror,对于1MB以上的大文件写入,有很大(70% for 100MB+)概率报 ioerror(5)。 原因不明。希望知道原因的朋友可以指导下!
指令很简单,这里就不细说,具体可以参考一篇keepalived+ceph rbd配置nfs的高可用文章:
1 2 3 4 5 6 7 8 | rbd -p rbd create bar --size 10G --image-format 1 rbd map -p rbd bar mkfs.xfs /dev/rbd0 mount /dev/rbd0 /mnt yum install nfs-utils -y echo "/mnt *(rw,async,no_subtree_check,no_root_squash)" > /etc/exports systemctl start nfs-server.service exportfs -r |
测试机选择了一台非 NFS 提供节点作为 客户端,使用 FIO 进行测试:
1 | fio -direct=1 -iodepth 32 -thread -ioengine=libaio -bs=4K/4M -size=10G -runtime=60 -group_reporting -name=mytest -filename=/mnt/xxx -rw=randwrite |
结果如下,另外测了一次ceph-fuse
挂载的写速度,还有使用kernel挂载cephfs的速度:
BS | iops | bw | |
---|---|---|---|
CephFS | 4K | 5765 | 23 MB/s |
4M | 169 | 695 MB/s | |
RBD | 4K | 70765 | 283 MB/s |
4M | 203 | 832 MB/s | |
ceph-fuse | 4K | 500 | 2 MB/s |
4M | 10 | 43 MB/s | |
mount -t ceph | 4K | 8261 | 33 MB/s |
4M | 293 | 1173.9 MB/s |