前言
本文介绍了两种方式将 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。
Git下载编译
对于 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, 注意打开对应的模块:
- 如果需要生成 FSAL_RGW 模块,则在编译选项中添加:
-DUSE_FSAL_RGW=ON
。 - 如果需要生成 FSAL_CEPH 模块,则在编译选项中添加:
-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
|
启动 ganesha-nfs
1
|
ganesha.nfsd -L /var/log/ganesha.log
|
如果一切顺利,你应该可以看到 ganesha.nfsd 进程在那,如果进程不在,那么查看Log,记得在启动进程前,关闭所有 CephX 配置。
挂载 nfs
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/
目录下。可以开始愉快的玩耍了!!!
RGW 模块测试时遇到的一些问题
我将 ganesha-nfs 部署到一个较大的集群中去,然后挂载NFS,对挂载目录进行压力测试,测试指令如下:
1
|
for i in {0..1000} ;do dd if=/dev/zero of=./$i bs=4k count=$i; done;
|
目的是,快速写入4KB~4MB不同大小的对象,现象是:
- 对于200KB以下的文件,写入正常,万次测试没有出现ioerror
- 对于400KB~1MB的文件,有5%的可能性,文件写入时报 ioerror(5)。
- 对于2MB以上的文件,有40%的可能性,文件写入报 ioerror(5)。
也就是说,对于几十KB的小文件写入,没有见到过ioerror,对于1MB以上的大文件写入,有很大(70% for 100MB+)概率报 ioerror(5)。 原因不明。希望知道原因的朋友可以指导下!
将 RBD 导出为 NFS。
指令很简单,这里就不细说,具体可以参考一篇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
|
RBD 和 CephFS 导出的 NFS 速度测试
测试机选择了一台非 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 |
参考文档: