|
|
楼主 |
发表于 2022-7-18 17:38:08
|
显示全部楼层
ceph-disk 是如何工作的?: E, _* T/ T+ A$ M. ^& o7 O
k0 K6 |3 u5 c通过ceph-disk 部署osd, 数据分区和journal 分区将自动挂载到正确的目录,机器重启也能保证工作。通过ceph-disk部署osd, 将大大提高ceph部署运维的自动化程度,并降低操作出错几率。9 f5 l, ]" X. \% f" Y
7 I/ C! i5 ~' p
以新创建OSD为例,描述ceph-disk的工作机制。$ _! W$ V0 r# U: s
2 Q* Y( T7 E! i; _4 M分为两大步骤:prepare disk 和activate disk
9 q4 T6 ]& N# J4 `6 m8 o2 J" i0 X: d" b" a9 x- r
假设/dev/sdg是OSD要使用的数据盘, /dev/sdk 是SSD, OSD要使用的journal分区在这里创建。则创建OSD 并上线的命令如下:+ `1 u( @* B7 k0 y e
7 S/ q' u7 t/ [Ceph-disk prepare /dev/sdg /dev/sdk
0 M+ e7 H/ K& Z H J8 |2 r% e& h9 `4 }7 d) e
Ceph-disk activate /dev/sdg1( Q& L3 z1 q# k+ B; ^7 _, M
0 C3 H$ B' [% x8 {. a# W$ J8 |下面详细深入其过程。0 w& L5 v! U$ {1 C) W
: Z. n7 v5 \! C" F* ~" H8 K) ~
1. 准备journal分区。5 N3 I# B( C; Q4 x
, Z0 E% ^2 X0 m6 @* v% [' MPrepare_journal_dev()调用分区工具sgdisk从/dev/sdk上划分一块journal分区。 V. g5 q* i; I
# Q. t3 p, V/ T0 M, e4 C" b
有以下注意要点:+ H+ O9 n4 G+ P* `$ t! I+ h
$ N) M- b0 @, xa. 在调用sgdisk之前,prepare_journal_dev()会获取ceph.conf文件中指定的osd_journal_size大小,我们的ceph.conf指定大小如下:
( A/ B3 J. b9 W9 u2 s2 j8 m6 a8 L! U, r$ Z1 C
, a2 d: X9 r1 s. f9 h$ U& b
8 C1 m1 `6 ~$ V0 R# s; m* }+ `5 F+ J0 A& i a. j: I6 v* C* D$ @
+ n$ h7 K6 k# ?# U) a
b. 实际部署环境中,由于作为journal的ssd分区并不需要很大空间,所以一个ssd很可能被多个osd共享来划分各自的journal分区,我们的环境是,一个300G的ssd 划分成5个(甚至更多的)20G的分区,挂载成5个osd的journal.
" t7 r9 v7 p" T' p( e
# \4 R/ p3 P# vc. Ceph-disk 在部署journal分区的时候,能自动侦测SSD盘已有分区数,不破坏已有分区,分配不冲突的新分区号来创建分区。
2 m/ V' j" g+ f+ @* \
% z% K& n4 k: c3 nd. 如果不指定创建分区的uuid,ceph-disk会自动为journal分区生成一个,称之为journal_uuid.
3 M" v- t; k* j. ]/ v7 l& g9 ]3 m
3 `0 S1 a9 N0 E6 i# ye. 在调用sgdisk的时候,还有一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建journal的typecode:
- Y9 i1 k( f; W- n
- p/ y+ K# N3 F+ T; B8 A2 D" G* |: r% K+ X4 R# s$ u3 S
) K6 s/ r3 n- v) v# L4 K$ ^. u
至于为何用此特殊UUID做typecode, 基本上此UUID可作为辨识分区为ceph journal的凭证,稍后深入解释。4 \) ? ]: k' F( u( x4 g" D
Q3 P/ ?0 {9 W$ m4 j4 U
至此,prepare_journal_dev()已经准备好了sgdisk所需的各个参数,下面给出一个实际发生的参数例子:5 f" F0 ~8 [/ ~1 g: r9 l
4 ?! |; i7 P/ |* O2 w
/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
4 Y \/ G* ]% n' [6 ~& Y
# Q4 ~" J" ?3 K# z3 C( }2. 在目录/dev/disk/by-partuuid/下为此journal分区创建link:) v" ]* n" p. ]
7 Q5 o0 h# B$ D, f- d- O- c6 M- n4 d' E6 u: i
& H+ \4 e5 K" \: @( U6 `
. n+ r, ?3 c( z9 q1 C4 h4 i/ t5 u7 }/ d' g6 _" M- d
简单介绍一下这个link如何产生的。
( ^* ]2 X$ f' X Q
" F b2 Y6 T( D在调用sgdisk 创建完journal分区后,ceph-disk 调用partx更新分区表,会触发一个块设备/分区udev event并通知到内核。Ceph编写了udev规则文件如下:- x8 b6 N" n% K! v6 o
q# g- Z( g3 s0 ?/ U, [0 x
* E4 b: q8 Z% H! M
; r) L8 d6 O1 p. [8 W. d
. h( ]0 ?; W# h
: O/ X) |2 c' K: U- W0 d2 \Udev daemon在收到由partx产生的udev event后,根据以上的ceph规则文件,将调用/usr/sbin/ceph-disk-udev脚本。正是在这个脚本里,在目录/dev/disk/by-partuuid/下为此journal分区创建了link。此脚本还有另外一个扫描OSD专属分区的功能,后文会提及。暂时不表。: Y7 `1 m$ q- Z! S
9 v8 E$ ^8 m, k4 n/ f 4 b3 X3 _& M1 a9 \
; u! C% f% P5 y, c
这个link有什么用?) e) C7 Q* y x
$ w0 T$ G9 P; i4 ]% y# g% |4 M( x由于这个link是根据partition uuid生成的,可以把它看成是到特定journal分区的固定映射。后文会指出osd的journal将映射到此link:4 p4 ~9 v6 f4 i3 f. }7 X8 h5 b( z
" @8 t0 v% P$ w( M0 G/ s0 w! n7 P
$ z: _5 i& n) _
: [8 q% Z6 @0 [4 d( [" z* x0 `2 d& ~5 B5 T
' X, ^. \1 S) N: n/ ]由此图看出,位于osd 数据分区里的journal是一个link,指向一个固定的位置:/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa, 再由这个link指向真正的journal分区,由此解决的盘符漂移带来的问题。下文介绍的osd 数据分区的link也是基于此原理。5 P9 V, W* Z. i9 v
8 }# ^* k2 B7 K+ x2 B% u% y ! v1 ?& y) A3 e. _4 \
* m+ [- C$ [* V3 P7 }3 O3. 准备OSD数据分区。
: K: @3 s3 G* S: n( Q
4 N$ T5 A; c. v4 D7 L4 B6 t这个过程跟准备journal分区大体一样。区别在于:
0 k, @0 }0 V% X' O5 T
9 E0 F( q* ?9 U$ ?a. 调用sgdisk 使用—largest-new来使用磁盘最大可能空间。所以/dev/sdg会有一个分区sdg1,它使用所有的空间。
+ l" j1 ^0 c+ `. V- S: @' H! T7 k# g$ C g# s9 `
b. 格式化/dev/sdg1。这里对ceph-disk做了小的定制,默认使用了ext4分区格式。. o/ o1 S2 C- {/ a4 ~% h. B* p
0 A9 M( }' B( p; `c. 将此分区mount到一个临时的目录,然后再其中创建一个名为journal的link,指向/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa。至此,OSD的journal分区映射完成。最后umount。
- ?* [7 q* T! |* E" F% o1 ]! P, b- ^% U9 \& J& h0 Q
d. 再次调用sgdisk,写入一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建OSD的typecode:4 J3 u' V: q# }# P/ E
# d. d9 |4 p. o/ o
- ?! k2 y% k0 O! ^" T! |& v6 N6 G( w4 y* b: P+ v& c. B; L K# @
同JOURNAL_UUID, 为何用此特殊UUID做typecode, 是因为此UUID可作为辨识分区为ceph OSD数据分区的凭证,稍后深入解释。
3 L$ {6 D* R1 |0 q2 h H4 I: M7 n6 D2 n
~) k" U1 B, K; g
# W/ J4 E$ n& c1 @- Z+ c4. 在目录/dev/disk/by-partuuid/下为此OSD 数据分区创建link。" ?# h( W& x* k8 b' l
; g! G4 r$ j) p9 ]! _
过程同journal的link创建过程。
% K& W+ m9 I, E+ B' @5 g* \
6 w1 G3 B; {" t7 U" X. S/ a8 s* t0 N
! u6 p9 _1 s$ H, j1 j9 R% U
2 ?" o' c1 b6 h( [) t5. Activate过程。" ]7 I/ R `' v: y; l
' |1 r4 D' v+ y2 @# E& zActivate的命令是 ceph-disk activate /dev/sdg1。5 X4 D; t. l6 h3 N0 c
2 ^% X. S, a, ^* E
但其实并不需要显式的调用这个命令。原因是,准备好OSD 数据分区后,udev event 触发了ceph-disk-udev。而ceph-disk-udev会自动调用ceph-disk activate /dev/sdg1。
4 G2 M5 A+ h1 B4 V* X3 x
, P7 B/ v3 R6 }8 H/ ?+ M下面介绍这个过程是如何自动化的。详情参见ceph-disk-udev脚本。
K, o7 f0 q' }: A" J
' Y+ b9 Q$ s$ d新的OSD 数据分区的生成,触发udev event, 通过ceph udev rule,最终调用ceph-disk-udev,分析该分区的typecode,发现是OSD_UUID,即表明是ceph OSD的数据分区,于是触发ceph-disk activate /dev/sdg1:; I% G! c' ]# {; S }% Z
1 M2 Z# v4 [! b- }' B
7 s& @( L6 D' H2 b3 m0 y
6 ?# U- j T, f2 k+ \& b
5 B% A2 `7 B3 s; r' \. `% E) t
Typecode 为JOURNAL_UUID的情况也一样,只不过是通过ceph-disk activate-journal 来启动OSD.: J. q# r0 p2 n) r) |
& U- b7 [# ], g! J# {
在介绍ceph-disk activate /dev/sdg1的具体流程。
W( {3 h! }$ ~$ ]6 v4 a- j( [+ L/ ~' ^2 m
a. 将/dev/sdg1 挂载至临时目录,一般为var/lib/ceph/tmp/mnt.xxx
5 L' j& ?7 X- x% w, g: `
: O* w7 y, ~7 ]8 |! [/ jb. 分配OSD id,及调用ceph osd create 产生 osd id9 L$ e; t& {: L
+ c; Y( l# b8 c$ V. R* m6 g
c. 初始化OSD, 如ceph-osd –mkfs –osd-data –osd-journal- P2 H) R3 N f& _
" ^# z- N0 i4 _0 \d. 根据osd id 重新挂载到最终目录: var/lib/{cluster}/osd/ceph-{osd.id}
! ?1 v% }6 w- X4 }
( K* Z* r H* b& {. M, q6 P( je. Service ceph start osd7 Y! B- ~- M4 U8 C
2 E) \* e7 ?& k- I+ ?7 l对于osd id 已经存在,重启osd的case,也会用到ceph-disk activate,这种情况稍有不同,不需要产生新的osd id,只需要将/dev/sdg1挂载至临时目录,获取osd id后,重新挂载到最终目录。7 }$ S R1 f, T$ ?5 Y( y
# a0 G* T' V& b# P8 _# o" u+ w
5 B8 P; m5 j5 p1 ~/ a
/ d% O; }0 E. V8 mCeph-disk 支持的其他命令如下:2 K* Y. p" m& P' F. X; w8 b+ Y
9 k @& O& m# j& p" c prepare Prepare a directory or disk for aCeph OSD; I. C! ?6 s# k# f8 I X- t
& \; ?) V' W! f P* E* | activate Activate a Ceph OSD. {3 U3 ~6 a6 G* v( u9 }
% o \; N) n! D: x activate-journal Activate an OSD via its journal device
* j3 L, G$ E% h! m; I# n
4 j, a$ N B- J/ R- D activate-all Activate all tagged OSD partitions
" W' q) K/ @0 m1 ]: w8 ]$ t3 G) o& |( b! I- q
list List disks, partitions, and CephOSDs: g) }$ c, v% J- w
6 J7 h6 x. }- @+ l2 n
suppress-activate Suppress activate on a device (prefix) I% a' Y5 O% S3 R& i' t! M
3 w/ C1 C, _0 W, q+ _ unsuppress-activate
X6 k* }5 ~# f$ c
3 V, U4 w3 Y0 z* m; I Stop suppressingactivate on a device (prefix)% j$ n& G% A5 ?9 ]# W0 ]
" {0 C X' g* N( k" Z2 R zap Zap/erase/destroy a device'spartition table (and) T4 N. e) |4 [& z7 E4 r
7 s* s3 i/ y, g contents) Z; y- h' t9 m( G9 m% A' v6 t
. U7 w! L N9 L: u; U, Y特别强调几点:
, W0 M( O7 J8 ^. m: F9 r, | C9 ~# K5 ]6 R4 v
a. Suppress的字面意思就是抑制,用在这里的意图主要是,如果只想prepare各个分区,暂时不想activate OSD(创建osd 上线),可以使用此命令,等到所有的分区都prepare好了,unsuppress 一把,再activate-all.
+ U, U6 E5 Y7 y1 `* I1 v7 Y, z( w- `
b. Activate-journal 是通过制定journal 分区来启动osd, 如:ceph-diskactivate-journal /dev/sdk6. Ceph-disk 执行的流程为:
! N" \8 h; c/ M5 R7 n$ P5 u
+ S: ^" q# B2 J/ z通过 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。- N5 O, O3 Z- @
: O- W$ \, t/ K: ]
这里要解释 为什么是ceph-osd-i 0?在此条命令中, -i 后面可以跟任何一个整数,在get-journal-uuid中会被忽略。但问题是,不加-i, ceph-osd格式检查就会报错。
1 v0 h3 r8 V/ I9 e1 m
, |0 O$ ^7 e5 w! I* A' h1 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。不得不抱怨一把,这个命令太容易让人产生混乱。理清逻辑是从源码中分析得来的。从这个小问题可以看出开源软件比起商业软件,细处略显粗糙,还需精细打磨。$ ^ \' v: O. M" u) N7 u
$ M$ p0 q% p4 j/ q( r! r7 {
0 J: L+ X0 ^( c, Z* |* x5 P( N
c. 如果prepare不显式指定 journal, 如 ceph-disk prepare /dev/sdg, 则处理逻辑为:+ ]1 x( T3 ]5 Q& I. ]+ r% u
- H; h" G; o, T l在sdg上划出两个分区,sdg2 为20G的journal分区,sdg1为剩下空间大小的osd 数据分区。
% B0 f: z& M2 o& P: n8 K
: e, e" k1 {$ V! T' |$ c* c
- }- C8 r; d. s5 Z3 t( x2 A) W) {
9 }% c" O1 X$ z$ c# d- b - B( f- n$ a6 `) P2 B {; [+ Q
4 n+ t; ?: v# ~( t+ N
: \" q) F/ {2 a; s* ?" r. q! h+ O* F* l1 D- x# C
注意事项2 }) ?+ F; y8 Y( E6 `/ {8 }! e+ d9 o
0 h9 e: r8 G% c' X9 N% j$ p+ MCeph-disk的定制:- U' D5 W0 l) r( `' P( r; B, m9 n
) t) t0 t0 K. r
1. default fstype ext4$ c& b; O' w* o7 ?5 O2 b" R8 u
8 [* [# | Q- K# S/ E6 p B2. keyring的问题,由于目前的ceph部署没有enablekeyring,所以屏蔽了相关代码。
. P7 g# Q& e0 \" V5 ~' h
z$ _; N: W* W- ?ceph-disk –v将打印更详细的log, 如果想深入理解ceph-disk命令的运行过程,此参数非常有效。
0 U) F* A% X, w) B5 |, q4 ^4 r5 y& r. \
权限问题:7 f& l8 w! S, B8 X- w
4 V, L& l4 k: |3 [chmod -R 777/home/ceph/software/ceph/var/lib/ceph/osd/ceph-*
( m$ r: j. a* C" \' Q, v' n
5 `7 p" a. F+ w2 f! B' T% ~删除OSD产生的死链问题。 |
|