ceph Luminous新功能之crush class
cursh class為新增的管理裝置類的功能,可以將特定一組裝置指定為類,建立rule的時候直接指定class即可,以前也可以實現該功能,只不過需要編輯crushmap,手動新增class。該功能只需要命令列就可以實現。
前言
叢集情況和上一篇文章一樣
# ceph -s
cluster:
id: 4c7ec5af-cbd3-40fd-8c96-0615c77660d4
health: HEALTH_OK
services:
mon: 3 daemons, quorum luminous0,luminous1,luminous2
mgr: luminous0(active)
mds: 1 /1/1 up {0=luminous0=up:active}
osd: 6 osds: 6 up, 6 in
data:
pools: 7 pools, 112 pgs
objects: 240 objects, 3359 bytes
usage: 9245 MB used, 51587 MB / 60833 MB avail
pgs: 112 active+clean
關於之前的crush
完全手動管理crush
1、在 ceph.conf
配置中將掛鉤關掉
osd_crush_update_on_start = false
2、部署OSD
3、手動建立所有的 CRUSH buckets
4、手動在每個 buckets 中放置 OSD
每當新加入、移除一個節點,或者將OSD從一個 host 移到另一個 host 時,也必須手動更改 CRUSH map。
CEPH-CRUSH-LOCATION 掛鉤
定義 osd_crush_location_hook,它可以讓你定義一個路徑去執行指令碼,允許你自動處理以上過程。
呼叫方式:
myhook --cluster <cluster_name> --id <id> --type osd
叢集名通常是 ceph , id 是守護程序識別符號( OSD 號)。
CRUSH devices class
目的
這麼做的目的是為ceph不同型別的裝置(HDD,SSD,NVMe)提供一個合理的預設,以便使用者不必自己手動編輯指定。這相當於給磁碟組一個統一的class標籤,根據class建立rule,然後根據role建立pool,整個操作不需要手動修改crushmap。
建立兩個 class
# ceph osd crush class ls
[]
# ceph osd crush class create hdd
created class hdd with id 0 to crush map
# ceph osd crush class create ssd
created class ssd with id 1 to crush map
# ceph osd crush class ls
[
"hdd",
"ssd"
]
根據class,可以對osd進行以下兩種操作:
1、部署OSD時指定 class,比如,指定部署磁碟所在的 OSD 到指定 class 中:
ceph-disk prepare --crush-device-class <class> /dev/XXX
2、將現有 osd 加入到指定 class 中,命令如下:
ceph osd crush set-device-class osd.<id> <class>
* 以下對第二種操作進行實驗,也是使用最多的。*
當前OSD 分佈
# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1 0.05814 root default
-2 0.01938 host luminous0
1 0.00969 osd.1 up 1.00000 1.00000
5 0.00969 osd.5 up 1.00000 1.00000
-3 0.01938 host luminous2
0 0.00969 osd.0 up 1.00000 1.00000
4 0.00969 osd.4 up 1.00000 1.00000
-4 0.01938 host luminous1
2 0.00969 osd.2 up 1.00000 1.00000
3 0.00969 osd.3 up 1.00000 1.00000
為class新增osd
將0、1、2分到hdd class,3、4、5分到ssd class
# for i in 0 1 2; do ceph osd crush set-device-class osd.$i hdd; done
set-device-class item id 3 name 'osd.0' device_class hdd
set-device-class item id 4 name 'osd.1' device_class hdd
set-device-class item id 5 name 'osd.2' device_class hdd
# for i in 3 4 5; do ceph osd crush set-device-class osd.$i ssd; done
set-device-class item id 3 name 'osd.3' device_class ssd
set-device-class item id 4 name 'osd.4' device_class ssd
set-device-class item id 5 name 'osd.5' device_class ssd
再檢視osd分佈
# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-12 0.02907 root default~ssd
-9 0.00969 host luminous0~ssd
5 0.00969 osd.5 up 1.00000 1.00000
-10 0.00969 host luminous2~ssd
4 0.00969 osd.4 up 1.00000 1.00000
-11 0.00969 host luminous1~ssd
3 0.00969 osd.3 up 1.00000 1.00000
-8 0.02907 root default~hdd
-5 0.00969 host luminous0~hdd
1 0.00969 osd.1 up 1.00000 1.00000
-6 0.00969 host luminous2~hdd
0 0.00969 osd.0 up 1.00000 1.00000
-7 0.00969 host luminous1~hdd
2 0.00969 osd.2 up 1.00000 1.00000
-1 0.05814 root default
-2 0.01938 host luminous0
1 0.00969 osd.1 up 1.00000 1.00000
5 0.00969 osd.5 up 1.00000 1.00000
-3 0.01938 host luminous2
0 0.00969 osd.0 up 1.00000 1.00000
4 0.00969 osd.4 up 1.00000 1.00000
-4 0.01938 host luminous1
2 0.00969 osd.2 up 1.00000 1.00000
3 0.00969 osd.3 up 1.00000 1.00000
建立rule
# ceph osd crush rule create-simple hdd-rule default~ssd host firstn
Invalid command: invalid chars ~ in default~ssd
osd crush rule create-simple <name> <root> <type> {firstn|indep} : create crush rule <name> to start from <root>, replicate across buckets of type <type>, using a choose mode of <firstn|indep> (default firstn; indep best for erasure pools)
Error EINVAL: invalid command
這裡出現錯誤,我在想,是不是 class name 不用帶上 default~
這個符號,於是
# ceph osd crush rule create-simple hdd-rule ssd host firstn
Error ENOENT: root item ssd does not exist
先跳過這個直接建立rule關聯class的命令,後續BUG修復了再來實驗
手動來建立rule
首先檢視當前rule的狀況
# ceph osd crush rule ls
[
"replicated_rule"
]
只有一個預設的rule
* 第一步:獲取crushmap *
# ceph osd getcrushmap -o c1
11
第二步:反編譯crushmap
# crushtool -d c1 -o c2.txt
編輯crushmap
# vim c2.txt
在 # rule
那一欄 replicated_rule
的後面新增 hdd_rule
和 ssd_rule
# rules
rule replicated_rule {
ruleset 0
type replicated
min_size 1
max_size 10
step take default
step chooseleaf firstn 0 type host
step emit
}
rule hdd_rule {
ruleset 1
type replicated
min_size 1
max_size 10
step take default class hdd
step chooseleaf firstn 0 type osd
step emit
}
rule ssd_rule {
ruleset 2
type replicated
min_size 1
max_size 10
step take default class ssd
step chooseleaf firstn 0 type osd
step emit
}
第三步:編譯crushmap
# crushtool -c c2.txt -o c1.new
第四步:注入crushmap
# ceph osd setcrushmap -i c1.new
12
此時,檢視rule
# ceph osd crush rule ls
[
"replicated_rule",
"hdd_rule",
"ssd_rule"
]
有了新建立的兩個rule
測試一下,rule 繫結 class是否成功
1、在 ssd_rule 上建立一個 pool
# ceph osd pool create testpool 64 64 ssd_rule
pool 'testpool' created
2、寫一個物件
# rados -p testpool put object1 c2.txt
3、檢視物件的osdmap
# ceph osd map testpool object1
osdmap e46 pool 'testpool' (7) object 'object1' -> pg 7.bac5debc (7.3c) -> up ([5,3,4], p5) acting ([5,3,4], p5)
發現物件確實只寫在 ssd class 所對應的 3個OSD(osd.3 osd.4 osd.5)上,rule繫結成功。