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. 參考文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章