まいど。レッドハットでストレージを中心にクラウドインフラを生業にしている宇都宮です。
Rook 1.1がリリースされました。色々なアップデートがありますが、Ceph-CSIがproduction-readyで対応したことからCephにとって大きな一歩になるでしょう。
さて前回は、Rook-Cephで障害を起こしてみてアプリに与える影響がどんなもんかを見てみました。今回はちょっと座学的になりますがRook-Ceph CSIの紹介とアーキテクチャのお話しをしたいと思います。
去る9/11(水)にOpenShift Meetup #6が開催されました。雷雲うごめく中お越しいただいた皆様、ご登壇くださった皆様、本当にありがとうございました!
そしてもう次回のOpenShift Meetup #7の情報が公開されています。注目のService MeshとServerless特集です!Twitter枠は空きがありますし、名古屋、大阪、福岡のサテライト会場でもLive中継されまーす!
OpenShift Meetup #5のセッション動画がcrash.academyさんで公開されています。Operatorガチな方々のセッションをご覧下さい!
あとRookとOpenShift Japan CommunityのTwitterアカウントがあります。@japan_rookと@openshiftjpです。フォローお願いします!
以上宣伝でした!
CSI : Container Storage Interface
はいそれでは本題に入ります。Rook-Ceph CSIをご紹介しますがその前にCSIってナンダ?というお話です。
CSIって何よ
CSIはKubernetes以外にもMesosとかCloudFoundryとかいろんなコンテナオーケストレーターシステム(COs)から、いろんなストレージを使えるように標準化されたストレージ管理APIです。
CSIがあることでユーザーはストレージに縛られることなくCOを選ぶことができるし、ストレージプロバイダはCO毎にドライバーを作ってメンテしなくて済みます。また、CSIはCOのコアの部分から隔離される形で実装されます。よってCOの開発側としてはコアの部分に謎のドライバロジックを埋め込むリスクもなくなりますし、ストレージのドライバ部分はテストしなくて済みます。
三方良しなアーキテクチャとして前々から必要性は言及されていたのですが、Kubernetesではv1.13でCSI 1.0がGAになりました。こちらの通り、色んなストレージプロバイダがCSI driverをリリースしています。
ちなみにKubernetesでは"in-tree plugin"と呼ばれる、Kubernetesのバイナリに組み込まれているストレージのドライバーが何種類かありますが、これら"in-tree"なドライバーは全てCSIに置き換えられるようになります。
"ストレージ CSI"でWeb検索するとたくさん記事が出てくるので、合わせて見てもらうとより理解が深まると思います。
Rook-Cephのアーキテクチャ
よく見るRook-Cephのアーキテクチャ
Web検索で"Rook Ceph"とかで画像検索すると、こんな図をよく見ることができます。
まあ確かにこうなんやけど、、、具体的にデプロイした姿を見ればより理解が深まると思います。というわけで実際にRook-Cephデプロイして見てみましょう。なんと今回はCSI仕様です。ババーン。
Rook 1.1でCephをデプロイしてみよう
ではさっそく最新のRook 1.1を使ってRook-Cephを見てみましょう。今回はこんな6ノードのk8sクラスタを使います。worker nodeにそれぞれ10GBのEBSを1個ずつ付けてます。
[utubo@tutsunom ~]$ kubectl get node -L nodetype --sort-by='{.metadata.creationTimestamp}' NAME STATUS ROLES AGE VERSION NODETYPE ip-172-20-117-198.ec2.internal Ready master 32m v1.15.3 ip-172-20-37-240.ec2.internal Ready master 26m v1.15.3 ip-172-20-86-56.ec2.internal Ready master 19m v1.15.3 ip-172-20-70-151.ec2.internal Ready node 14m v1.15.3 ip-172-20-54-38.ec2.internal Ready node 7m41s v1.15.3 ip-172-20-121-163.ec2.internal Ready node 2m12s v1.15.3
あいにくOperatorHubのRook-Cephはまだ1.1じゃないんで、githubからインストールします。
*コマンド出力省略 [utubo@tutsunom ~]$ git clone https://github.com/rook/rook.git [utubo@tutsunom ~]$ cd rook/cluster/examples/kubernetes/ceph [utubo@tutsunom ceph]$ kubectl create -f common.yaml [utubo@tutsunom ceph]$ kubectl create -f operator.yaml [utubo@tutsunom ceph]$ kubectl create -f cluster.yaml
これで終わりですよ。やっぱ簡単だなぁ。幸せだなぁ。ぼかぁ君と居ると(略
5,6分コトコト煮込んでいると自動的にCephクラスタができてます。kubectl get all
で見てみましょう。
[utubo@tutsunom ceph]$ kubectl get all -n rook-ceph NAME READY STATUS RESTARTS AGE pod/csi-cephfsplugin-87xc7 3/3 Running 0 3m43s pod/csi-cephfsplugin-j9dhm 3/3 Running 0 3m43s pod/csi-cephfsplugin-provisioner-68b89bfd6c-ms22r 4/4 Running 0 3m43s pod/csi-cephfsplugin-provisioner-68b89bfd6c-nc6q6 4/4 Running 0 3m43s pod/csi-cephfsplugin-slvzj 3/3 Running 0 3m43s pod/csi-rbdplugin-4ftsw 3/3 Running 0 3m43s pod/csi-rbdplugin-d4plf 3/3 Running 0 3m43s pod/csi-rbdplugin-dghcl 3/3 Running 0 3m43s pod/csi-rbdplugin-provisioner-669fdd7465-4fjj2 5/5 Running 0 3m43s pod/csi-rbdplugin-provisioner-669fdd7465-d452m 5/5 Running 0 3m43s pod/rook-ceph-mgr-a-f4d9d7c66-qgqxt 1/1 Running 0 2m19s pod/rook-ceph-mon-a-6986bcb454-thb5x 1/1 Running 0 2m57s pod/rook-ceph-mon-b-8974d98f9-gxgnj 1/1 Running 0 2m48s pod/rook-ceph-mon-c-6957d6db48-5tp5j 1/1 Running 0 2m33s pod/rook-ceph-operator-54665977bf-8kqqs 1/1 Running 0 5m8s pod/rook-ceph-osd-0-5d4ff9f46d-cf8mj 1/1 Running 0 79s pod/rook-ceph-osd-1-5479f66fc9-xwgk9 1/1 Running 0 78s pod/rook-ceph-osd-2-77464c5648-shgtl 1/1 Running 0 78s pod/rook-ceph-osd-prepare-ip-172-20-121-163.ec2.internal-cntf7 0/1 Completed 0 114s pod/rook-ceph-osd-prepare-ip-172-20-54-38.ec2.internal-c42bz 0/1 Completed 0 114s pod/rook-ceph-osd-prepare-ip-172-20-70-151.ec2.internal-65s66 0/1 Completed 0 114s pod/rook-discover-9vx4z 1/1 Running 0 5m7s pod/rook-discover-gdsn7 1/1 Running 0 5m7s pod/rook-discover-psnz5 1/1 Running 0 5m7s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/csi-cephfsplugin-metrics ClusterIP 100.64.60.214 <none> 8080/TCP,8081/TCP 3m44s service/csi-rbdplugin-metrics ClusterIP 100.65.62.154 <none> 8080/TCP,8081/TCP 3m44s service/rook-ceph-mgr ClusterIP 100.71.205.11 <none> 9283/TCP 115s service/rook-ceph-mgr-dashboard ClusterIP 100.69.192.148 <none> 8443/TCP 116s service/rook-ceph-mon-a ClusterIP 100.70.114.174 <none> 6789/TCP,3300/TCP 2m58s service/rook-ceph-mon-b ClusterIP 100.70.177.170 <none> 6789/TCP,3300/TCP 2m51s service/rook-ceph-mon-c ClusterIP 100.67.165.255 <none> 6789/TCP,3300/TCP 2m39s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/csi-cephfsplugin 3 3 3 3 3 <none> 3m44s daemonset.apps/csi-rbdplugin 3 3 3 3 3 <none> 3m44s daemonset.apps/rook-discover 3 3 3 3 3 <none> 5m8s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/csi-cephfsplugin-provisioner 2/2 2 2 3m44s deployment.apps/csi-rbdplugin-provisioner 2/2 2 2 3m44s deployment.apps/rook-ceph-mgr-a 1/1 1 1 2m20s deployment.apps/rook-ceph-mon-a 1/1 1 1 2m58s deployment.apps/rook-ceph-mon-b 1/1 1 1 2m49s deployment.apps/rook-ceph-mon-c 1/1 1 1 2m34s deployment.apps/rook-ceph-operator 1/1 1 1 5m9s deployment.apps/rook-ceph-osd-0 1/1 1 1 80s deployment.apps/rook-ceph-osd-1 1/1 1 1 79s deployment.apps/rook-ceph-osd-2 1/1 1 1 79s NAME DESIRED CURRENT READY AGE replicaset.apps/csi-cephfsplugin-provisioner-68b89bfd6c 2 2 2 3m44s replicaset.apps/csi-rbdplugin-provisioner-669fdd7465 2 2 2 3m44s replicaset.apps/rook-ceph-mgr-a-f4d9d7c66 1 1 1 2m20s replicaset.apps/rook-ceph-mon-a-6986bcb454 1 1 1 2m58s replicaset.apps/rook-ceph-mon-b-8974d98f9 1 1 1 2m49s replicaset.apps/rook-ceph-mon-c-6957d6db48 1 1 1 2m34s replicaset.apps/rook-ceph-operator-54665977bf 1 1 1 5m9s replicaset.apps/rook-ceph-osd-0-5d4ff9f46d 1 1 1 80s replicaset.apps/rook-ceph-osd-1-5479f66fc9 1 1 1 79s replicaset.apps/rook-ceph-osd-2-77464c5648 1 1 1 79s NAME COMPLETIONS DURATION AGE job.batch/rook-ceph-osd-prepare-ip-172-20-121-163.ec2.internal 1/1 36s 116s job.batch/rook-ceph-osd-prepare-ip-172-20-54-38.ec2.internal 1/1 37s 116s job.batch/rook-ceph-osd-prepare-ip-172-20-70-151.ec2.internal 1/1 36s 116s
おや、前回までの出力と違いますね。
- csi-cephfsplugin
とかcsi-rbdplugin-provisioner
とか、CSIドライバーっぽいのができてる
- rook-ceph-agent
が無い
そうなんです。1.1からRook-CephはCSIがデフォルトのドライバになります。だから特にCSI絡みのマニフェストファイルをkubectl create
しなくてもCSIドライバーのPodが入るようになっています。
そして、rook-ceph-agent
が無いのも実はこれに関連しています。rook-ceph-agent
はFlexVolumeというストレージドライバで、worker nodeがCephのストレージをattachしたりmountしたりして使うために必要なドライバの役割を果たしていました。CSIがデフォルトになるまではFlexVolumeがデフォルトだったんですが、1.1からそれが逆転したのでrook-ceph-agent
はいなくなりました。
ちなみにFlexVolumeはまだサポートされるので、operatorをデプロイするマニフェストファイルでFlexVolumeをEnableにすると、rook-ceph-agent
はプロビジョンされます。
Podの配置を絵で見てみよう
割と結構な数のPodがたくさんあってごちゃごちゃしていますが、絵にするとこんな風になっています。
Podは大きくわけてRook, Ceph, Ceph CSIの3種類に群に分かれます。ガイア、マッシュ、オルテガと名付けるのはさすがに無理がありますが、こいつらのジェットストリームアタックによってアプリケーションにPVを提供するわけですね。はい。
ざっくり説明します。
Rook
rook-ceph-operator
Rook-Ceph Operatorそのもの。rook-discover
worker nodeに接続されるストレージデバイスをリアルタイムに検知する。Cephクラスタが稼働中にノードにデバイスを挿すと、discoverにより自動的に認識されるが、その後Operatorが定義されているルールに則してCephクラスタに新規osdとして追加するかしないか決める。
Ceph
rook-ceph-mon
Cephクラスタ全体を監視する。"MONitor"。障害等によるトポロジーの変化を察知し望ましい姿への復帰(下がった冗長性の復旧など)を司る。ユーザ認証も担う。rook-ceph-osd
Cephクラスタの保存媒体であるデバイスを抽象化した姿。"Object Store Device/Daemon"(諸説あり)。通常1デバイス=1osdの対応。Cephの全てのデータはosdによってデバイスに読み書きされる。rook-ceph-mgr
: Cephクラスターの管理面を担う。"ManaGeR"。Dashboardを提供したり、Prometheus,Zabbixなど外部ツールへのAPIを提供したりする。
Ceph CSI
Ceph CSIのPodに注目してみましょう。
csi-rbdplugin
,csi-cephfsplugin
csi-rbdplugin-provisioner
,csi-cephfsplugin-provisioner
というのがあります。
前者はApp PodがCeph RBD/CephFSのPVを使うためのドライバで、全てのworker nodeにプロビジョンされます。
後者はざっくり言えばmasterのkube-apiserverに飛んできたCeph RBD/CephFS PV関連のリクエストをwatchして、飛んできたらストレージシステムに対してトリガーするという仲介役と捉えればOKです。
絵の右側の通り、どのPodも複数のコンテナで構成されていますが、この中でオレンジのコンテナはKubernetesの開発側から共通で提供されていて、グリーンのコンテナはストレージプロバイダーが独自に開発して提供するものです。例えばcis-rbdplugin-provisioner
を覗いてみましょう。
[utubo@tutsunom ceph]$ kubectl get pod csi-rbdplugin-provisioner-669fdd7465-4fjj2 -o json | jq -r '.status.containerStatuses[] | .name, .image' | xargs -n2 csi-provisioner quay.io/k8scsi/csi-provisioner:v1.3.0 csi-rbdplugin quay.io/cephcsi/cephcsi:v1.2.0 csi-rbdplugin-attacher quay.io/k8scsi/csi-attacher:v1.2.0 csi-snapshotter quay.io/k8scsi/csi-snapshotter:v1.2.0 liveness-prometheus quay.io/cephcsi/cephcsi:v1.2.0
5つコンテナがあるんですが、csi-provisioner
,csi-rbdplugin-attacher
,csi-rbdplugin-attacher
はquay.io/k8scsi/
からpullしていて、csi-rbdplugin
,liveness-prometheus
はquay.io/cephcsi/
からpullしてることがわかります。
ストレージプロバイダーはオレンジのsidecarの仕様に合わせて、緑色のコンテナイメージだけを開発・メンテすることになります。kubernetesの中身には一切手を付けないようになっているので、ドライバの修正やアップデートをしやすくなっていますね。
これらのPodが具体的にどんな動きをするのかは、OpenShift Meetup #6のサイトにアップされている資料で何となくうかがい知ることができますので、よかったら見てみて下さい。
まとめ
そういうわけで今回は最新のRook 1.1でRook-Ceph CSIをデプロイしたときのアーキテクチャを紹介しました。何だかいろいろとできていないことがある気がするんですが、今回はここまで。