Kuberentes環境で動的なストレージ性能の管理 (Adaptive QOS)

# Kuberentes環境で動的なストレージ性能の管理 (Adaptive QOS)
多数のワークロードを実行しているKuberentes環境では、ストレージの性能管理を適切に実施したいといったケースがあるかと思います。

Kubernetes環境でのストレージ利用では、ダイナミックプロビジョニング機能で ユーザ側が任意のタイミングで必要な容量を指定して永続ボリューム(PV)を作成して利用することが可能です。このような使い方では、PV毎の設定は管理者の方が手動で都度実施するのは現実的ではありません。PVが作成される時に 動的に サイズに応じて パフォーマンスの設定をする機能が必要になってくるかと思います。

<br>
NetAppのストレージOS ONTAPでは Adaptive Qos という機能が提供されています。
これはサイズに応じて動的に性能上限等の設定をボリュームに適用してくれる機能です。 NetAppのAstra Trident経由で Kuberentes環境で利用することも可能になっています。


例えば、20 IOPS/GB のAdaptive QoS Policyを設定したPVを作成すると、 サイズが10GBなら、200IOPs 、50GBなら1,000IOPSの性能上限を自動的に設定するといったことが可能になります。

今回は Kubernetes環境での この Adaptive Qos機能の利用を 実際に試してみたのでその内容を紹介したいと思います。


## 前提
以下の環境で試しています。 

- Astra Trident 23.10.0
- ONTAP 9.13.1P4
- Kubernetes 1.26.5
- AlmaLinux 9.1

※ Tridentは導入済みの前提としています。 導入方法は[こちらのブログ](https://licensecounter.jp/devops-hub/blog/trident/)で紹介されているので参考にしてください。

## やってみること
Adaptive QoSを利用して Kubernetes上でPVを作成時に サイズに応じた性能上限設定が 自動的に適用されることを確認します。
<br>

 1. Adaptive QosのPolicyを作成
 2. Kuberentes環境で Adaptive QoSを利用するための準備を実施
 3. Kuberentes環境から、Adaptive QoSのPolicyが適用されたPVを作成
 4. PVのサイズに応じたストレージ性能が設定されていることを確認

## 1. Adaptive QoSのPolicyを作成
最初にストレージ側で Adaptive QoSのPolicyを作成し、どういった条件で性能を設定するかを決定しておきます。

なお、Adaptive QoS Policyを使用すると、PVのサイズに応じて 性能上限や下限を自動的に調整し、 TB または GB あたりの IOPS を一定に保つことができます。これは、多数のワークロードを管理する環境では大きなメリットかと思います。 詳細が 気になる方は [ONTAPのドキュメントサイト](https://docs.netapp.com/ja-jp/ontap/performance-admin/adaptive-qos-policy-groups-task.html)で紹介されていますので確認してみてください。


<br>
今回は、IOPSの上限 を PVのサイズ 1GB あたり 150 IOPS に 設定する ポリシーを作成します。

ONTAPにsshでログインして以下作業を実施します。


```shell:
::> adaptive-policy-group create -vserver trident_svm -policy-group aqos01 -expected-iops 100IOPS/GB -peak-iops 150IOPS/GB -peak-iops-allocation allocated-space
::> qos adaptive-policy-group show
                            Expected    Peak         Minimum Block
Name         Vserver Wklds  IOPS        IOPS         IOPS    Size
------------ ------- ------ ----------- ------------ ------- -----
aqos01       trident_svm
                     0      100IOPS/GB  150IOPS/GB   75IOPS  ANY
・
・
・
```
aqos01というポリシーで Peak IOPS(性能上限)が 150IOPS/GBとなっていることが確認できます。

このaqos01というポリシーを適用した10GB の PV を作成した場合 Peak IOPS=1500 IOPSの設定が 自動的に適用されます。


<BR>

上記で設定した以外にもaqosにはいくつかのパラメータを設定して、その動作を柔軟に制御可能です。aqosの各パラメータについては[こちらのKB](https://kb.netapp.com/onprem/ontap/Performance/What_is_Adaptive_QoS_and_how_does_it_work)でも紹介されていますので、気になる方は参照してみてください。


## 2. Kuberentes環境で Adaptive QoSを利用するための準備を実施
Kubernetes環境で Adaptive Qosを利用するために、TridentのBackend設定で 利用するAdaptive QoSポリシーの情報を登録します。


### 2-1. Trident Backend作成
先ほど作成したポリシーをBackend定義内に記載して Backendを作成します。

```shell:
$ cat <<EOF >> backend-tbc-ontap-nas-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: backend-tbc-ontap-nas-secret
type: Opaque
stringData:
  username: cluster-admin
  password: password
EOF
$ kubectl -n trident apply -f backend-tbc-ontap-nas-secret.yaml
secret/backend-tbc-ontap-nas-secret created
$ cat <<EOF >> backend-tbc-ontap-nas.yaml
apiVersion: trident.netapp.io/v1
kind: TridentBackendConfig
metadata:
  name: backend-tbc-ontap-nas
spec:
  version: 1
  backendName: ontap-nas
  storageDriverName: ontap-nas
  managementLIF: 10.0.0.1
  dataLIF: 10.0.0.2
  svm: trident_svm
  labels: { backend: qos }
  storagePrefix: trident_aqos_
  credentials:
    name: backend-tbc-ontap-nas-secret
  defaults:
    adaptiveQosPolicy: aqos01  
EOF
$ kubectl -n trident apply -f backend-tbc-ontap-nas.yaml
tridentbackendconfig.trident.netapp.io/backend-tbc-ontap-nas created
$ kubectl -n trident get tbc backend-tbc-ontap-nas
NAME                    BACKEND NAME           BACKEND UUID                           PHASE   STATUS
backend-tbc-ontap-nas   backend-tbc-ontap-nas  6a900a51-7f68-4a78-af9f-fee03e512e5b   Bound   Success

```
backend-tbc-ontap-nas.yamlファイル内に、 "adaptiveQosPolicy: aqos01"という記載がAdaptive QoSを利用するための設定です。

この設定によりこのBackend経由で作成される PV には aqosポリシーが適用され、ポリシーに則って サイズに応じたPeak IOPSが自動的に設定されます。
 


### 2-2. Storage Class作成
先ほど作成したBackendを利用するStorage Classを作成します。

```shell:
$ cat <<EOF >> sc-ontap-nas.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ontap-nas
provisioner: csi.trident.netapp.io
parameters:
  backendType: "ontap-nas"
  selector: "backend=qos"
EOF
$ kubectl apply -f sc-ontap-nas.yaml
$ kubectl get sc

```
このストレージクラスを利用することで、Adaptive QoSポリシーが適用されたPVがプロビジョニングされるPVCを作成することが可能になります。

これで、Kuberentes環境で Adaptive QoSを利用するための準備ができました。

## 3. Kuberentes環境から、Adaptive QoSのPolicyが適用されたPVを作成
Adaptive QoSのPolicyが適用されたPVを作成してみます。

容量に応じたIOPSが設定されることを確認するために、今回は３つのPVを作成します。

```shell:
$ cat <<EOF >> pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: qos-10g
  namespace: qos
  labels:
    app: qos
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ontap-nas
  resources:
    requests:
        storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: qos-20g
  namespace: qos
  labels:
    app: qos
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ontap-nas
  resources:
    requests:
        storage: 20Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: qos-30g
  namespace: qos
  labels:
    app: qos
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ontap-nas
  resources:
    requests:
        storage: 30Gi
EOF
$ kubectl create ns qos
$ kubectl apply -f pvc.yaml
$ kubectl -n qos get pvc
NAME           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS    AGE
qos-10g        Bound    pvc-bfdd99d5-2067-460f-a23b-9191483bbd95   10Gi       RWO            ontap-nas       41s
qos-20g        Bound    pvc-8a5e50ae-21e7-4434-9f33-349ef59f089f   20Gi       RWO            ontap-nas       41s
qos-30g        Bound    pvc-5fee2044-69e5-4605-90f2-890d159836d1   30Gi       RWO            ontap-nas       41s
$
```
Adaptive QoSを登録したBackendを利用するStorageClassをontap-nasを指定した 10G/20G/30Gの容量のPVを作成しました。


## 4. PVのサイズに応じたストレージ性能が設定されていることを確認してみる。 
作成したPV毎に、サイズに応じたストレージ性能が設定されていることを確認します。

ONTAPにsshでログインして確認のコマンドを実行します。


```shell:
::> qos workload show  -fields max-throughput
workload               max-throughput
---------------------- -------------------
trident_aqos_pvc_5fee2044_69e5_4605_90f2_890d159836d1-wid30160
                       4500IOPS
trident_aqos_pvc_8a5e50ae_21e7_4434_9f33_349ef59f089f-wid46143
                       3000IOPS
trident_aqos_pvc_bfdd99d5_2067_460f_a23b_9191483bbd95-wid30014
                       1500IOPS
3 entries were displayed.
```

各PV(に対応するONTAP上のボリューム)毎に 最大IOPSの値が動的に設定されています。

10GのPVが 1500 IOPS / 20GのPVが 3000 IOPS / 30GのPVが4500IOPSに設定されていることが確認できます。
<BR>
なお、ONTAP上でのボリューム名は、Prefix + PV名の 形式になるため、trident_aqos_pvc_xxxxxxxxという名前になっています。（Prefixは"trident_aqos" =TridentのBackendで指定したStoragePrefixの値です)



## まとめ。
Adaptive QoS機能の Kuberentes環境からの利用について紹介しました。
この機能を利用することで、管理者の方の手をわずらわせずに、動的に 利用規模に応じたストレージ性能を提供する環境を実装することが可能になるかと思います。

PVを作成したタイミングで サイズに応じて最大IOPSが自動的に設定されますので、管理者の方の運用負荷の軽減にとどまらず 設定ミスや設定忘れの防止にもつながりますので 総合的な運用効率 向上につながります。

Adaptive QoS機能ははより柔軟な使い方が可能であり、仮想ストレージ全体での上限や下限を設定するなどの使い方も可能です。 
複数のポリシーを定義することが可能なので、高パフォーマンス、コスト最適化など サービスレベルのパターンを用意して運用することも可能です。
実装したいサービス、実現したい運用形態により、そういった機能の使い分けを検討してみるのも面白いのではないかと思います。