|
|
楼主 |
发表于 2022-7-18 17:38:08
|
显示全部楼层
ceph-disk 是如何工作的?/ F9 ~! o9 i- h
6 x$ f* `) V( {+ X |- \) x3 g通过ceph-disk 部署osd, 数据分区和journal 分区将自动挂载到正确的目录,机器重启也能保证工作。通过ceph-disk部署osd, 将大大提高ceph部署运维的自动化程度,并降低操作出错几率。
8 [9 _7 X* T4 k9 h- _) x( `3 ^7 F4 Z7 v0 Z+ @( d1 @4 {0 x
以新创建OSD为例,描述ceph-disk的工作机制。9 ^- l5 @. X7 m, Z6 D; C( Z9 H
: Q$ V7 g F( s" V- V! F! h4 `! _, L
分为两大步骤:prepare disk 和activate disk
, |* {8 i/ Q7 h+ v, [1 V( x8 _ {' I+ [. Q% Y, v
假设/dev/sdg是OSD要使用的数据盘, /dev/sdk 是SSD, OSD要使用的journal分区在这里创建。则创建OSD 并上线的命令如下:
1 G: m1 u" O/ P/ }4 W0 O; K& C4 H# X
Ceph-disk prepare /dev/sdg /dev/sdk
' N- z8 t+ L$ Q9 k) Q2 Y6 U3 ~ t6 v/ i
Ceph-disk activate /dev/sdg1: Z( Z. n* u9 ~* |* ]
5 K" Y( ^% @9 Q7 T7 I下面详细深入其过程。$ T' ]3 F/ t% W# L7 S- ]( Q- L4 ~
( x. | c _) D# J1. 准备journal分区。
& C0 d4 Y: d& W; w2 A4 C5 Q
1 l# Q5 i1 D0 i% x( v$ V: n& i, [& ^Prepare_journal_dev()调用分区工具sgdisk从/dev/sdk上划分一块journal分区。
4 j( w! E' p3 m' T" C1 z) ^
9 S. X ^* G# h3 P有以下注意要点:: R) T) T8 o( U
% \8 P/ K/ Q5 X/ c' [6 F
a. 在调用sgdisk之前,prepare_journal_dev()会获取ceph.conf文件中指定的osd_journal_size大小,我们的ceph.conf指定大小如下:+ p. z* l$ ? r+ n
+ t6 c( o" e, W1 c1 O4 X
* E" E. f' Q" \: u5 g" `5 v' D2 j3 {
( J. i$ x% }' C! y0 R3 h9 D I
- @5 A8 q9 G( Jb. 实际部署环境中,由于作为journal的ssd分区并不需要很大空间,所以一个ssd很可能被多个osd共享来划分各自的journal分区,我们的环境是,一个300G的ssd 划分成5个(甚至更多的)20G的分区,挂载成5个osd的journal.- p$ J! g* p* l& u
. X; L& \6 I" e) Jc. Ceph-disk 在部署journal分区的时候,能自动侦测SSD盘已有分区数,不破坏已有分区,分配不冲突的新分区号来创建分区。
( Q6 A+ W- Q" A" t3 P) s# R
+ F' d7 p8 d; R8 r) @/ u" _8 W7 Md. 如果不指定创建分区的uuid,ceph-disk会自动为journal分区生成一个,称之为journal_uuid.. T* d, n" F8 B/ d$ K
9 h+ G3 O& h7 F$ l4 Z N; we. 在调用sgdisk的时候,还有一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建journal的typecode:
3 f5 K* k* V' t- X; F; S: p- }( ?/ Y" v9 o0 R3 l+ r! ^( _. y
3 K; r' p0 }. E0 D4 @" B4 f
- h& k7 r# D8 } t至于为何用此特殊UUID做typecode, 基本上此UUID可作为辨识分区为ceph journal的凭证,稍后深入解释。
/ _4 ~0 P. l* `0 c p! p$ q, c; B( t3 ~4 y7 S. \& R
至此,prepare_journal_dev()已经准备好了sgdisk所需的各个参数,下面给出一个实际发生的参数例子:
0 n- N4 x3 m5 F! c+ e5 K, a, \# U
5 K0 D* x8 J* u7 r) e2 y% u6 X, t! Q/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
2 ]" [: w" p" p1 z
2 o/ |$ ^7 h" ]) S9 V3 k i2. 在目录/dev/disk/by-partuuid/下为此journal分区创建link:% J }) y, z" n7 z; s4 d2 s' o. T+ x
/ i. Y1 Q/ @" h
; t% z( s: W) f) j, y& r
- J; n, v# H1 q1 t0 i ! t# Z" K+ g/ r) Q
# N' E5 D- u* J0 ]简单介绍一下这个link如何产生的。
+ F. d& H; b% V' p/ K/ p' }2 A) b1 e' B' q% g2 Y4 c8 I
在调用sgdisk 创建完journal分区后,ceph-disk 调用partx更新分区表,会触发一个块设备/分区udev event并通知到内核。Ceph编写了udev规则文件如下:# ~8 j4 n% X9 s) ~: G; V2 f u
, z# s |- i0 ]' e* ~3 B2 J0 I / A' D; Y+ g; C; s U) S
5 `% N" a5 M) K; G$ j( L
: ^4 D: Q' [) G6 n! t, J* B
& g) t4 V) c- N8 T1 `. G& N) Z7 r
Udev daemon在收到由partx产生的udev event后,根据以上的ceph规则文件,将调用/usr/sbin/ceph-disk-udev脚本。正是在这个脚本里,在目录/dev/disk/by-partuuid/下为此journal分区创建了link。此脚本还有另外一个扫描OSD专属分区的功能,后文会提及。暂时不表。1 w) Y5 D; B% M( y
& i4 B% \5 S5 A3 w
9 g9 w3 D, p3 l
9 Y2 `' ]& v8 I) z7 L- k$ X( F这个link有什么用?6 F4 g' [* j' g, U R/ s
0 o# F2 c6 a% `+ S由于这个link是根据partition uuid生成的,可以把它看成是到特定journal分区的固定映射。后文会指出osd的journal将映射到此link:
% Q6 R/ Q: [ v. p7 Q: ^: y3 Y- ^. w9 {2 P% O( U
' H1 x: ?1 X" m$ n) s X, R' j; t2 B; W9 T% \; S
% h5 Q! V" A9 q! ]- \# V: _! b6 u! R( l% ?1 B
由此图看出,位于osd 数据分区里的journal是一个link,指向一个固定的位置:/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa, 再由这个link指向真正的journal分区,由此解决的盘符漂移带来的问题。下文介绍的osd 数据分区的link也是基于此原理。
, _ J* ^2 k( Q8 ~
0 t2 @5 O3 A- {- S/ ^
5 a% I {$ w+ G" h. ^4 i& U* w' H. ]3 e5 s( K6 [
3. 准备OSD数据分区。- K& k8 R$ ^" \' K% E& U8 s
. `' \/ u$ U: W4 I" U% g这个过程跟准备journal分区大体一样。区别在于:
% f' `0 U. p9 b% ^2 V* `
9 \, q) o3 T* L- z, f4 Ma. 调用sgdisk 使用—largest-new来使用磁盘最大可能空间。所以/dev/sdg会有一个分区sdg1,它使用所有的空间。5 T, N2 I! Z$ T$ {
* |3 W2 f; Q: j2 B4 M
b. 格式化/dev/sdg1。这里对ceph-disk做了小的定制,默认使用了ext4分区格式。5 T; `" o: ?, T! ~
+ |" x. O4 `6 Y5 I! \- [. W4 V# {
c. 将此分区mount到一个临时的目录,然后再其中创建一个名为journal的link,指向/dev/disk/by-partuuid/c6422c03-d320-4633-b35d-4f43c6cdd9fa。至此,OSD的journal分区映射完成。最后umount。
' R$ m( L7 {0 C3 Z' L
8 p3 y: K% s8 J9 L% O+ }d. 再次调用sgdisk,写入一个重要的参数,--typecode. Ceph-disk 使用一个特殊的UUID 作为创建OSD的typecode:
# y7 X0 _$ j% x4 k! J; O1 \# a
! f) E# P7 f3 R; j! q! H* |9 q- m) Q5 b
D/ U, Y% C( p) l' C/ m8 m# C6 T6 K同JOURNAL_UUID, 为何用此特殊UUID做typecode, 是因为此UUID可作为辨识分区为ceph OSD数据分区的凭证,稍后深入解释。
3 ]0 Z. Q7 R G! S" R- E! |9 F3 J& A+ Z* m4 K3 |
1 m8 a' ]* ?% u/ ^7 k8 U4 t/ D6 D
- ]/ \5 i4 }& L! |4. 在目录/dev/disk/by-partuuid/下为此OSD 数据分区创建link。
9 S0 L1 z; K" t5 {9 C2 A! N7 r# p5 n$ a6 S: n/ F! _, R+ \
过程同journal的link创建过程。
: Q' |( j) J3 r; K& p8 x8 ^) k' }2 ?2 m# p7 ~) M1 Z- X3 o- Q; E7 e
% I0 t& b+ g7 [" ^! ~ Z# O( C; y7 b
! }) v7 o- E0 l% ]) m7 C5. Activate过程。# G5 j5 [9 P" ^0 y+ h/ R1 P
I7 s- U1 X; o& ?3 Q2 [9 O
Activate的命令是 ceph-disk activate /dev/sdg1。5 k+ Y. g( c3 q B/ w
0 E2 @. N: H# O7 O; H d) u5 S# u但其实并不需要显式的调用这个命令。原因是,准备好OSD 数据分区后,udev event 触发了ceph-disk-udev。而ceph-disk-udev会自动调用ceph-disk activate /dev/sdg1。; Q. R0 Z j5 q p
& J: i) b6 v9 \3 a
下面介绍这个过程是如何自动化的。详情参见ceph-disk-udev脚本。
7 N V ^2 m) i3 S9 o! Q7 c, R) j1 _3 [ o c0 R
新的OSD 数据分区的生成,触发udev event, 通过ceph udev rule,最终调用ceph-disk-udev,分析该分区的typecode,发现是OSD_UUID,即表明是ceph OSD的数据分区,于是触发ceph-disk activate /dev/sdg1:. W# h( V; r8 O* h$ s+ W7 e/ _0 f
6 n$ s8 C t# ]: o
' k( ~* K1 f4 ]! m' g
1 b4 R! F4 _/ |7 l; T
( [: A0 i, G1 |
2 i3 Y: Q9 `8 h. mTypecode 为JOURNAL_UUID的情况也一样,只不过是通过ceph-disk activate-journal 来启动OSD.
5 G |8 L/ D- K
% } T: U) y1 h8 [' V在介绍ceph-disk activate /dev/sdg1的具体流程。
$ I4 `- g! B9 e; G0 I! E# Q9 g# B7 y; I) W
a. 将/dev/sdg1 挂载至临时目录,一般为var/lib/ceph/tmp/mnt.xxx$ z' n. R2 h v: s; o. D! K8 s
" z1 g! u- y0 eb. 分配OSD id,及调用ceph osd create 产生 osd id
) _1 }) m: k2 o6 C' i7 _# J U$ C, N& t8 c. q
c. 初始化OSD, 如ceph-osd –mkfs –osd-data –osd-journal0 C3 F/ s9 `- h1 V0 W
: A6 q! H8 R# Q* p* G7 N+ S2 k
d. 根据osd id 重新挂载到最终目录: var/lib/{cluster}/osd/ceph-{osd.id}
( c( w+ E- V2 J2 q& _1 D% F) P( q* B& B, E/ U
e. Service ceph start osd0 f& Z" M- u) y; p- y
+ [7 t* @. U/ \( C" m; |$ p" e对于osd id 已经存在,重启osd的case,也会用到ceph-disk activate,这种情况稍有不同,不需要产生新的osd id,只需要将/dev/sdg1挂载至临时目录,获取osd id后,重新挂载到最终目录。5 I/ l. l% p$ H
; M0 r1 K) x- p" j7 k
) w) @! M) j d Y6 G
2 P: ^& i- Q' W9 P0 B9 I0 w0 r) _" [0 RCeph-disk 支持的其他命令如下:4 k& i( y3 I& _9 a) B! v
u5 R" U/ H& [/ L
prepare Prepare a directory or disk for aCeph OSD! u( T- i- w" L' B% n! c
1 f5 w7 R+ Y J& | activate Activate a Ceph OSD0 }+ f+ K5 W% w5 ~2 C2 m
# ~- _" k% A5 C$ I8 C/ L' k+ U activate-journal Activate an OSD via its journal device9 r; E; ?. `( [. n: N( i: V6 I$ F
- d) D- e+ o8 n& A! A+ q0 ^3 I
activate-all Activate all tagged OSD partitions0 o$ _" L4 N! _- s( O, j6 U
6 g, s. Y% P" {! x' W$ W$ Q
list List disks, partitions, and CephOSDs
" ?$ j, s( j6 E5 H9 E A$ Z2 q, k; A9 m0 M7 U) K$ I# t
suppress-activate Suppress activate on a device (prefix) {7 d( {: M$ ~- T/ l% R
( P B! E& b: b+ z; V1 O% K unsuppress-activate; b$ q, j& f5 }+ m# \
* z) i6 v0 X% q4 b% g
Stop suppressingactivate on a device (prefix)& x( [) `" k$ ^
; e' |" D: }: ~
zap Zap/erase/destroy a device'spartition table (and
3 G: H* [# I- g7 W# x. I; v) K9 ]
% u4 w2 m: c. [) y# d6 [ contents) [+ H; n. _# n' D! x! X) y
* A/ T6 u, B |* F
特别强调几点:
/ e z8 I0 B2 {) _- ^# L6 a7 h5 P) J1 {% Q8 J1 S1 Q! L
a. Suppress的字面意思就是抑制,用在这里的意图主要是,如果只想prepare各个分区,暂时不想activate OSD(创建osd 上线),可以使用此命令,等到所有的分区都prepare好了,unsuppress 一把,再activate-all.+ Q E7 [, j* @# z( G
* v y( c: s$ {2 c0 R) x" f: D# xb. Activate-journal 是通过制定journal 分区来启动osd, 如:ceph-diskactivate-journal /dev/sdk6. Ceph-disk 执行的流程为:
( G! a) U" c) O5 y0 X
/ c7 W* B, p" J8 J! K通过 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。% m: S. b9 b6 j' P/ G# U4 E
. t. a7 A) X: c, L, V- I这里要解释 为什么是ceph-osd-i 0?在此条命令中, -i 后面可以跟任何一个整数,在get-journal-uuid中会被忽略。但问题是,不加-i, ceph-osd格式检查就会报错。
' {! `6 X/ j! O$ y
0 z3 s1 B8 \2 R+ I: l1 P: {/ @还有就是—get-journal-uuid,字面意思好像是获取journal分区的uuid,但实际上返回的一个叫journal.header 结构体里的fsid. 此fsid的值就是 osd 数据分区的uuid. 所以命令ceph-osd -i 0 --get-journal-uuid --osd-journal /dev/sdk6 返回值是osd_uuid。不得不抱怨一把,这个命令太容易让人产生混乱。理清逻辑是从源码中分析得来的。从这个小问题可以看出开源软件比起商业软件,细处略显粗糙,还需精细打磨。( Z' h. d% m% v* `6 e" R& v
/ _1 K% ~4 {& d0 c7 t! P+ m+ Z
; Q' m9 h1 z. Q& T; ]' M9 ?- f, u/ E* R- X
c. 如果prepare不显式指定 journal, 如 ceph-disk prepare /dev/sdg, 则处理逻辑为:" o6 \0 g' w" S ^! Q8 B' s
2 R4 T* I+ ]& v
在sdg上划出两个分区,sdg2 为20G的journal分区,sdg1为剩下空间大小的osd 数据分区。
J! G$ R) f& k9 V8 }
" H) R( I; o. n6 X
% _. V7 s" R8 w* c8 h: c6 C( ~' a* R/ S5 [" P8 j l
0 v" K2 e: h, ?) ^" O' j; s5 @% X* Y: \6 K
- X$ O6 D) @7 P8 @ W- d9 b
/ J0 { z& r0 h. S1 ?2 J, M
注意事项7 c0 D' G6 x- Y. w/ X" k
# }8 Z0 E0 u& L. aCeph-disk的定制:
+ z4 o0 k6 b) G. c8 P" Q% v0 m5 p2 I
N; s' }- f8 x0 p1. default fstype ext4
% S" {: a" H# d; _% X& ?3 q. Q
P. ~: U- f7 ~6 ^; w& `. r2. keyring的问题,由于目前的ceph部署没有enablekeyring,所以屏蔽了相关代码。: x3 X& s. N, [# d4 R2 H5 ?* g
) Z8 {$ Y! I2 Q( y- }ceph-disk –v将打印更详细的log, 如果想深入理解ceph-disk命令的运行过程,此参数非常有效。9 t" u9 C+ ]' C3 b
. b* c" s, g2 a* E. i
权限问题:
h; o5 E/ _8 i( M& d, }/ [" P$ i# M% f! X% j
chmod -R 777/home/ceph/software/ceph/var/lib/ceph/osd/ceph-*7 ^, m0 ~7 w) R; Q$ J+ X; T' A1 _0 ^
8 ^: f& @2 I4 B. J* [: `
删除OSD产生的死链问题。 |
|