使用 Linux 远程连接来挂载 Ceph RBD 磁盘
block storage
RBD 是 Ceph 的块存储方案,最近需要在一台 Linux 服务器上挂载 Ceph 镜像,做法和 Kubernetes 挂 RBD 很像,但部分操作由于 Kubernetes 在镜像中已经固化了,所以将这次完全自己控制的步骤记录下来,加深对 Ceph 挂载的理解。
1. 安装 Ceph
要挂载 RBD 磁盘的 Linux 服务器首先要有 Ceph 的客户端,也就是 RBD 的客户端,以及一些 RBD 专用的 kernel module,毕竟这是要通过网络走特定的协议来完成的磁盘挂载,和本地直接 mount 还是有差别的。
安装过程并不复杂,因为环境中已经有了 Ceph 集群,从 Ceph 集群中的主节点使用 ceph-deploy 扩展新节点即可,就不再描述如何安装 Ceph 了。
# On Linux client
$ echo "<user-name> ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/<user-name>
$ sudo chmod 0440 /etc/sudoers.d/<user-name>
$ sudo apt-get install -y python
# On Ceph master
$ ceph-deploy install <Linux-client-IP>
$ ceph-deploy admin <Linux-client-IP>
2. 创建和挂载磁盘
上一步,已经在要挂载 RBD 的 Linux 服务器上安装好了 Ceph,接下来的操作在要挂载 Ceph RBD 磁盘的 Linux 服务器上操作即可。
首先为这个磁盘单独创建一个存储池,并指定该存储池作为 RBD 使用
$ sudo ceph osd pool create <pool-name> 50 50 # 两个 50 指定的 pg 和 pgp 的数量
$ sudo ceph osd pool application enable <pool-name> rbd
然后创建磁盘,下面这个命令创建了一个 1T 大小的磁盘,image-feature 参数指定的是 RBD 镜像的功能特性,很多功能特性只有高版本的 Linux kernel 才支持,甚至有些都没有 kernel 版本支持,所以只打开最基本的 layering 即可。
$ sudo rbd create <pool-name>/<image-name> --size 1T --image-feature=layering
接下来为了将远端的 RBD 磁盘挂载到本地,需要将其映射到本地的盘符上。
$ sudo rbd map <pool-name>/<image-name>
虽然已经关掉了大部分的 RBD 功能特性,结果还是报错了:
libceph: ... feature set mismatch, my 107b84a842aca < server's 40107b84a842aca, missing 400000000000000
3. 排错
接下来让我们看看 missing 400000000000000 是个什么意思。400000000000000 是一个二进制的字符串,每一个比特位对应一个 RBD 的功能特性,每个比特标识什么意思详见下表,表中还标出了支持该特性的内核版本,400000000000000 对应的特性是 CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING,内核是从 4.5 开始支持的,而这次用的 Linux 系统是 Ubuntu 16.04,内核版本为 4.4,所以才会报出这个问题。
Feature |
BIT |
OCT |
3.8 |
3.9 |
3.10 |
3.14 |
3.15 |
3.18 |
4.1 |
4.5 |
4.6 |
---|---|---|---|---|---|---|---|---|---|---|---|
CEPH_FEATURE_NOSRCADDR |
1 |
2 |
R |
R |
R |
R |
R |
R |
R |
R |
R |
CEPH_FEATURE_SUBSCRIBE2 |
4 |
10 |
-R- |
||||||||
CEPH_FEATURE_RECONNECT_SEQ |
6 |
40 |
-R- |
R |
R |
R |
R |
R |
R |
||
CEPH_FEATURE_PGID64 |
9 |
200 |
R |
R |
R |
R |
R |
R |
R |
R |
|
CEPH_FEATURE_PGPOOL3 |
11 |
800 |
R |
R |
R |
R |
R |
R |
R |
R |
|
CEPH_FEATURE_OSDENC |
13 |
2000 |
R |
R |
R |
R |
R |
R |
R |
R |
|
CEPH_FEATURE_CRUSH_TUNABLES |
18 |
40000 |
S |
S |
S |
S |
S |
S |
S |
S |
S |
CEPH_FEATURE_MSG_AUTH |
23 |
800000 |
-S- |
S |
S |
S |
|||||
CEPH_FEATURE_CRUSH_TUNABLES2 |
25 |
2000000 |
S |
S |
S |
S |
S |
S |
S |
S |
|
CEPH_FEATURE_REPLY_CREATE_INODE |
27 |
8000000 |
S |
S |
S |
S |
S |
S |
S |
S |
|
CEPH_FEATURE_OSDHASHPSPOOL |
30 |
40000000 |
S |
S |
S |
S |
S |
S |
S |
S |
|
CEPH_FEATURE_OSD_CACHEPOOL |
35 |
800000000 |
-S- |
S |
S |
S |
S |
S |
|||
CEPH_FEATURE_CRUSH_V2 |
36 |
1000000000 |
-S- |
S |
S |
S |
S |
S |
|||
CEPH_FEATURE_EXPORT_PEER |
37 |
2000000000 |
-S- |
S |
S |
S |
S |
S |
|||
CEPH_FEATURE_OSD_ERASURE_CODES*** |
38 |
4000000000 |
|||||||||
CEPH_FEATURE_OSDMAP_ENC |
39 |
8000000000 |
-S- |
S |
S |
S |
S |
||||
CEPH_FEATURE_CRUSH_TUNABLES3 |
41 |
20000000000 |
-S- |
S |
S |
S |
S |
||||
CEPH_FEATURE_OSD_PRIMARY_AFFINITY |
41* |
20000000000 |
-S- |
S |
S |
S |
S |
||||
CEPH_FEATURE_CRUSH_V4 **** |
48 |
1000000000000 |
-S- |
S |
S |
||||||
CEPH_FEATURE_CRUSH_TUNABLES5 |
58 |
200000000000000 |
-S- |
S |
|||||||
CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING |
58* |
400000000000000 |
-S- |
S |
解决这个问题,可以有两种方法,第一种是升级 kernel,第二种方法是降级 Ceph 的 CRUSH 算法,本文采用的是第二种方法,因为升级第二种方法操作起来更简单,风险也更低,一条命令即可:
$ sudo ceph osd crush tunables legacy
映射操作现在可以成功了!
$ sudo rbd map <pool-name>/<image-name>
/dev/rbd0
接下来的操作和挂载一个本地磁盘就没有任何区别了:
$ sudo mkfs.ext4 /dev/rbd0
$ sudo mkdir /data
$ sudo mount /dev/rbd0 /data/
让我们看看挂载的结果吧。
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 893.8G 0 disk
|-sda1 8:1 0 476M 0 part /boot
|-sda2 8:2 0 119.2G 0 part [SWAP]
`-sda3 8:3 0 774.1G 0 part /
rbd0 251:0 0 1T 0 disk /data
4. 参考文档
- [ceph-users] Rbd map command doesn't work
- [ceph-users] Rbd map command doesn't work
- Feature Set Mismatch Error on Ceph Kernel Client
- Linux挂载RBD
- ceph分布式存储实战(4)——ceph存储配置(映射RBD镜像到客户端)