はじめに
こんにちは、Necoプロジェクトのsatです。Necoプロジェクトではサイボウズのクラウドサービスcybozu.comの次期インフラ基盤を開発しています。その根幹となるコンポーネントの一つがお客様のデータをあずかるストレージです。本記事ではNecoのストレージの本番適用に向けた取り組みの一つを紹介いたします。
たくさんの取り組みをしているのですが、ここではストレージシステムの運用にあたって、データを格納するRook/Cephクラスタの運用に必要なオペレーションを作る部分について扱います。
用語解説
ここでは本記事を読むにあたって必要になるCephの用語について、いくつか説明しておきます。
OSD
OSDとはCephクラスタに組み込まれる個々のディスク上に存在している、ユーザの実データを保存する領域です。Cephは自身を構成するノード上にあるOSDを束ねてストレージプールを作ります。
MON
Cephではクラスタの状態をMONというデーモンを使って管理しています。MONは複数個作って冗長化するのが一般的です。MONが複数個ある場合は、全てのMONがクラスタの最新の状態を保持するようになっています。
MONは奇数個作るのが一般的で、かつ、それらのうち過半数が正常動作していればクラスタにアクセスできます*1。そう出ない場合はクラスタにアクセスできなくなるので、後述の手順で正常動作するMONの数を回復する必要があります。
具体的な取り組み
ここからは以下の2つのオペレーションについて、それぞれどういう取り組みをしているかについて書きます。
- ディスクの削除、交換処理
- クラスタにアクセスできなくなった場合の対処
OSDの削除、交換処理
OSDの削除
Rook/Cephクラスタを構成するディスクが壊れた場合、その上に存在しているOSDをクラスタから削除する必要があります。この手順はCeph、およびRookの両方においてドキュメント化されています。
我々はまず、実際にこの手順に従ってOSDの削除処理を試してみました。すると、我々が使っているPVC-based clusterというタイプのクラスタでは、物理サーバ上にクラスタを構築するオンプレミス環境において、OSDをうまく削除できないという問題をあることを発見しました。なぜこういうことが起きたかというと、当時このPVC-based clusterはクラウド環境上で動作することだけを想定していたからです。
この問題についてはupstream Rookに対してissueを発行したところ、すぐにメンテナのかたがPRを投稿してくれて、私を含めた他のメンテナたちとも議論した末、無事にマージされました。
このように自分達が検出した問題を他の誰かが修正してくれるのは、OSS開発の醍醐味のひとつで、とても嬉しいものです。今後もこのようにupstreamコミュニティ全体で協力して、リソースを出し合って開発を進めていきたいと思います。
もう一点。OSDの削除についてはオペレーションコストを下げるために自動化ジョブが用意されています。しかし、このジョブについてのドキュメントが無かったため、公式ドキュメントに必要事項を追記しました。これに加えて、OSDの削除手順が全体的にわかりにくかったので、このPRにおいて整理して、ほとんどを書き直しました。
ここで手元の手順を作るだけではなくupstream Rookのドキュメントも修正する理由は2つあります。ひとつは、この手順に従って問題が発生したときにupstream Rookコミュニティの支援が得られるためです。もうひとつは、Rookの他のユーザが正しい手順を使えるようになり、Rookユーザ全員のためになるからです。
OSDの交換
続いてOSDの交換手順です。通常は運用中にOSDを削除するときは、削除したOSDのかわりに別の正常なOSDを追加します。ところがRookにおけるOSDの交換には専用のオペレーションが無く、一旦OSD削除処理をしてから別のOSDを追加する、という素朴かつ面倒なものしかありませんでした。
我々はこれを見直して、OSDを削除すると自動的に他の正常なOSDに入れ替わる手順を新たに作りました。この手順については、もう一度整理してからupstream RookにPRを送り、公式化を目指す予定です。
クラスタにアクセスできない場合の対処
上述のように、複数個あるMONのうちの正常動作しているものが半分以下になっていると、クラスタにアクセスできません。この場合はクラスタの外から働きかけて正常なMONが過半数になるように回復しなければなりません。
正常なMONが1つ以上ある場合
正常なMONが一つ以上ある場合は、正常なMONのデータを他のMONにコピーすれば問題を解決できます。この手順はCephにもRookにもドキュメント化されています。
まず我々はRookの公式手順に従えば実際にクラスタにアクセスできるようになるかを確認しました。その結果、一部について問題があることがわかったため、問題を修正するPRをupstream Rookに送付しました。
このPRは幸いにもすぐにマージされました。ただし、このオペレーションは手作業でやるには複雑なので、今後はなるべく自動化していこうということを他のメンテナと合意しています。
正常なMONがひとつも残っていない場合
正常なMONが一つも残っていない場合、MONのデータはすでに信用できないものになっているため、オペレーションはより面倒になります。具体的にはOSDに保存されているMONのデータのコピーを利用して、最新に近いクラスタの状態を復元することになります。これについてCephでは以下のようにドキュメント化されています。
このオペレーションについては残念ながらRookには対応するドキュメントが無かったため、我々はCephのものを参考に、一から手順を作り上げました。こちらについてもupstreamにPRを投げて、現在レビュー結果を反映中です。
こちらもMONが1つ以上残っている場合と同様、今後自動化していく予定です。
なお、本件についてはCephのマニュアルにも誤りを見つけたため、こちらについてもPR投稿中です。
今後の取り組み
オペレーションの手順ができたからといっても、まだまだ終わりではありません。まず既に述べたように、手作業によるミスを無くすためにさらなる自動化が必要です。それに加えて、次のようなことも必要です。
- 上記オペレーションを、今後プロジェクトに入ってくる技術者たちに共有する
- オペレーションが意味するところを理解するために、RookやCephについての知見を共有する。これができていないとオペレーション実行時にトラブルが発生しても対応できない
- 上記オペレーションが必要になった際にすみやかに実行できるように、定期的に訓練をする
- 社内用途で実際に使ってみる。ソフトウェアは実用してみてはじめて運用の勘所がわかると共に安定化してくる
今後もこれらの取り組みをどんどん進めていきます。
おわりに
本記事で話題にしたRook/Cephクラスタの安定稼働に加えて、ログ基盤の作成など、他にもやることはたくさんあります。ストレージ以外でもそれは同様です。参考までに、これまでに取り組んできたことについては以下リンク先の記事一覧をごらんください。
Necoプロジェクトはこれらの作業に一緒に取り組んでくれるかたを絶賛募集中です。我こそはというかたは、ぜひ以下URLからご応募ください。
*1:分散システムについてご存知の方に向けて書くと、これを実現するために分散合意アルゴリズムPAXOSを使っています