4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Microsoft Azure TechAdvent Calendar 2023

Day 15

AKS での複数可用性ゾーンの利用と、ZRS Azure Disk Persistent Volume(永続ボリューム)

Last updated at Posted at 2023-12-14

1. はじめに

image.png

今回は AKS(Azure Kubernetes Service) での複数可用性ゾーンの利用と、ZRS(ゾーン冗長ストレージ | Zone Redundant Storage) Azure Disk Persistent Volume についての記事となります。

Azure disk の ZRS 対応について、東日本リージョンでは2023年6月に GA されており、既に VM 等で利用されている方も多いかもしれません。
今回は AKS での 利用についてあらためて検証した結果を記事にしました。
なお Azure disk の ZRS 対応リージョンについては、順次拡大中となります!

AKS(Azure Kubernetes Service) では、可用性ゾーンを利用することで、クラスタの高可用性を向上させることができます。
可用性ゾーン(Availability Zone)とは、物理的に分離されたデータセンターのグループで、同じリージョン内に複数存在します。

また、AKS(Azure Kubernetes Service) では、ノードプールごとに可用性ゾーンを指定することができます。
複数の可用性ゾーンを指定した場合、ノードプール内のノードは、指定された可用性ゾーンに分散されて起動し、ロードバランサーやパブリックIPアドレスなどのリソースも、ゾーン冗長に作成されます。

しかし、AKS で可用性ゾーン(Availability Zone)を利用する場合、かつ、Azure Disk Persistent Volume(永続領域) を使用する際に注意が必要です。

Azure ディスク可用性ゾーンのサポート
Azure マネージド LRS ディスクを使用するボリュームはゾーン冗長リソースではありません。ゾーンをまたいでアタッチされるため、サポートされません。 ターゲット ポッドをホストしている指定ノードと同じゾーン内のボリュームを併置する必要があります。
Azure マネージド ZRS ディスク (Azure Disk CSI ドライバー v1.5.0 以降でサポート) を使用するボリュームは、ゾーン冗長リソースです。 これらのボリュームは、すべてのゾーンおよび非ゾーン エージェント ノード上でスケジュールできます。

上記の制限について詳しく解説していきます。

Azure Disk は、仮想マシンにアタッチされる永続的なストレージで、AKS では、Persistent Volume (PV) と Persistent Volume Claim (PVC) を使って、Azure Disk を Pod にマウントすることができます。

また、Azure Disk には LRS (ローカル冗長ストレージ | Locally Redundant Storage) とZRS (ゾーン冗長ストレージ | Zone Redundant Storage) の2種類があります。

  • LRS Azure Disk は、同じ 可用性ゾーン(Availability Zone)内の3つのレプリカで構成されます。
  • ZRS Azure Disk は、異なる 可用性ゾーン(Availability Zone)内の3つのレプリカで構成されます。
  • 以下は LRS と ZRS の違いイメージ
    image.png

ここで、LRS Azure Disk を使用する場合は、以下の点に注意しなければなりません。

  • LRS Azure Diskはゾーン冗長に対応していません。つまり、Azure Disk が作成された可用性ゾーン(Availability Zone)がダウンした場合は、Azure Disk も利用できなくなります。
  • LRS Azure Disk は可用性ゾーン(Availability Zone)をまたいでアタッチできません。つまり、Azure Disk が作成された可用性ゾーンと異なる可用性ゾーン上で起動しているノードからは Azure Disk をマウントすることができません。
  • AKS では、LRS Azure Disk を動的に作成する場合は、最初にアタッチされたノードのゾーンに固定されます。つまり、ノードプールのスケールアップやスケールダウンなどでノードのゾーンが変わった場合は、Pod から Azure Disk をマウントできなくなります。

これらの制約からわかるように、LRS Azure Disk はゾーン冗長の AKS クラスタには適していません。
Pod が起動するためには、Azure Disk と同じゾーンのノードが必ず存在しなければなりませんので、可用性ゾーンを1つに固定するなどの対処が必要でした。

しかし、可用性ゾーンを利用する目的は、ノードの障害やメンテナンスなどでノードが利用できなくなった場合でも、別の可用性ゾーン上のノードで Pod を再配置することですが、LRS Azure Disk を使用すると、この目的を達成できません。

では、どうすればよいのでしょうか?
複数の可用性ゾーンを有効にした AKS クラスタで、Azure Disk の Persistent Volume (PV) が必要な場合は、かならず ZRS Azure Disk を使用してください。

ZRS Azure Disk は、以下の特徴を持ちます。

  • ZRS Azure Disk はゾーン冗長に対応しています。つまり、Azure Disk が作成された可用性ゾーンがダウンしても、別の可用性ゾーンのレプリカを利用できます。
  • ZRS Azure Disk は可用性ゾーンをまたいでアタッチできます。つまり、Azure Disk が作成された可用性ゾーンと異なる可用性ゾーン上のノードでもマウントすることができます。
  • ZRS Azure Disk を動的に作成した場合でも、最初にアタッチされたノードの可用性ゾーンに依存しません。つまり、ノードプールのスケールアップやスケールダウンなどでノードの可用性ゾーンが変わっても、Azure Disk をマウントすることができます。

ZRS Azure Disk は、ゾーン冗長の AKS クラスタにおいて、Azure Disk を使用する場合のベストプラクティスです。
ZRS Azure Disk を使用することで、可用性ゾーンのメリットを最大限に活かすことができます。

それでは、このあと、ゾーン冗長を有効にした AKS クラスタでの LRS と ZRS Azure Disk の Persistent Volume (PV) 挙動の違いを確認していきます。

本記事の実行結果等は執筆時点(2022年12月13日)での内容となります

2.事前準備

  1. ゾーン冗長 AKS クラスタの作成
  2. カスタムのStorageClassの作成
  3. PVC と Deployment の作成

2.1. ゾーン冗長 AKS クラスタの作成

image.png

初期状態として以下のような可用性ゾーンを有効にした AKS クラスタを用意します。

  • リージョン: japaneast
  • ノードプール
      * 可用性ゾーン: ゾーン 1, ゾーン 2
      * ノード数: 2
  • az cli で作成する場合は以下
# create resouce group 
az group create --name rg-demo-aks-zrs --location japaneast
# create AKS Cluster, 2node, 2zone
az aks create -g rg-demo-aks-zrs \
-n aks-demo-zrs01 \
--enable-managed-identity \
--enable-addons monitoring \
--enable-msi-auth-for-monitoring  \
--node-count 2 \
--generate-ssh-keys --zones 1 2

作成した AKS ノードプールのノード(VM)の可用性ゾーン(Availability Zone)をkubectlコマンドから確認します。

takuya [ ~ ]$ az aks get-credentials --resource-group demo-aks-zrs --name demo-aks-zrs01
Merged "demo-aks-zrs01" as current context in /home/takuya/.kube/config
takuya [ ~ ]$ kubectl get node -L topology.kubernetes.io/region -L topology.kubernetes.io/zone
NAME                                STATUS   ROLES   AGE   VERSION   REGION      ZONE
aks-nodepool1-28151597-vmss000000   Ready    agent   34m   v1.27.7   japaneast   japaneast-1
aks-nodepool1-28151597-vmss000001   Ready    agent   34m   v1.27.7   japaneast   japaneast-2
  • Azure Poratl からもAKS ノードプールの状況を確認

image.png

image.png

image.png

以上で、複数の可用性ゾーンを有効にした AKS クラスタの準備ができました。

2.2. カスタムのStorageClassの作成

image.png

つづいて、Azure disk の LRS / ZRS は StorageClassで指定するため、ぞれぞれのカスタムのStorageClassを用意します。

デフォルトで用意されている、StorageClassは、LRS のため、ZRS のカスタムのStorageClassの作成します。

ベースとなる AKS 初期から組み込まれているmanaged-csiの内用を確認すると
以下の通り、skuname: StandardSSD_LRSであることがわかります。

takuya [ ~ ]$ kubectl get sc
NAME                    PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
azurefile               file.csi.azure.com   Delete          Immediate              true                   60m
azurefile-csi           file.csi.azure.com   Delete          Immediate              true                   60m
azurefile-csi-premium   file.csi.azure.com   Delete          Immediate              true                   60m
azurefile-premium       file.csi.azure.com   Delete          Immediate              true                   60m
default (default)       disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   60m
managed                 disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   60m
managed-csi             disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   60m
managed-csi-premium     disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   60m
managed-premium         disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   60m
managed-premium         disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   60m
takuya [ ~ ]$ kubectl get sc managed-csi -o yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  creationTimestamp: "2023-12-13T03:47:20Z"
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: managed-csi
  resourceVersion: "380"
  uid: 56c60813-8a7f-45bc-b593-9c4f834ab72e
parameters:
  skuname: StandardSSD_LRS
provisioner: disk.csi.azure.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
takuya [ ~ ]$ 

managed-csiと同内容(skuname: StandardSSD_LRS)で別名managed-csi-lrsStorageClassを用意します。

managed-csi-lrs.yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: managed-csi-lrs
parameters:
  skuname: StandardSSD_LRS
provisioner: disk.csi.azure.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

つづいて、managed-csiの内容をStandardSSD_ZRS変更した、別名managed-csi-zrsStorageClassを用意します。

managed-csi-zrs.yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: managed-csi-zrs
parameters:
  skuname: StandardSSD_ZRS
provisioner: disk.csi.azure.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

以下の通り、それぞれのカスタムのStorageClassを作成します。

takuya [ ~ ]$ kubectl apply -f managed-csi-lrs.yaml 
storageclass.storage.k8s.io/managed-csi-lrs created
takuya [ ~ ]$ kubectl apply -f managed-csi-zrs.yaml 
storageclass.storage.k8s.io/managed-csi-zrs created
takuya [ ~ ]$ kubectl get sc | grep managed-csi
managed-csi             disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   68m
managed-csi-lrs         disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   5m38s
managed-csi-premium     disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   68m
managed-csi-zrs         disk.csi.azure.com   Delete          WaitForFirstConsumer   true                   5m30s
takuya [ ~ ]$ 

2.3. PVC と Deployment の作成

image.png

つづいて、作成したカスタムのStorageClassを指定した PVC と その PVC を利用する Deployment のマニフェストファイルを準備して AKS クラスタへkubectl applyします。
これにより、Dynamic にそれぞれ PV が作成され、Deployment により作成された Pod へ Azure disk がマウントされることを確認します。

  • LRS 用の PVC
pvc-azuredisk-csi-lrs01.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-azuredisk-lrs01
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: managed-csi-lrs
  • ZRS 用の PVC
pvc-azuredisk-csi-zrs01.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-azuredisk-zrs01
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: managed-csi-zrs
  • LRS 用の PVC を指定した Deployment
dp-pvc-lrs01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-azuredisk-lrs01
  labels:
    node: aci
    app: nginx-azuredisk-lrs01
spec:
  strategy:
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      app: nginx-azuredisk-lrs01
  template:
    metadata:
      name: nginx-azuredisk-lrs01
      labels:
        app: nginx-azuredisk-lrs01
    spec:
      containers:
        - image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine
          name: nginx-azuredisk
          command:
            - "/bin/sh"
            - "-c"
            - while true; do echo $(date) >> /mnt/azuredisk/outfile; sleep 1; done
          volumeMounts:
            - name: azuredisk
              mountPath: "/mnt/azuredisk"
      volumes:
        - name: azuredisk
          persistentVolumeClaim:
            claimName: pvc-azuredisk-lrs01
  • ZRS 用の PVC を指定した Deployment
dp-pvc-zrs01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-azuredisk-zrs01
  labels:
    node: aci
    app: nginx-azuredisk-zrs01
spec:
  strategy:
    type: RollingUpdate
  replicas: 1
  selector:
    matchLabels:
      app: nginx-azuredisk-zrs01
  template:
    metadata:
      name: nginx-azuredisk-zrs01
      labels:
        app: nginx-azuredisk-zrs01
    spec:
      containers:
        - image: mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine
          name: nginx-azuredisk
          command:
            - "/bin/sh"
            - "-c"
            - while true; do echo $(date) >> /mnt/azuredisk/outfile; sleep 1; done
          volumeMounts:
            - name: azuredisk
              mountPath: "/mnt/azuredisk"
      volumes:
        - name: azuredisk
          persistentVolumeClaim:
            claimName: pvc-azuredisk-zrs01

以下のように PVC , Deployment を Apply し Pod が正常に起動してそれぞれ LRS および ZRS の Azure Disk の PV をマウントできることを確認

ttakuya [ ~ ]$ kubectl apply -f pvc-azuredisk-csi-lrs01.yaml 
persistentvolumeclaim/pvc-azuredisk-lrs01 created
takuya [ ~ ]$ kubectl apply -f pvc-azuredisk-csi-zrs01.yaml 
persistentvolumeclaim/pvc-azuredisk-zrs01 created
takuya [ ~ ]$ kubectl get pv,pvc -o wide
NAME                                        STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS      AGE   VOLUMEMODE
persistentvolumeclaim/pvc-azuredisk-lrs01   Pending                                      managed-csi-lrs   60s   Filesystem
persistentvolumeclaim/pvc-azuredisk-zrs01   Pending                                      managed-csi-zrs   52s   Filesystem
takuya [ ~ ]$ 
takuya [ ~ ]$ kubectl apply -f dp-pvc-lrs01.yaml
deployment.apps/nginx-azuredisk-lrs01 created
takuya [ ~ ]$ kubectl apply -f dp-pvc-zrs01.yaml
deployment.apps/nginx-azuredisk-zrs01 created
takuya [ ~ ]$ 
takuya [ ~ ]$ kubectl get pv,pvc,deploy,pod -o wide
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS      REASON   AGE   VOLUMEMODE
persistentvolume/pvc-10b6bd60-89cf-489a-b68f-966143763b4e   10Gi       RWO            Delete           Bound    default/pvc-azuredisk-lrs01   managed-csi-lrs            63s   Filesystem
persistentvolume/pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb   10Gi       RWO            Delete           Bound    default/pvc-azuredisk-zrs01   managed-csi-zrs            58s   Filesystem

NAME                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE     VOLUMEMODE
persistentvolumeclaim/pvc-azuredisk-lrs01   Bound    pvc-10b6bd60-89cf-489a-b68f-966143763b4e   10Gi       RWO            managed-csi-lrs   3m7s    Filesystem
persistentvolumeclaim/pvc-azuredisk-zrs01   Bound    pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb   10Gi       RWO            managed-csi-zrs   2m59s   Filesystem

NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS        IMAGES                                            SELECTOR
deployment.apps/nginx-azuredisk-lrs01   1/1     1            1           66s   nginx-azuredisk   mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine   app=nginx-azuredisk-lrs01
deployment.apps/nginx-azuredisk-zrs01   1/1     1            1           60s   nginx-azuredisk   mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine   app=nginx-azuredisk-zrs01

NAME                                         READY   STATUS    RESTARTS   AGE   IP            NODE                                NOMINATED NODE   READINESS GATES
pod/nginx-azuredisk-lrs01-5c4687b6d6-9474c   1/1     Running   0          67s   10.244.0.9    aks-nodepool1-28151597-vmss000001   <none>           <none>
pod/nginx-azuredisk-zrs01-96fc46f84-mrpnz    1/1     Running   0          61s   10.244.0.10   aks-nodepool1-28151597-vmss000001   <none>           <none>
takuya [ ~ ]$ 

また、Podは可用性ゾーンjapaneast-2aks-nodepool1-28151597-vmss000001ノード上で動作していることがわかります。

再掲: 作成した AKS ノードプールをkubectlコマンドから確認

takuya [ ~ ]$ kubectl get node -L topology.kubernetes.io/region -L topology.kubernetes.io/zone
NAME                                STATUS   ROLES   AGE   VERSION   REGION      ZONE
aks-nodepool1-28151597-vmss000000   Ready    agent   34m   v1.27.7   japaneast   japaneast-1
aks-nodepool1-28151597-vmss000001   Ready    agent   34m   v1.27.7   japaneast   japaneast-2

また、Azure Portal から、PV 名よりMC_リソースグループ内に Azure disk がそれぞれ作成されていることを確認します。

  • pvc-10b6bd60-89cf-489a-b68f-966143763b4e

    • Standard SSD LRS
    • Japan East (ゾーン 2)
      image.png
  • pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb

    • Standard SSD ZRS
    • Japan East
      image.png

以上で事前準備が整いました。

3. AKSのノード数を減らし、LRS と ZRS Azure disk の PV 挙動の違いを確認

image.png

いよいよ、ノード数を手動で2台から1台へ減少させ、LRS と ZRS Azure disk の PV 挙動の違いを確認していきます。

Azure Portal より、ノードプールのスケーリングでノード数2から1へ変更します。

image.png

ノードが1台のみになっていることを確認します。
image.png

kubectlコマンドからも確認します。

takuya [ ~ ]$ kubectl get node -L topology.kubernetes.io/region -L topology.kubernetes.io/zone
NAME                                STATUS   ROLES   AGE    VERSION   REGION      ZONE
aks-nodepool1-28151597-vmss000000   Ready    agent   143m   v1.27.7   japaneast   japaneast-1
takuya [ ~ ]$ 

つづいて、Pod の状況を確認します。

  • node02(vmss000001) で Running 中の Pod が 削除(terminated)され、node02(vmss000001) より node1(vmss000000) で Pod を起動しようとするが
  • node01(vmss000000) の可用性ゾーンでは、LRS の Azure Disk が存在しないため、LRS の Pod は PV/PVC をマウントできず、Pendingの状態となります。
  • 一方 ZRS の Pod は、node01 のリージョンに Azure Disk が存在するため、Pod はPV/PVC をマウント可能なため、Runningの状態となります。
takuya [ ~ ]$ kubectl get pv,pvc,deploy,pod -o wide 
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS      REASON   AGE   VOLUMEMODE
persistentvolume/pvc-10b6bd60-89cf-489a-b68f-966143763b4e   10Gi       RWO            Delete           Bound    default/pvc-azuredisk-lrs01   managed-csi-lrs            33m   Filesystem
persistentvolume/pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb   10Gi       RWO            Delete           Bound    default/pvc-azuredisk-zrs01   managed-csi-zrs            33m   Filesystem

NAME                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE   VOLUMEMODE
persistentvolumeclaim/pvc-azuredisk-lrs01   Bound    pvc-10b6bd60-89cf-489a-b68f-966143763b4e   10Gi       RWO            managed-csi-lrs   35m   Filesystem
persistentvolumeclaim/pvc-azuredisk-zrs01   Bound    pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb   10Gi       RWO            managed-csi-zrs   35m   Filesystem

NAME                                    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS        IMAGES                                            SELECTOR
deployment.apps/nginx-azuredisk-lrs01   0/1     1            0           33m   nginx-azuredisk   mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine   app=nginx-azuredisk-lrs01
deployment.apps/nginx-azuredisk-zrs01   1/1     1            1           33m   nginx-azuredisk   mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine   app=nginx-azuredisk-zrs01

NAME                                         READY   STATUS    RESTARTS   AGE     IP            NODE                                NOMINATED NODE   READINESS GATES
pod/nginx-azuredisk-lrs01-5c4687b6d6-2hn7l   0/1     Pending   0          7m14s   <none>        <none>                              <none>           <none>
pod/nginx-azuredisk-zrs01-96fc46f84-wrv85    1/1     Running   0          7m14s   10.244.1.13   aks-nodepool1-28151597-vmss000000   <none>           <none>

Pending状態の Pod の詳細状況をkubectl describeで確認すると

takuya [ ~ ]$ kubectl describe pod/nginx-azuredisk-lrs01-5c4687b6d6-2hn7l 
Name:             nginx-azuredisk-lrs01-5c4687b6d6-2hn7l
Namespace:        default
Priority:         0
Service Account:  default
Node:             <none>
Labels:           app=nginx-azuredisk-lrs01
                  pod-template-hash=5c4687b6d6
Annotations:      <none>
Status:           Pending
IP:               
IPs:              <none>
Controlled By:    ReplicaSet/nginx-azuredisk-lrs01-5c4687b6d6
Containers:
  nginx-azuredisk:
    Image:      mcr.microsoft.com/oss/nginx/nginx:1.17.3-alpine
    Port:       <none>
    Host Port:  <none>
    Command:
      /bin/sh
      -c
      while true; do echo $(date) >> /mnt/azuredisk/outfile; sleep 1; done
    Environment:  <none>
    Mounts:
      /mnt/azuredisk from azuredisk (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pknnr (ro)
Conditions:
  Type           Status
  PodScheduled   False 
Volumes:
  azuredisk:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  pvc-azuredisk-lrs01
    ReadOnly:   false
  kube-api-access-pknnr:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  8m56s  default-scheduler  0/2 nodes are available: 1 node(s) had volume node affinity conflict, 1 node(s) were unschedulable. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling..
  Warning  FailedScheduling  3m54s  default-scheduler  0/1 nodes are available: 1 node(s) had volume node affinity conflict. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..
takuya [ ~ ]$ 

以下のようにFailedScheduling として、LRS の Pod は Azure Disk を0/1 nodes are available: 1 node(s) had volume node affinity conflict. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..というメッセージで起動に失敗していることを確認できます。

  ----     ------            ----   ----               -------
  Warning  FailedScheduling  8m56s  default-scheduler  0/2 nodes are available: 1 node(s) had volume node affinity conflict, 1 node(s) were unschedulable. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling..
  Warning  FailedScheduling  3m54s  default-scheduler  0/1 nodes are available: 1 node(s) had volume node affinity conflict. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..

4. TIPS Kubernetes内での LRS, ZRS PV の制御

Kubernetes 上で、LRS の Azure Disk と ZRS の Azure Disk の PV リソースの中身を見てみると、Kubernetes の Afinity ルール の機能を利用して、可用性ゾーンを制御していることがわかります。

takuya [ ~ ]$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS      REASON   AGE
pvc-10b6bd60-89cf-489a-b68f-966143763b4e   10Gi       RWO            Delete           Bound    default/pvc-azuredisk-lrs01   managed-csi-lrs            39m
pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb   10Gi       RWO            Delete           Bound    default/pvc-azuredisk-zrs01   managed-csi-zrs            39m
takuya [ ~ ]$ kubectl get pv pvc-10b6bd60-89cf-489a-b68f-966143763b4e -o yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: disk.csi.azure.com
    volume.kubernetes.io/provisioner-deletion-secret-name: ""
    volume.kubernetes.io/provisioner-deletion-secret-namespace: ""
  creationTimestamp: "2023-12-13T05:41:32Z"
  finalizers:
  - kubernetes.io/pv-protection
  - external-attacher/disk-csi-azure-com
  name: pvc-10b6bd60-89cf-489a-b68f-966143763b4e
  resourceVersion: "28412"
  uid: f6fc711e-e32a-4204-a1ff-7d899a761554
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-azuredisk-lrs01
    namespace: default
    resourceVersion: "28386"
    uid: 10b6bd60-89cf-489a-b68f-966143763b4e
  csi:
    driver: disk.csi.azure.com
    volumeAttributes:
      csi.storage.k8s.io/pv/name: pvc-10b6bd60-89cf-489a-b68f-966143763b4e
      csi.storage.k8s.io/pvc/name: pvc-azuredisk-lrs01
      csi.storage.k8s.io/pvc/namespace: default
      requestedsizegib: "10"
      skuname: StandardSSD_LRS
      storage.kubernetes.io/csiProvisionerIdentity: 1702439180671-9937-disk.csi.azure.com
    volumeHandle: /subscriptions/379623ee-242c-4125-9c4c-7dfb8d74cdc9/resourceGroups/mc_demo-aks-zrs_demo-aks-zrs01_japaneast/providers/Microsoft.Compute/disks/pvc-10b6bd60-89cf-489a-b68f-966143763b4e
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-2
  persistentVolumeReclaimPolicy: Delete
  storageClassName: managed-csi-lrs
  volumeMode: Filesystem
status:
  phase: Bound
takuya [ ~ ]$  kubectl get pv pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb  -o yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: disk.csi.azure.com
    volume.kubernetes.io/provisioner-deletion-secret-name: ""
    volume.kubernetes.io/provisioner-deletion-secret-namespace: ""
  creationTimestamp: "2023-12-13T05:41:37Z"
  finalizers:
  - kubernetes.io/pv-protection
  - external-attacher/disk-csi-azure-com
  name: pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb
  resourceVersion: "28462"
  uid: e496d654-b15f-4a34-8419-8afe702d2296
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: pvc-azuredisk-zrs01
    namespace: default
    resourceVersion: "28430"
    uid: 95c186f1-ba4f-4e4f-ae6a-af2d565acfcb
  csi:
    driver: disk.csi.azure.com
    volumeAttributes:
      csi.storage.k8s.io/pv/name: pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb
      csi.storage.k8s.io/pvc/name: pvc-azuredisk-zrs01
      csi.storage.k8s.io/pvc/namespace: default
      requestedsizegib: "10"
      skuname: StandardSSD_ZRS
      storage.kubernetes.io/csiProvisionerIdentity: 1702439180671-9937-disk.csi.azure.com
    volumeHandle: /subscriptions/379623ee-242c-4125-9c4c-7dfb8d74cdc9/resourceGroups/mc_demo-aks-zrs_demo-aks-zrs01_japaneast/providers/Microsoft.Compute/disks/pvc-95c186f1-ba4f-4e4f-ae6a-af2d565acfcb
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-1
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-2
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-3
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - ""
  persistentVolumeReclaimPolicy: Delete
  storageClassName: managed-csi-zrs
  volumeMode: Filesystem
status:
  phase: Bound
takuya [ ~ ]$ 

nodeAffinity:により、マウント可能な可用性ゾーンがコントロールされていることがわかります。

  • LRSの場合は作成時の特定の可用性ゾーンjapaneast-2のみが設定されている
# 抜粋
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-2
  • ZRSの場合は、リージョン内のすべての可用性ゾーンjapaneast-1,japaneast-2,japaneast-3,””(可用性ゾーン無し)が設定されている
# 抜粋
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-1
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-2
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - japaneast-3
      - matchExpressions:
        - key: topology.disk.csi.azure.com/zone
          operator: In
          values:
          - ""

5. まとめ

  • 複数の可用性ゾーンを使用する Azure Kubernetes Service (AKS) クラスターにおいて、Azure Disk の PersitentVolume(PV)を利用する場合は、ZRS (ゾーン冗長ストレージ | Zone Redundant Storage)を利用しないと、ノードの増減や、バージョンアップ等のローリングアップデートなどで、意図した可用性を実現できませんのでご注意ください。
  • 複数の可用性ゾーンを使用する AKS クラスターで、Azure Disk の PersitentVolume(PV)を利用する必要がある場合は、必ず、ZRS (ゾーン冗長ストレージ | Zone Redundant Storage)を利用してください。

以上


4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?