|
|
楼主 |
发表于 2022-7-18 17:38:08
|
显示全部楼层
ceph-disk 是如何工作的?
, C. l2 D3 e" x, @( d) Q
* @: ]! i; w' R* a* S+ ?通过ceph-disk 部署osd, 数据分区和journal 分区将自动挂载到正确的目录,机器重启也能保证工作。通过ceph-disk部署osd, 将大大提高ceph部署运维的自动化程度,并降低操作出错几率。
1 V& C) {+ {9 ?+ M3 s, A5 N; a$ A1 W' O
以新创建OSD为例,描述ceph-disk的工作机制。
% }8 A8 v0 G/ H2 Z8 i& _
3 f, z# ^/ n* Z2 V# U$ g分为两大步骤:prepare disk 和activate disk8 s/ w" u* H, R5 D& r, X6 \5 x
; F4 m0 M. A0 h. B" @ _2 H
假设/dev/sdg是OSD要使用的数据盘, /dev/sdk 是SSD, OSD要使用的journal分区在这里创建。则创建OSD 并上线的命令如下:6 N) u4 @* [0 G4 s( _( {
9 m i- W* N3 Y
Ceph-disk prepare /dev/sdg /dev/sdk
& H0 e6 T; u& c+ ]; J- f6 T' y* z3 Y: W7 y* M9 ]/ A# s. b
Ceph-disk activate /dev/sdg1
( Y6 Y( e! C: F- I
5 e3 O* a7 j" n9 Y. B+ y下面详细深入其过程。
" z5 y# e+ i9 h- Z) o
+ ^1 l2 s9 N8 z; s4 @! F# S1. 准备journal分区。3 t9 f9 S: K5 m# | I
7 u/ T+ M; R' O+ H( n {Prepare_journal_dev()调用分区工具sgdisk从/dev/sdk上划分一块journal分区。
2 c6 k! Y* L: S6 f) C
& D2 T' W0 B/ O有以下注意要点:
/ x' V. A% A& u; T! K k' r
$ s# E6 @ B* ya. 在调用sgdisk之前,prepare_journal_dev()会获取ceph.conf文件中指定的osd_journal_size大小,我们的ceph.conf指定大小如下:+ v$ b1 |7 v: |$ P. B& o
- b) L0 d; l% n* N
2 x$ a7 Q3 L3 X$ ]4 |7 t
0 M: {% N+ s. T; m! w3 z. a+ T; G5 {6 s' r. T1 i) s
% q1 ?9 ~/ R6 A8 H
b. 实际部署环境中,由于作为journal的ssd分区并不需要很大空间,所以一个ssd很可能被多个osd共享来划分各自的journal分区,我们的环境是,一个300G的ssd 划分成5个(甚至更多的)20G的分区,挂载成5个osd的journal.5 m" C9 {( D [5 a
6 F/ W: x: a7 g1 g' n% \; S
c. Ceph-disk 在部署journal分区的时候,能自动侦测SSD盘已有分区数,不破坏已有分区,分配不冲突的新分区号来创建分区。
4 }# H0 F/ J9 ~% o- |9 i9 J1 c# H% Y* M
d. 如果不指定创建分区的uuid,ceph-disk会自动为journal分区生成一个,称之为journal_uuid.+ H9 F7 v9 V) o9 e3 d
6 b& c! d+ h. \9 W. [* R
e. 在调用sgdisk的时候,还有一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建journal的typecode:. h1 E% T& T$ a' V5 H" @" ]2 ]. F
6 z) M! |. c# d0 g; J4 @
9 C0 o$ X' S! j0 `% M0 a1 c; L3 @9 y) j5 o& c$ ^0 I
至于为何用此特殊UUID做typecode, 基本上此UUID可作为辨识分区为ceph journal的凭证,稍后深入解释。+ d. o5 o/ L2 b3 `
) p! X' ~) v! Z6 v! e) A( Y
至此,prepare_journal_dev()已经准备好了sgdisk所需的各个参数,下面给出一个实际发生的参数例子:
; W# @- w& ~0 j" K0 T
0 O8 J% X( E- |( _5 O m. P4 c/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
6 c* I; J! _" U
$ z" M, g3 `6 n: V2. 在目录/dev/disk/by-partuuid/下为此journal分区创建link:
, I) M5 K- H/ {) L) K' D/ X0 M5 L
, _7 n5 B6 a8 n
: D# ?, Y$ Y6 h, i4 I" L% q( h/ F z
; ]! r$ D9 O- @/ B4 k5 ^: Y7 `8 U& x
简单介绍一下这个link如何产生的。
/ x( W, q4 n' |% }# U. B
, h5 H! [; ]5 c9 y6 N在调用sgdisk 创建完journal分区后,ceph-disk 调用partx更新分区表,会触发一个块设备/分区udev event并通知到内核。Ceph编写了udev规则文件如下:% _; @3 r+ T& k% n5 c) [. j: D
0 x M* i N8 R8 ]7 S7 S) O* g
# f, }, k2 i- } K9 o1 m( Q, Q4 w; A2 P- {9 j+ U/ Z3 |
. n' O. T1 w6 c- N! B o
+ s& M( X1 e9 W. ]3 I
Udev daemon在收到由partx产生的udev event后,根据以上的ceph规则文件,将调用/usr/sbin/ceph-disk-udev脚本。正是在这个脚本里,在目录/dev/disk/by-partuuid/下为此journal分区创建了link。此脚本还有另外一个扫描OSD专属分区的功能,后文会提及。暂时不表。
' G' c5 I& o% C% T1 @. Y4 e2 e% G4 r4 X1 u( `8 b8 R
: s3 {5 g6 [$ ]
* J% @+ G* v, ^这个link有什么用?( d- r: f9 }" Z b3 d/ Q- U
* k# d4 D; y, e* n* u) O- v: ~由于这个link是根据partition uuid生成的,可以把它看成是到特定journal分区的固定映射。后文会指出osd的journal将映射到此link:
. m& D H' X! u" m" O; V8 E8 `1 ]0 @$ j. j/ v5 u$ G
) M4 D* A$ u/ {$ g5 s
7 q( m5 K4 e; z( P! S
. Q& c3 s; A" ~ |5 N2 Y ^- p0 T& _
4 S! f) K; I& g: N% l. I$ n由此图看出,位于osd 数据分区里的journal是一个link,指向一个固定的位置:/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa, 再由这个link指向真正的journal分区,由此解决的盘符漂移带来的问题。下文介绍的osd 数据分区的link也是基于此原理。
8 q1 u* @/ _% A; o& R( \' Q+ m+ m( c9 Z( ?
- j |% i8 b* {% a3 x' |. K B/ d
7 j5 l' [9 T8 K4 p3. 准备OSD数据分区。
$ N- N) l3 W# g) e( z! B; ?2 p( i5 D Q2 r4 R( f
这个过程跟准备journal分区大体一样。区别在于:
" ~3 V U: s6 D' g( u1 a( v. i1 r$ Z6 {/ r' L
a. 调用sgdisk 使用—largest-new来使用磁盘最大可能空间。所以/dev/sdg会有一个分区sdg1,它使用所有的空间。+ B$ C9 i. ^" s. f2 u3 ?
( B+ S+ h. _# v- i* v9 sb. 格式化/dev/sdg1。这里对ceph-disk做了小的定制,默认使用了ext4分区格式。
& d+ o: r: U/ u# F! @3 {9 u; K, K5 K2 ]' U
c. 将此分区mount到一个临时的目录,然后再其中创建一个名为journal的link,指向/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa。至此,OSD的journal分区映射完成。最后umount。; ]4 X8 i* l0 n3 k2 y
& v) y1 G0 A3 D1 W
d. 再次调用sgdisk,写入一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建OSD的typecode:+ x; k/ o# E( o: m6 y
! O; d& N; |; v2 Q% s( Y+ }& O3 e, T/ D. [1 R
3 M3 v/ [, _1 i3 H/ y; N同JOURNAL_UUID, 为何用此特殊UUID做typecode, 是因为此UUID可作为辨识分区为ceph OSD数据分区的凭证,稍后深入解释。
, W; w& M; j) w+ D. t! E: k: o B
0 o6 _2 c) x& h5 S8 q4 L 2 i7 Q+ v! e" d* [
+ A+ G& K7 N) T( \" Y0 h4. 在目录/dev/disk/by-partuuid/下为此OSD 数据分区创建link。
8 u' D9 R! K6 A4 X' f
$ S! X3 S9 T1 l2 A5 l过程同journal的link创建过程。
! P( H% W1 W( j9 y' w5 y& F0 |( M5 j' l0 i% K
* y0 v( q% Y0 _# @9 z/ N
0 R; B/ e) h& O; _3 d0 n5. Activate过程。$ { w/ e& M7 x' n- x9 O( `9 N/ s* ~/ g
& t, I# ~* s* L! a4 K% n
Activate的命令是 ceph-disk activate /dev/sdg1。
- n1 ?2 A+ v# j6 f- |
& ~( m' W: Q* O& L! g# H2 \但其实并不需要显式的调用这个命令。原因是,准备好OSD 数据分区后,udev event 触发了ceph-disk-udev。而ceph-disk-udev会自动调用ceph-disk activate /dev/sdg1。
5 I1 |/ `# A6 Z) _9 o! H& J
4 W! H# D# w+ _8 u1 R# t' B下面介绍这个过程是如何自动化的。详情参见ceph-disk-udev脚本。6 f# r' {2 r- x2 o2 V& R& g4 f
6 a" C) Q0 M) m7 Q. [新的OSD 数据分区的生成,触发udev event, 通过ceph udev rule,最终调用ceph-disk-udev,分析该分区的typecode,发现是OSD_UUID,即表明是ceph OSD的数据分区,于是触发ceph-disk activate /dev/sdg1:( N- s# o' d4 O- b! Y/ S d8 k
9 ?9 K$ }4 w2 j5 x# C8 r4 r, D% K* Y8 _, a& f$ ?
( U3 ^$ I& R5 _2 X: A+ F3 A
, |3 P/ W2 R: p+ ~! D/ C# T* W6 \! `4 Y9 P- K+ _( f$ p
Typecode 为JOURNAL_UUID的情况也一样,只不过是通过ceph-disk activate-journal 来启动OSD.
( L* @! F) i8 M" `4 M
) h1 c4 S& V- ]4 ^在介绍ceph-disk activate /dev/sdg1的具体流程。 i6 J7 \+ ?$ W2 {& V1 d( P/ T5 t
3 Z& r# `8 j6 T* B
a. 将/dev/sdg1 挂载至临时目录,一般为var/lib/ceph/tmp/mnt.xxx
5 Y. ^: j6 n& d- e5 `
. e! p1 o- s$ b' e" tb. 分配OSD id,及调用ceph osd create 产生 osd id
Y" D: w; ^2 x& h0 `9 c/ Q% \3 T, D$ S- L) h9 r8 Z) s9 _
c. 初始化OSD, 如ceph-osd –mkfs –osd-data –osd-journal
3 d$ {" _/ |" }( u1 G! Y5 f8 O" i2 l! G
d. 根据osd id 重新挂载到最终目录: var/lib/{cluster}/osd/ceph-{osd.id}6 E' h- F; T6 @1 O, d, L$ t
# V0 q% ^4 z4 ]* T N5 be. Service ceph start osd
- Q. G1 r# q4 F y \, r$ t8 D0 g0 _" f7 ]2 o) y: K+ G
对于osd id 已经存在,重启osd的case,也会用到ceph-disk activate,这种情况稍有不同,不需要产生新的osd id,只需要将/dev/sdg1挂载至临时目录,获取osd id后,重新挂载到最终目录。
5 v& f: `4 Y) O) c9 k b5 o/ T* { B) e0 @0 x
6 N3 O; H6 x* ~2 l; ~, y' X2 K
$ `$ G4 u+ v+ q# ]5 s
Ceph-disk 支持的其他命令如下:
" u! m* t( O$ |! K' y7 C. H3 z1 m- ]2 Q4 m
prepare Prepare a directory or disk for aCeph OSD
: C! E- c3 e3 n9 F" h/ g! e5 P9 \8 W1 O
activate Activate a Ceph OSD& W5 `2 ]. R& Y7 X% B: A
( F& p3 z9 Q' |+ c- C' i
activate-journal Activate an OSD via its journal device
2 t( r5 y) d1 g5 z2 @2 t
5 q/ P' h- C2 C; s" q6 }$ ` activate-all Activate all tagged OSD partitions
# X! n5 D: _+ X- T
6 b8 k3 C3 C& R7 N list List disks, partitions, and CephOSDs1 t4 {$ s, J0 z$ |1 u, u" c+ C$ B
' A- X6 F3 [8 N- s- I; J+ o
suppress-activate Suppress activate on a device (prefix)2 `% g8 N @/ }& p& Z- ?1 }; b
" k) Z8 l% J5 I- j9 o5 \
unsuppress-activate
* u* w! a3 r, Q2 K! t0 x: R3 h# Q k$ P& O$ u
Stop suppressingactivate on a device (prefix)
+ O3 c8 x) x K& O$ c
5 V& u0 R! V Z zap Zap/erase/destroy a device'spartition table (and
. ]: v1 j& f3 C. r
9 ?2 t! }: r) [: X7 a( v contents)! h0 T" R2 b7 V/ P4 `/ |! H/ ~
+ j0 `3 j/ y4 Y; _9 b' }1 K J
特别强调几点:
' H6 _! w/ A J9 x6 Y1 M2 k$ P3 v' B( p
a. Suppress的字面意思就是抑制,用在这里的意图主要是,如果只想prepare各个分区,暂时不想activate OSD(创建osd 上线),可以使用此命令,等到所有的分区都prepare好了,unsuppress 一把,再activate-all./ Z0 k9 @9 R) p' S
. i2 Y; N* G, b1 Zb. Activate-journal 是通过制定journal 分区来启动osd, 如:ceph-diskactivate-journal /dev/sdk6. Ceph-disk 执行的流程为:/ o8 s( @" n C3 h4 U* c
7 q u/ Y! A* w! p3 S L通过 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。
1 o& U# p5 @# ]- n7 u) e/ F) x3 }8 J$ w: |
这里要解释 为什么是ceph-osd-i 0?在此条命令中, -i 后面可以跟任何一个整数,在get-journal-uuid中会被忽略。但问题是,不加-i, ceph-osd格式检查就会报错。% T6 w" @! ~3 L; c+ u
+ U, x R9 n& `( O+ \4 T- r4 X还有就是—get-journal-uuid,字面意思好像是获取journal分区的uuid,但实际上返回的一个叫journal.header 结构体里的fsid. 此fsid的值就是 osd 数据分区的uuid. 所以命令ceph-osd -i 0 --get-journal-uuid --osd-journal /dev/sdk6 返回值是osd_uuid。不得不抱怨一把,这个命令太容易让人产生混乱。理清逻辑是从源码中分析得来的。从这个小问题可以看出开源软件比起商业软件,细处略显粗糙,还需精细打磨。+ [$ R! G' v0 s- o f
. U& m& `) V8 E6 |8 U
/ @( M' C! d- T+ R) F
* w$ ~5 Z% L1 p6 R: ec. 如果prepare不显式指定 journal, 如 ceph-disk prepare /dev/sdg, 则处理逻辑为:
; C4 w6 u* Z3 k- r+ `* q+ _- \ I! u9 G! \- i; w% K
在sdg上划出两个分区,sdg2 为20G的journal分区,sdg1为剩下空间大小的osd 数据分区。
/ D/ t+ o+ y4 o$ ]* n) T' Q/ j( u9 G j
1 Q% r1 P6 ?0 `, N: u
+ R* k5 D8 h( x2 ?9 A' g* k
2 x5 Z2 M3 e/ |, K
) }+ T F2 k0 u; _, h. S2 c , w2 P: G/ Q) f8 f* T
( K9 G4 e, l' y" [- t" q1 `! P
注意事项* }. ^; f$ G$ {0 L J) [
/ m$ r7 D1 j& H, S- m4 W! jCeph-disk的定制:
* x# Y, T4 l# _$ V" y9 n0 h% n0 G9 U/ u! f, r& ^& p; M8 y
1. default fstype ext4
0 |5 J7 P. }3 H7 {
( K z. A* ?5 f2. keyring的问题,由于目前的ceph部署没有enablekeyring,所以屏蔽了相关代码。
8 }) d) T8 p! y9 k' C4 M6 P. `: f8 s
ceph-disk –v将打印更详细的log, 如果想深入理解ceph-disk命令的运行过程,此参数非常有效。/ _' }3 f* j! E: z$ w# N, u. W
9 X/ b+ P$ g0 b% a) ~/ @4 ]
权限问题:9 \- ]* c: M; b0 _. L4 H$ Z5 q9 M
/ P- g4 j+ ~" m% S
chmod -R 777/home/ceph/software/ceph/var/lib/ceph/osd/ceph-*
- P5 B6 w) L4 I0 A) f j5 {8 K. w- d
1 l! v. h5 w- Y# ?5 {/ I删除OSD产生的死链问题。 |
|