Tridentでボリュームを払い出すプールを制御する（Virtual Storage Pool編）

:::note info
久しぶりの追記です。
この記事の中で以下の処理についてふれています。

1. BackendConfig に Labelsを付けておく
2. StorageClass の parameters に selectorを書いて 利用するバックエンドを決定するロジックを指定する

この Tridentの BackendConfigにつける Label で使える文字がドキュメントに書かれていないと思います。私が調べた限り 0-9, A-Z, a-z, '_', '-' だけ[^LabelValue]となるはずです。
これ以外の文字を使った場合でも、直接的なエラーにはなりません。ただ、実際にボリュームをプロビジョニングしようとしたときに、Selectorに合致するBackendを見つけられないというエラーが起きるはずですので注意してください。

それと、続きを書けていなくてすいません🙇
:::

こんにちは。NetAppの大野です。  
[前回]に続いて [Trident] のストレージプールの話になります。

今回は 素のストレージプールでは、大規模環境等で課題となる点と、その改善方法となる仮想ストレージプールについて書いていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/91331fed-691d-3b83-aa27-a8838a15e6e1.png)

## Storage Pool管理の課題

[前回]、ボリュームを払い出すストレージプールの選択方法として二種類あるとお伝えしました。

- "このストレージの、この [Aggregate] から" と、プールを具体的に指定する設定
- "SSDのプールから" "ブロック・ストレージのプールから" といった、ストレージの属性を指定することによって、条件に合うプールを自動的に選択させる設定

しかしながら、名前による指定方法では Kubernetes上で管理されている [Storage Class] が、[Trident] の バックエンド設定＝ストレージ管理と強く結びついてしまいます。また、属性による指定だけでは、会社組織等のシステムによるストレージの分離がうまく表現できません。

例えば 社内に２つの部門があり、ストレージ負荷が影響しあうのを避けるために [Aggregate] を、２つ aggr1 と aggr2 というプールで分けて運用したいとします。  
ここでは両方とも同じ構成を持っているので、そのままでは属性による自動選択はできません。名前を使って [Storage Class] の storagePools 設定でそれぞれ指定して運用するとします。

運用が進んで、一方の部門で性能と容量が不足してきたので、物理的にコントローラと[Aggregate]を追加して aggr3 というプールを新しく追加しました。
このとき、[Storage Class] 側でプールの名前指定をしていると [Storage Class] 側の設定にプール aggr3 を追加する必要が出てきます。

部門用ファイルサーバの運用に例えて言うなら、部門の社員が増えたり減ったりする度、ファイルサーバの共有設定を変える様な運用と言えます。  
一般的には、認証基盤側でグループを設定して、ファイルサーバ側ではグループに対してファイルの共有設定をする事で、社員の異動が、ファイルサーバ運用・設定に影響を与えないようにします。

Storage Poolにも、ストレージ運用と、Kubernetes運用を、もう少しゆるく繋いでやる方法が必要に思います。

## Virtual Storage Poolとは

この様な Storage Pool 管理の課題に対し、[Trident]は [Virtual Storage Pool]という機能を持っています。

[Virtual Storage Pool]の主な使い方は二種類あります

### 複数のプールをまとめて扱う

先程の例に示した様に、プール名で管理していると、ストレージ側の設定（バックエンド設定まで）に Kubernetes側の設定が影響を受けてしまいます。それを防ぐために、特定のラベルを持つプールを、グループとしてまとめるような使い方です。

![説明1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/9248f81a-3ec9-ccc1-9399-69a109b18389.png)

これにより、[Storage Class]で 直接プールの名前を指定するのではなく、プールについたラベルを指定する事によって、プールを選択させることが可能になります。

また、ストレージの物理構成を変更したりしても、Kubernetes管理側への影響を防ぐ事ができます[^affect_backend]。

[^affect_backend]: バックエンドの構成には影響を与えてしまう事があり、この場合 [Custom Resourceによるバックエンド](https://docs.netapp.com/us-en/trident/trident-use/backend-kubectl.html)の変更か、[Backend JSONとtridentctlによるバックエンド](https://docs.netapp.com/us-en/trident/trident-use/backend_ops_tridentctl.html)の変更等が必要になります。このあたりの管理の境界は、大規模環境等で課題になる事があります。

### 一つの物理ストレージプールを複数の属性を持つ仮想ストレージプールに分割

上の使い方は、複数のプールを 一つにまとめる(分類する)役目だったわけですが、ここでは逆に一つのプールを複数に分ける使い方です。

例えば１つの物理プール(ONTAPの場合はAggregate)でも、「本番用のボリュームは容量不足の心配の無いThickボリュームでで」「開発用のボリュームはコスト効率の良いThinボリュームで」と使い分けたい場合があります。

複数のバックエンドとして構成することも可能ですが、ここに[Virtual Storage Pool]を使うことで一つのバックエンドで、これを実現することができます。

![説明2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/6d49dcdb-3afb-7472-bbda-d996109c4792.png)

## まとめ

今回のお話はまとめると以下のようになるかと思います。

- ストレージ管理（バックエンド管理）と、Kubernetesの管理の間に入る抽象化層として [Virtual Storage Pool]という機能がある
- [Virtual Storage Pool]の使い方は主に２つ
  - 複数のプールを１つのプールとしてまとめる
  - １つのプールを複数の属性を持った複数のプールとして使う

次回は実際にどの様に[Virtual Storage Pool]を構成するかについて書いてみたいと思います。

[前回]: https://qiita.com/yasuoohno/items/d18ab651d834a7ebfb30
[Trident]: https://docs.netapp.com/us-en/trident/index.html
[Aggregate]: https://kb-ja.netapp.com/Advice_and_Troubleshooting/Data_Storage_Software/ONTAP_OS/What_is_an_aggregate
[Storage Class]: https://kubernetes.io/docs/concepts/storage/storage-classes/
[Virtual Storage Pool]: https://docs.netapp.com/us-en/trident/trident-concepts/virtual-storage-pool.html
[^LabelValue]: [ここ](https://github.com/NetApp/trident/blob/master/storage_attribute/label.go#L14)の記載から labelValue としては \w- の文字クラスとの一致が必要と判断しています。ドキュメントへの記載については改善リクエストを出してあります。