※この記事は Red Hat Advent Calendar 2023 の 16日目の記事です。
こんにちは。レッドハットでクラウドインフラを生業にしている宇都宮(うつぼ)です。
早速ですがストレージに関する問題です。
問題
アリスはオンプレミスで展開された OpenShift(または Kubernetes)クラスタの管理者です。
クラスタには1つ 10TiB ものデカすぎる PV があります。この PV のバックエンドはブロックストレージで、Thin-provisioned な論理ボリュームを使っています。 ストレージの管理者であるボブからは「もうストレージの容量がなくなりそうだから、この PV から容量を返してくれ」と言われています。
クラスタ管理者のアリスは、このデカすぎる PV を使うキャロルにこの話をして、PV 内に溜め込んだ不要なファイルを消してもらうことになりました。
キャロルからは、「仰せの通りファイルを消した、3分の1 くらいになった」と報告を受けました。
アリスはこれで一件落着と枕を高くして寝ました。しかし翌日ボブからは「もう本当にまずい!早く容量を返してくれ!」と言われ、困惑しています。
さて、なぜでしょうか。なお、ボブもキャロルも嘘はついていないものとします。
解答
簡単ですね。正解は、ファイルを消してもファイルシステムは勝手に縮まないし、ファイルシステムが縮まなければボリュームサイズも減らないから です。
これは別に Kubernetes とかに限った話ではありません。一般的な Linux サーバでも同じ現象は起こります。
そもそも上の問題で一番ダメなのは 10TiB の PVC を許しているところで、OpenShift かストレージ側で Quota をかけて制限すべきです。
ですが、ブロックストレージだとファイルシステムでファイルを消したら自動で空いた容量がストレージに帰っていくなんてことは無いので、アリスもぐっすり寝てる場合ではありません。
Space Reclamation と PV
一度使ったけど空いた容量をストレージ側に返すことを、Space Reclamation と言います。
シックプロビジョニングではまず出てきませんが、シンプロビジョニングではおなじみの概念です。
シンプロビジョニングは「自分が必要な容量だけ使うべき」なポリシーですので、「必要なくなって取りすぎた容量は返すべき」だからです。
通常の Linux で Space Reclamation するには、fstrim
コマンドを実行してファイルシステムの使っていない領域を開放します。その後はストレージ側でそれを回収します。
それでは Kubernetes PV の場合は?わざわざ Pod や Worker ノードに入って fstrim
を実行する?そんな運用ありえないですよね。
PV の場合は、CSI (Container Storage Interface) Add-on を使って Reclaim することができます。
ReclaimSpaceJob
というカスタムリソースを使います。Reclaim はそんなに常時やるものではないので、単発で Job 的に使います。
ODF で PV の Space Reclamation を試してみる
Red Hat OpenShift Data Foundation(ODF)はこれに対応しているので、実際やってみましょう。
ODF がインストールされたクラスタで適当なアプリを作って 50GiB PVC をアタッチします。
Pod からは /dev/rbd0
として見えます。この時点ではほとんど空っぽ。
sh-4.4$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop1 7:1 0 512G 0 loop rbd0 252:0 0 50G 0 disk /mnt nvme0n1 259:0 0 100G 0 disk |-nvme0n1p1 259:1 0 1M 0 part |-nvme0n1p2 259:2 0 127M 0 part |-nvme0n1p3 259:3 0 384M 0 part `-nvme0n1p4 259:4 0 99.5G 0 part /dev/termination-log sh-4.4$ df -h /mnt Filesystem Size Used Avail Use% Mounted on /dev/rbd0 49G 24K 49G 1% /mnt
ODF のダッシュボードで見ても、ほとんど使われていない初期状態です。
ここで 10GiB のダミーファイルを書き込みます。10GiB 増えています。(当たり前)
sh-4.4$ dd if=/dev/random of=/mnt/10G.dat bs=1M count=10240 10240+0 records in 10240+0 records out 10737418240 bytes (11 GB, 10 GiB) copied, 81.0443 s, 132 MB/s sh-4.4$ sh-4.4$ df -h /mnt Filesystem Size Used Avail Use% Mounted on /dev/rbd0 49G 11G 39G 21% /mnt
ODF では三重でレプリケーションされるので、ダッシュボードで見ると 3倍の 30GiB ほどが増えていることがわかります。
それでは Pod でファイルを削除します。10GiB 減ります。
sh-4.4$ rm -f /mnt/10G.dat sh-4.4$ sh-4.4$ df -h /mnt Filesystem Size Used Avail Use% Mounted on /dev/rbd0 49G 24K 49G 1% /mnt
ODF では、全然減ってません。
さてここで ReclaimSpaceJob
を作って Reclaim してみましょう。
apiVersion: csiaddons.openshift.io/v1alpha1 kind: ReclaimSpaceJob metadata: name: reclaim-odf-pvc namespace: test spec: target: persistentVolumeClaim: odf-pvc
これを実行すると、次のようになります。
ODF の中で動く Ceph のブロックデバイス(RBD)は、シンプロビジョニングで作られます。
この ReclaimSpaceJob
によって、アプリ Pod と同じノードで動く CSI driver が fstrim
を実行します。Ceph RBD は sparse なイメージファイルなので、ゼロ領域は自動的に Ceph のプールに返されます。
Space Reclamation はスケジュールするともっと楽
ad hoc に Reclaim するなら ReclaimSpaceJob
を作りますが、定期的に実行するようスケジュールしておくとよいです。
ReclaimSpaceCronJob
というカスタムリソースでスケジュールを設定できるのですが、対象の PVC に annotation を追加することで代用できます。
# oc annotate pvc odf-pvc "reclaimspace.csiaddons.openshift.io/schedule=@weekly" -n test persistentvolumeclaim/odf-pvc annotated
上の @weekly
の部分は Cron と同じ書き方でもOKです。毎週金曜日の深夜0時に実行するなら、0 0 * * 5
みたいな感じですね。
これでアリスもボブも枕を高くしてぐっすり眠れることでしょう。
まとめ
クラウド環境で Space Reclamation しないとマズい、ということはほとんど無いと思いますが、冒頭の問題のようにオンプレミス環境だったら意外とあるかもしれません。
ストレージはあって当然使えて当然、とお思いの方もいるかもしれませんが、いやいや結構中の人は色々と工夫と苦労をしているんですね。
今回は ODF で確認しましたが、他のストレージの CSI はどうなのでしょう。すみません私もわかりません。色々と試してみるとよいのではないかなと思います。
というわけで、今回はここまで。