こんにちは :-)
Airitech株式会社で、インフラ寄りのシステムやアプリケーション開発を生業にしている三宅です。
1回目でBootstrap構築が終わったので、2回目としてOSDの構築手順について書いていきます。
OSDとストレージデバイスとの関係
OSDはObject Storage Daemonの略で、名前の通りCephのオブジェクトデータを保存するためのサービスになります。
そのためOSDは、オブジェクトデータを保存先となるストレージデバイスと関連付けて構築することになります。
ここでは、OSD構築手順を説明する前に、OSDとストレージデバイスとの大まかな関係について説明します。
Filestore vs Bluestore
OSDのデータ保存のためのデータ構造には、LinuxFileSystem上に作るFileStoreと、ブロックデバイス上に作るBlueStoreの2つが用意されています。
下の図にあるように、FileStoreはLinuxFileSystemを経由するため、BlueStoreと比較してIO性能が悪くなります。
昔はFileStoreしかありませんでしたが、BlueStoreができてからはBlueStoreが標準となっており、FileStoreが使われることはなくなっています。
BlueStoreは、FileStoreの欠点を解決するために作られたという背景があります。
Bluestoreの構成
BlueStoreの内部は、以下の図にあるように3つの構成に分かれています。
これらの構成データが、ストレージデバイス上に保存されます。
内部ジャーナル/write-ahead ログ(WAL)
一般的なジャーナリングファイルシステムで使用されているジャーナルや、DBシステムのWALとほぼ同じ役割を持つものです。
データ書き換え時に障害が発生した際に、データを復旧させることを目的としています。
OSDに対してオブジェクトデータの書き換えを行うたびに、内部ジャーナルやWALの更新が行われるため、この部分のIO処理が遅いと、データ更新処理そのものが遅くなります。
内部メタデータ
OSD の基本的なメタデータが含まれていて、OSD に関する情報が保存されます。
オブジェクトデータの構造もこのメタデータに含まれているため、オブジェクトデータへの参照や更新を行うたびにこのメタデータにアクセスするため、この部分のIO処理が遅いと、データの参照と更新処理が遅くなります。
このメタデータは、組み込み型のKVS(Key-Valuse Store)であるRocksDBを使って管理されています。
データ
オブジェクトデータそのもの。
一番ディクス容量を使う部分になります。
HDDとSSDを組み合わせたBluestoreのストレージ構成
すべてのOSDのストレージデバイスとしてSSDを使うことができれば一番いいのですが、そうするとByte辺りの単価が高くなり、費用対効果が悪くなります。
かといってHDDをストレージデバイスにすると、内部ジャーナルやWAL、内部メタデータの保存先もHDDになってしまうため、性能問題が起きてしまいます。データ更新を頻繁にするシステムの場合は致命的な問題になります。
そこでOSDのBlueStoreでは、高速なIOが求められる内部ジャーナルやWAL、内部メタデータのストレージデバイスと、データの保存先となるストレージデバイスを、個別に指定して構築することができるようになっています。
この組み合わせのパターンには、以下の2つがあります。
WALデバイス+プライマリーストレージデバイス
一つのOSDに対して数GByteの容量のSSDしか割り当てられない場合は、以下の図のように内部ジャーナルやWALのみをSSDに保存する以下の組み合わせでOSDを構築します。
この内部ジャーナルやWALのみを保存するSSDのストレージデバイスを、WALデバイスと言います。
この組み合わせの場合、内部メタデータとデータがHDD(プライマリストレージデバイス)に保存されることになります。
DBデバイス+プライマリーストレージデバイス
一つのOSDに対して、HDD(プライマリストレージデバイス)の1%〜4%の容量のSSDを割り当てることが可能であれば、以下の図のように内部ジャーナルやWAL、内部メタデータをSSDに保存する以下の組み合わせでOSDを構築します。
この内部ジャーナルやWAL、内部メタデータを保存するSSDのストレージデバイスを、DBデバイスと言います。
DBデバイスの容量については、Sizing considerations を参照してみてください。
内部メタデータが、DBデバイスを超えるサイズになった場合は、溢れた分をプライマリーストレージデバイス(HDD)に保存するようになります。
溢れたメタデータで管理されているオブジェクトデータにアクセスする際は性能が落ちるので、DBデバイスのサイズ設計には注意が必要です。
【補足】
厳密にいえば、内部ジャーナルとWALの保存先は、DBデバイスとプライマリストレージデバイスのうち、どちらか高速なストレージデバイスに保存するようになっています。
そのため、必然的にDBデバイス側に内部ジャーナルとWALが保存されることになります。
LVMを使ったOSD用ストレージデバイスの構成
SSDとHDDを組み合わせた構成の場合、だいたいDBデバイス+プライマリーストレージデバイスの組み合わせて構築することがほとんどです。
その場合、OSDの数だけSSDを用意するのは費用対効果として効率が悪いので、LVMを使って以下のように1つのSSDデバイスを分割して使用することになります。
プライマリーストレージデバイスとして使用するHDDについては、一つのOSDに対して一つのHDDを割り当てるため、上記の図にあるようにLVMを使わずに直接ストレージデバイスを指定することもできます。
しかしストレージデバイスの名称(/dev/sda)では、OSDとの対応付けの管理が煩雑になってしまします。そこでOSDとの関連付けを把握しやすいLV名称とすることで、構築時や障害発生時の人為的ミスが発生するリスクを減らす工夫をしています。
【補足】
ストレージデバイスを増減させたのちに再起動すると、ストレージデバイスの名称(/dev/sda)が再割り当てされるため、ストレージサーバのストレージデバイスを名称だけで管理するのはトラブルの元になります。
それもあり、LVMのLVを使って名称が変わらないようにしています。(LVM内部ではUUIDでストレージデバイスを管理しています)
DBデバイス用SSDが複数ある場合のLV構成
プライマリーストレージデバイス(HDD)を多く搭載できるストレージサーバの場合、一つのSSDだけですべてのOSDのDBデバイス分の容量を確保できない場合、複数のSSDを使ってDBデバイス用LVを構築することになります。
その場合以下の図にあるようにDBデバイス用VGに対して、必ず1つのSSD(PV)をアサインしてLVを構築します。
一般的には、以下の図にあるように1つのDBデバイス用VGに対して複数のSSD(PV)をアサインする方が管理が簡単に見えますが、SSDに障害が発生して交換が必要になった場合、どのOSDに影響が出るのかを判断することができなくなるという問題が発生します。
その結果1つのSSD交換を行うために、そのホスト上のすべてのOSDを停止しなければならなくなります。
OSD構築手順
それでは実際にOSDを構築する手順を説明します。
ここでは、以下の図にあるOSDを1つのCephホスト上に構築する手順について説明します。
前回のBootstrap構築で構築した5つのCephホストに対して、ここで説明する手順でOSD構築を行います。
これ以降の説明は、5つのCephホストのうちのceph-node002に対してOSDを構築する手順となります。
Type |
Device Name |
用途 |
SSD |
/dev/sdb |
DBデバイス |
HDD |
/dev/sdc |
プライマリーストレージデバイス |
HDD |
/dev/sdd |
プライマリーストレージデバイス |
HDD |
/dev/sde |
プライマリーストレージデバイス |
HDD |
/dev/sdf |
プライマリーストレージデバイス |
【補足】
ここは、説明をシンプルにするためHDDを4つにしていますが、実際にはHDDを16玉ぐらい搭載できるストレージサーバで構築することが一般的です。
各ストレージ用LV構築
ceph-node002上に、DBデバイスおよびプライマリーストレージデバイス用のLVを構築する手順を説明します。
DBデバイス用LV構築
以下のコマンドを実行して、DBデバイス用VGを作成します。
[xxx@ceph-node002 ~]$ sudo pvcreate /dev/sdb
[xxx@ceph-node002 ~]$ sudo vgcreate vg_db_0 /dev/sdb
上記で作成したVGに対して、DBデバイス用LVを4つ作成します。
作成するLVサイズについては、VGの何%を使用するのかを指定します。
ここでは1つのVGに対して4つのLVを作成するので、パーセンテージには25%を指定します。
[xxx@ceph-node002 ~]$ sudo lvcreate -l 25%VG -n lv_db_0 vg_db_0
[xxx@ceph-node002 ~]$ sudo lvcreate -l 25%VG -n lv_db_1 vg_db_0
[xxx@ceph-node002 ~]$ sudo lvcreate -l 25%VG -n lv_db_2 vg_db_0
[xxx@ceph-node002 ~]$ sudo lvcreate -l 25%VG -n lv_db_3 vg_db_0
以上で、DBデバイス用LVの作成は完了です。
プライマリーストレージデバイス用LV構築
以下のコマンドを実行して、プライマリーストレージデバイス用LVを作成します。
[xxx@ceph-node002 ~]$ sudo pvcreate /dev/sdc
[xxx@ceph-node002 ~]$ sudo vgcreate vg_data_0 /dev/sdc
[xxx@ceph-node002 ~]$ sudo lvcreate -l 100%FREE -n lv_data_0 vg_data_0
これで1つ目のプライマリーストレージデバイス用LVの作成が完了しました。
同じ手順で、残りの3つを作成します。
[xxx@ceph-node002 ~]$ sudo pvcreate /dev/sdd
[xxx@ceph-node002 ~]$ sudo vgcreate vg_data_1 /dev/sdd
[xxx@ceph-node002 ~]$ sudo lvcreate -l 100%FREE -n lv_data_1 vg_data_1
[xxx@ceph-node002 ~]$ sudo pvcreate /dev/sde
[xxx@ceph-node002 ~]$ sudo vgcreate vg_data_2 /dev/sde
[xxx@ceph-node002 ~]$ sudo lvcreate -l 100%FREE -n lv_data_2 vg_data_2
[xxx@ceph-node002 ~]$ sudo pvcreate /dev/sdf
[xxx@ceph-node002 ~]$ sudo vgcreate vg_data_3 /dev/sdf
[xxx@ceph-node002 ~]$ sudo lvcreate -l 100%FREE -n lv_data_3 vg_data_3
OSD構築
上記で作成した4つのDBデバイス用LVとプライマリーストレージデバイス用LVを使って、OSDの構築手順を説明します。
注意する点として、OSDを構築するコマンドを実行できるのはcephadmを実行することのできるbootstrapノード(ceph-node001)上だということです。
OSD追加前の事前設定
OSDを追加するたびに既存のOSDとの整合性を取ったりスクラビングなどの処理が走るため、全てのOSDの追加が完了するまでの間、それらの機能を以下の手順で一時的に抑止します。
まずは以下のコマンドを実行して、スクラビングの無効化を行います。
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph osd set noscrub
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph osd set nodeep-scrub
次に以下のコマンドを実行して、バックフィルおよび復元機能を制限します。
[xxx@ceph-node001 ~]$ cephadm shell -- ceph tell osd.* injectargs --osd-max-backfills 1 --osd-recovery-max-active 1 --osd-recovery-op-priority 1
OSDの追加
次に、以下のようにコマンドを実行してOSDを追加します。
cephadm shell -- ceph orch daemon add osd [Cephホスト名称]:data_devices=[プライマリーストレージデバイス用LV],db_devices=[DBデバイス用LV]
[Cephホスト名称]にはOSDを追加するCephホストの名称、[プライマリーストレージデバイス用LV]にはCephホスト上に構築したプライマリーストレージデバイス用LVの/devからのデバイス名称、[DBデバイス用LV]にはCephホスト上に構築したDBデバイス用LVの/devからのデバイス名称を指定します。
今回の例ではceph-node001上にOSD用LVを生成しているので、以下のようにコマンドを実行してOSDを追加します。
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph orch daemon add osd ceph-node002:data_devices=/dev/vg_data_0/lv_data_0,db_devices=/dev/vg_db_0/lb_db_0
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph orch daemon add osd ceph-node002:data_devices=/dev/vg_data_1/lv_data_1,db_devices=/dev/vg_db_0/lb_db_1
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph orch daemon add osd ceph-node002:data_devices=/dev/vg_data_2/lv_data_2,db_devices=/dev/vg_db_0/lb_db_2
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph orch daemon add osd ceph-node002:data_devices=/dev/vg_data_3/lv_data_3,db_devices=/dev/vg_db_0/lb_db_3
OSDの追加が終わったので、事前に無効化していた機能を復活させます。
まずは以下のコマンドを実行してスクラビングを有効化します。
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph osd unset noscrub
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph osd unset nodeep-scrub
次に以下のコマンドを実行して、バックフィルおよび復元機能を元のdefault値に戻します。
もしdefault以外の値に設定していた場合は、事前に設定していた値を設定してください。
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph tell osd.* injectargs --osd-max-backfills 1 --osd-recovery-max-active 3 --osd-recovery-op-priority 3
これで、ceph-node002へのOSD追加は完了です。
以下のコマンドを実行することで、その時点でのOSD数を確認することができます。
[xxx@ceph-node001 ~]$ sudo cephadm shell -- ceph orch ls 2> /dev/null
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
crash 5/5 7m ago 16h *
mgr 2/2 7m ago 16h count:2
mon 3/3 7m ago 16h count:3
node-proxy 0/0 - 16h *
osd 4 7m ago - <unmanaged>
あとは、残りのceph-node001、ceph-node003、ceph-node004、ceph-node005に対して上記の手順でLV生成とOSDの追加を行います。
以上で、OSD構築手順の説明は終わりです。
この段階で、RBD(RADOS Block Device)が利用可能となります。
これで最低限のCeph機能が利用できる状態になったので、次回は監視サービスの設定について書く予定です。
それではまた :-)