|
|
楼主 |
发表于 2022-7-18 17:38:08
|
显示全部楼层
ceph-disk 是如何工作的?
/ i, V% O& P( [. c. \3 t: L
8 \9 ~. ]9 X/ J! u! M通过ceph-disk 部署osd, 数据分区和journal 分区将自动挂载到正确的目录,机器重启也能保证工作。通过ceph-disk部署osd, 将大大提高ceph部署运维的自动化程度,并降低操作出错几率。
: l( G% Q: b0 b. H4 v* k
4 ^5 `- r3 k. B" t. B( g( r3 Z以新创建OSD为例,描述ceph-disk的工作机制。
$ e* R. I# E5 G% y" D2 y6 p2 h2 f( V5 o+ f& k( [/ \
分为两大步骤:prepare disk 和activate disk4 p! y1 C, }. I! ]4 T5 |! J
% O# j! T* s+ I* {2 q* w9 q/ B+ R% n
假设/dev/sdg是OSD要使用的数据盘, /dev/sdk 是SSD, OSD要使用的journal分区在这里创建。则创建OSD 并上线的命令如下:
0 N9 B! N# ~' |6 [; J; Q; x: i1 F# V
Ceph-disk prepare /dev/sdg /dev/sdk" d8 `& A5 S/ ?( O F4 p
@3 a: C/ r$ x; mCeph-disk activate /dev/sdg1
6 t0 B- @' j8 f7 v4 s: j/ u9 |9 |+ C. }
下面详细深入其过程。" y9 b* L1 ? o' T, [4 B3 u! q3 X
1 M2 B! L- v$ u8 c- u! f1. 准备journal分区。
- \8 L! R$ x, z* m" u- n
. j1 g* L, n8 p2 ]Prepare_journal_dev()调用分区工具sgdisk从/dev/sdk上划分一块journal分区。& F) K9 Q: Q! n7 N5 u
2 g; t. p) n- {. T0 r有以下注意要点:2 y5 {4 Q; ^, s* V$ `4 ~
( ?- T9 q j n4 Q) P/ Ia. 在调用sgdisk之前,prepare_journal_dev()会获取ceph.conf文件中指定的osd_journal_size大小,我们的ceph.conf指定大小如下:5 f7 t! G$ t7 \9 z, f# L/ b1 W0 ~3 O
) z4 T# o, C" X$ q1 _
# ?( A/ p- }% D3 {! z3 q5 \6 E2 R* ~+ T5 j) c$ j
4 a% {4 O2 z6 Q- U
% s e5 I+ @8 B9 c7 m
b. 实际部署环境中,由于作为journal的ssd分区并不需要很大空间,所以一个ssd很可能被多个osd共享来划分各自的journal分区,我们的环境是,一个300G的ssd 划分成5个(甚至更多的)20G的分区,挂载成5个osd的journal.
X- W" c3 e4 l
/ D; x5 y. u8 Nc. Ceph-disk 在部署journal分区的时候,能自动侦测SSD盘已有分区数,不破坏已有分区,分配不冲突的新分区号来创建分区。* I9 B/ ]- N: U; p# ?( I
+ s( L5 r" I1 ^$ A( O1 A5 l3 m+ N
d. 如果不指定创建分区的uuid,ceph-disk会自动为journal分区生成一个,称之为journal_uuid.; N, q& g* D: v7 g9 K5 x
( g, T) W% p' P. Ue. 在调用sgdisk的时候,还有一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建journal的typecode:
' F- s6 W' N8 k. K& B
7 b2 @- ^, j8 ~2 {1 v
9 O+ m4 R# [" |, s6 ] S8 a/ s) b+ Z4 Y2 w
至于为何用此特殊UUID做typecode, 基本上此UUID可作为辨识分区为ceph journal的凭证,稍后深入解释。9 ~5 Z$ @+ L1 |6 Y2 s7 u) c
4 M+ u y* ?, f, Y/ v至此,prepare_journal_dev()已经准备好了sgdisk所需的各个参数,下面给出一个实际发生的参数例子:0 g9 V/ N& Y; P+ u+ c, t# \5 M# ~
4 s$ F7 Y, H& u& G7 P/usr/sbin/sgdisk --new=6:0:+20480M--change-name="6:ceph journal" --partition-guid=6:c6422c03-d320-4633-b35d-4f43c6cdd9fa--typecode=6:45b0969e-9b03-4f30-b4c6-b4b80ceff106 --mbrtogpt -- /dev/sdk/ Z8 S9 u# F% Z, x& y
: j8 Z/ A! i. {4 F( l
2. 在目录/dev/disk/by-partuuid/下为此journal分区创建link:
8 ]6 o, @1 W& \* j2 w) E$ a
1 w J. C% d) d7 Y, F1 C2 z) j
+ V: a; o! ?& g1 i' q5 T, S9 `( Z9 `8 H( C! N2 c% ~
% E( y* V8 q# K+ h+ J
- t; ?% [- X+ S1 k4 `$ O简单介绍一下这个link如何产生的。+ |0 w" k8 C% l/ N
& e. q1 R5 n1 R: a在调用sgdisk 创建完journal分区后,ceph-disk 调用partx更新分区表,会触发一个块设备/分区udev event并通知到内核。Ceph编写了udev规则文件如下:* y ^" h8 a9 {
5 I4 `/ ?. k; ?" k% M 5 @3 U- P: s( V
* z6 ~& ^8 F8 c) m% X$ ~0 b# I
8 q5 Q- {0 u4 j- Z% n
3 x2 h+ S% T, r: uUdev daemon在收到由partx产生的udev event后,根据以上的ceph规则文件,将调用/usr/sbin/ceph-disk-udev脚本。正是在这个脚本里,在目录/dev/disk/by-partuuid/下为此journal分区创建了link。此脚本还有另外一个扫描OSD专属分区的功能,后文会提及。暂时不表。 V/ m9 }1 e3 o' f: y
/ D/ n$ W7 H' ~% o n. s4 K* t2 W
% S2 n3 f( {) L- ^
7 ^; v, ?" g8 e这个link有什么用?8 ]% X5 b+ M+ w1 R
* V* }4 V5 y$ G
由于这个link是根据partition uuid生成的,可以把它看成是到特定journal分区的固定映射。后文会指出osd的journal将映射到此link:: a( w d: T7 |5 E% ]1 E
% |% S7 U9 ~$ k; g- h, k( d& p
& s6 K* g& y! U; X5 s
8 G; G; R, X8 R" M- S1 L! R' a2 t5 \- x0 m2 b
5 ?$ L1 a% X, h! K由此图看出,位于osd 数据分区里的journal是一个link,指向一个固定的位置:/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa, 再由这个link指向真正的journal分区,由此解决的盘符漂移带来的问题。下文介绍的osd 数据分区的link也是基于此原理。7 b4 h( ~; P' S) R
" P: }6 E" l' m* r; z4 J# n2 T3 E
. v$ M7 S# q( A7 m [: P8 ~9 C4 d' M7 N' h+ @, M
3. 准备OSD数据分区。
/ |* ?2 K' m M- U2 [) k" L+ q4 u: m( Y
这个过程跟准备journal分区大体一样。区别在于:
s: [0 g* M, A; R
3 i5 Y# Y' J- Va. 调用sgdisk 使用—largest-new来使用磁盘最大可能空间。所以/dev/sdg会有一个分区sdg1,它使用所有的空间。
& \5 |- O& o; z- A; m0 `
) W1 \# A$ A8 [* `! z$ b. |4 kb. 格式化/dev/sdg1。这里对ceph-disk做了小的定制,默认使用了ext4分区格式。
+ |6 u, f3 R) u, e6 |
' P! T- `# i! ~# v% U+ p8 f% Cc. 将此分区mount到一个临时的目录,然后再其中创建一个名为journal的link,指向/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa。至此,OSD的journal分区映射完成。最后umount。0 N+ W9 k/ q0 t$ w! o6 c2 B2 u
9 x" {/ _! i* i3 h/ {% ~d. 再次调用sgdisk,写入一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建OSD的typecode:! {4 Y% O2 d8 M4 S% S$ g
3 \) m3 K+ `0 N; l1 h; x7 p2 R1 E
, r4 E: x8 m) V& L+ _
同JOURNAL_UUID, 为何用此特殊UUID做typecode, 是因为此UUID可作为辨识分区为ceph OSD数据分区的凭证,稍后深入解释。" u: N* F/ K0 n# g
" w8 k# a& Y: e3 u, t2 f/ n/ H
& V+ ? z2 {% m# y. O5 b! Y' s8 |. R: x- n& |
4. 在目录/dev/disk/by-partuuid/下为此OSD 数据分区创建link。
8 }$ J+ Q2 \1 \9 P- l1 p3 f/ y
, y$ `* U4 `" d2 ?+ g9 \) f% R过程同journal的link创建过程。8 i( n9 `! u# \, @5 f
# h1 a& ?7 q2 C! C
5 k0 r( ^' A& u8 e2 m: l5 X$ Y
7 ?: k0 ]6 G8 y6 F* M+ c) X/ e9 v5. Activate过程。
1 L7 ~5 J$ V* x% t. M$ h A3 Y% z2 [1 f* P9 u7 z
Activate的命令是 ceph-disk activate /dev/sdg1。
* \3 E1 { u7 D' c# t9 N, i
5 S5 t/ r, R3 A. ^+ B( _, o3 D但其实并不需要显式的调用这个命令。原因是,准备好OSD 数据分区后,udev event 触发了ceph-disk-udev。而ceph-disk-udev会自动调用ceph-disk activate /dev/sdg1。
9 `* O4 s5 Q9 o& H9 T) F, f
1 L8 U* X' | b- X |1 D下面介绍这个过程是如何自动化的。详情参见ceph-disk-udev脚本。
, r |. U* D$ s' }+ @* G" |0 f6 o8 N# I
新的OSD 数据分区的生成,触发udev event, 通过ceph udev rule,最终调用ceph-disk-udev,分析该分区的typecode,发现是OSD_UUID,即表明是ceph OSD的数据分区,于是触发ceph-disk activate /dev/sdg1:; b3 H8 o1 W) Y3 r" `0 P9 C8 }
: a k6 j* N" \4 x0 `
7 N# M- K* R9 I; L3 `' h) q
0 F W, O- E' H" j" F) J 8 }* `; |; M% O
+ t# o" y" j, f- c7 rTypecode 为JOURNAL_UUID的情况也一样,只不过是通过ceph-disk activate-journal 来启动OSD.
9 J; E0 ?% {3 Z4 f
3 r- A# }+ E6 g$ r! n. i4 b在介绍ceph-disk activate /dev/sdg1的具体流程。
. `0 I5 \2 [* j* t% \6 c5 q
7 ?4 o+ m8 K4 O+ T3 qa. 将/dev/sdg1 挂载至临时目录,一般为var/lib/ceph/tmp/mnt.xxx
! v: x/ Q- b$ o) k% P0 m
C9 [: ^3 q% C+ s- E0 ~b. 分配OSD id,及调用ceph osd create 产生 osd id/ S. E7 D" z V5 M( p: p
, j: H, `" Y I4 C9 k1 O
c. 初始化OSD, 如ceph-osd –mkfs –osd-data –osd-journal* x- k% w* I: Z- m* k% {
( O6 q# {/ E) l- U8 z( Bd. 根据osd id 重新挂载到最终目录: var/lib/{cluster}/osd/ceph-{osd.id}
/ f# [/ @* W+ Y( j u3 h& D; j( ^- d4 Q6 W, K1 I* L N
e. Service ceph start osd
" _2 w8 B* p# \; |: s0 r: r& E5 v3 c- \/ D" g5 t
对于osd id 已经存在,重启osd的case,也会用到ceph-disk activate,这种情况稍有不同,不需要产生新的osd id,只需要将/dev/sdg1挂载至临时目录,获取osd id后,重新挂载到最终目录。
5 B& k! D5 b% K+ R& I( y0 y
4 [9 ]# r) l! \: q; O( R 2 z1 j/ N' t( I8 d
! p, a' V( q/ H/ LCeph-disk 支持的其他命令如下:* `. v) A# N3 ~3 I; w6 O
4 h5 o% x2 X; t) t( @3 L9 v prepare Prepare a directory or disk for aCeph OSD' {* t! n1 y6 A) Y6 m, ~
2 O1 S8 m' V7 V. m+ H* z1 A2 I
activate Activate a Ceph OSD
2 S! B: q" K2 d. O4 X- E, s6 u% _- V1 a4 N0 n+ `
activate-journal Activate an OSD via its journal device
, n0 K# c2 @3 e4 S
) U' n1 V8 P( M# {. ]; A activate-all Activate all tagged OSD partitions3 N' l4 r* |4 E& S
$ u# k; w9 ]8 y5 X2 q
list List disks, partitions, and CephOSDs. x- e; [) C- u. n( O. f
& ]" L0 B. w# n6 A1 _1 H7 V$ G suppress-activate Suppress activate on a device (prefix): n" j5 H% a( R0 j7 Q
' H* E9 b+ L0 c unsuppress-activate3 p. |& X) D7 e% q; k* k- }' U
4 z" O! a" ^ F% p Stop suppressingactivate on a device (prefix)( n: \3 S, V0 J; S& H* t
/ W ?$ L# k* Z" c4 X0 Q% z
zap Zap/erase/destroy a device'spartition table (and2 y3 ?" _' e8 K5 ~, T$ q A/ F
1 Q/ K ]0 \7 \1 ^$ R7 n contents)% |% L- P: J% W( o) W$ e: m
" ~/ T- V3 O6 r) ]! R# E% t特别强调几点:
, o" D0 [1 x& Q% |( a- L/ ]3 e4 r: m" f' l/ w
a. Suppress的字面意思就是抑制,用在这里的意图主要是,如果只想prepare各个分区,暂时不想activate OSD(创建osd 上线),可以使用此命令,等到所有的分区都prepare好了,unsuppress 一把,再activate-all.' J* m$ u% X: F' Z3 l# H8 ]% J# K
% f7 |8 }+ w( b) ab. Activate-journal 是通过制定journal 分区来启动osd, 如:ceph-diskactivate-journal /dev/sdk6. Ceph-disk 执行的流程为:3 e2 d$ g# ?5 E
2 _7 c4 p* a! f& T9 O5 C通过 ceph-osd -i 0 --get-journal-uuid --osd-journal /dev/sdk6 返回osd_uuid. 有了osd_uuid,就能找到osd 数据分区了,即定位/dev/disk/by-partuuid/$osd_uuid,这样就回到了使用osd 数据分区来activate的命令逻辑,即ceph-disk activate /dev/sdg1。
/ `' b+ k, v0 W' V$ ?* R' ~/ o# L& Q6 }/ \
这里要解释 为什么是ceph-osd-i 0?在此条命令中, -i 后面可以跟任何一个整数,在get-journal-uuid中会被忽略。但问题是,不加-i, ceph-osd格式检查就会报错。2 V7 i3 w- `6 i: x7 r1 r3 ]* W
& R" Z7 D' y* F
还有就是—get-journal-uuid,字面意思好像是获取journal分区的uuid,但实际上返回的一个叫journal.header 结构体里的fsid. 此fsid的值就是 osd 数据分区的uuid. 所以命令ceph-osd -i 0 --get-journal-uuid --osd-journal /dev/sdk6 返回值是osd_uuid。不得不抱怨一把,这个命令太容易让人产生混乱。理清逻辑是从源码中分析得来的。从这个小问题可以看出开源软件比起商业软件,细处略显粗糙,还需精细打磨。3 Q9 Y/ M5 ?. |' d& ^( Z7 X- D
0 n6 y3 Q; U3 z5 _4 G- e # y/ r0 d! Z( M5 ?7 G
0 {+ \9 c7 H }
c. 如果prepare不显式指定 journal, 如 ceph-disk prepare /dev/sdg, 则处理逻辑为:* U* Y4 L- [8 c5 Y6 i
( g4 T" ]1 A* ?3 f在sdg上划出两个分区,sdg2 为20G的journal分区,sdg1为剩下空间大小的osd 数据分区。
j! S# t- _3 y% c+ Z4 ~
1 u: u! Q2 s, T J7 b
1 v# |3 o b6 G6 m& X5 {- x. C' Y0 E- J
5 A3 y3 }+ ]) H3 r
" k/ n! A( x& I7 l8 A
/ O. c2 ?% x/ q
* N0 @9 V5 g) e; K% k9 m注意事项
, }- q! s. ^4 M! u( F$ W1 F ]7 g) m8 n* x1 U9 i
Ceph-disk的定制:% R( g1 O0 P/ e% \; x3 p
# C, l. J; v ~- q9 y! z+ \$ S8 V+ ~
1. default fstype ext4
3 f) D* v$ i5 i1 Y/ T! a7 l2 N; I8 o
2. keyring的问题,由于目前的ceph部署没有enablekeyring,所以屏蔽了相关代码。. A* s4 d6 H& N
4 _- f* }/ W9 q- }# F: Dceph-disk –v将打印更详细的log, 如果想深入理解ceph-disk命令的运行过程,此参数非常有效。
, w! {. D* F$ Q& H e' ?! G$ Q+ i7 u' c
权限问题:; x4 p' q- M! s% o: B2 s
9 J; @: C7 \6 b) mchmod -R 777/home/ceph/software/ceph/var/lib/ceph/osd/ceph-*
# E O5 q& f" D- Z' W% L
5 M( n4 i! A% ~1 E. d删除OSD产生的死链问题。 |
|