Tanzu Kubernetes Grid 1.3.0でvSphere CSIで作られたPersistent VolumeをOffline Volume Expansionするworkaround

ℹ️ TKG 1.4.0ではOnline Volume Expansionに対応しました

ℹ️ TKG 1.3.1では以下のWorkaroundは不要です

TKG 1.3.0のデフォルトのCSIの設定ではPersistent Volumeのリサイズは行えません。csi-resizerが設定されていないためです。

次のコマンドでREADY5/5になっている場合は、csi-resizerが存在しません。

$ kubectl get pods -n kube-system -l app=vsphere-csi-controller
NAME                                     READY   STATUS    RESTARTS   AGE
vsphere-csi-controller-<ID-HASH>         5/5     Running   0          6m49s

csi-resizerを追加してOffline Volume Expansionを行うWorkaroundは次のドキュメントに記述されています。

https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.3/vmware-tanzu-kubernetes-grid-13/GUID-tanzu-k8s-clusters-storage.html#enable-offline-volume-expansion-for-vsphere-csi-vsphere-7-6

Offline Volume Expansionなので、Online(使用中)のリサイズには対応していません。
ちなみに、使用中のVolumeをResizeしようとするとVolume is attached to node. Only offline volume expansion is supportedというエラーが発生します。
Online Volume ExpansionはvSphere CSI driver v2.2で対応予定です。 https://vsphere-csi-driver.sigs.k8s.io/features/volume_expansion.html

このドキュメントのやり方はマニュアルな作業が多くて面倒くさい上にRBACの設定が足りていません。

この記事ではyttのoverlayを使用して、このドキュメントの作業を自動化し、かつ今後作成されるクラスタに対しては自動で適用されるようにします。 Add-onを使用するため、TKG 1.2には対応していません。

~/.tanzu/tkg/providers/infrastructure-vsphere/ytt/vsphere-overlay.yamlに次の内容を追記してください。

#@ load("@ytt:overlay", "overlay")

#@ csi_addon = lambda i,left,right: left["metadata"]["name"].endswith("-vsphere-csi-addon")
#@ secret = overlay.subset({"kind": "Secret"})
#@overlay/match by=overlay.and_op(csi_addon, secret), expects="1+"
#@overlay/match-child-defaults missing_ok=True
---
stringData:
  overlays.yaml: |
    #@ load("@ytt:overlay", "overlay")
    #@overlay/match by=overlay.subset({"kind": "Deployment", "metadata": {"name": "vsphere-csi-controller"}})
    ---
    spec:
      template:
        spec:
          containers:
          #@overlay/append
          - name: csi-resizer
            image: projects.registry.vmware.com/tkg/kubernetes-csi_external-resizer:v1.0.0_vmware.1
            args:
            - "--v=4"
            - "--timeout=300s"
            - "--csi-address=$(ADDRESS)"
            - "--leader-election"
            env:
            - name: ADDRESS
              value: /csi/csi.sock
            volumeMounts:
            - mountPath: /csi
              name: socket-dir
    
    #@overlay/match by=overlay.subset({"kind": "ClusterRole", "metadata": {"name": "vsphere-csi-controller-role"}})
    ---
    rules:
    #@overlay/append
    - apiGroups: [""]
      resources: ["persistentvolumeclaims/status"]
      verbs: ["patch"]

次のコマンドを実行していください。CLUSTER_NAMEは変更してください。

export CLUSTER_NAME=CHANGE_ME
export NAMESPACE=default
export CLUSTER_PLAN=dev
export VSPHERE_CONTROL_PLANE_ENDPOINT=dummy
export _TKG_CLUSTER_FORCE_ROLE=workload

export FILTER_BY_ADDON_TYPE=csi/vsphere-csi
tanzu cluster create ${CLUSTER_NAME} --dry-run -f ~/.tanzu/tkg/cluster-config.yaml > ${CLUSTER_NAME}-csi.yml

ContextをManagement Clusterに変更して作成したyamlを適用します。

kubectl config use-context carrot-admin@carrot
kubectl apply -f ${CLUSTER_NAME}-csi.yml

次のコマンドでREADY6/6になっていることを確認してください。kapp-controllerの更新間隔の設定上、Add-onの更新に最大5分間かかります。

$ kubectl get pods -n kube-system -l app=vsphere-csi-controller
NAME                                     READY   STATUS    RESTARTS   AGE
vsphere-csi-controller-<ID-HASH>         6/6     Running   0          6m49s

csi-controllerのログを確認してください。

kubectl logs deploy/vsphere-csi-controller -n kube-system -c csi-resizer

次のログが出ていればcsi-resizerが起動しています。

I0308 23:44:45.079638       1 controller.go:241] Starting external resizer csi.vsphere.vmware.com 

実際にPersistent Volumeのリサイズを行います。

次のファイルpvc.ymlを作成し、kubectl apply -f pvc.ymlを実行します。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

次のような結果が出力されます。

$ kubectl get pv,pvc                
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
persistentvolume/pvc-abbd7a41-937c-40c4-bf8d-99b8fd22afc5   1Gi        RWO            Delete           Bound    default/task-pv-claim     default                 78s

NAME                                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/task-pv-claim   Bound    pvc-abbd7a41-937c-40c4-bf8d-99b8fd22afc5   1Gi        RWO            default        80s

次のこのPVをリサイズします。

pvc.ymlを次のように変更し、kubectl apply -f pvc.ymlを実行します。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi

次のコマンドを実行するとPersistent Volumeが3Giに変更されていることがわかります。PVCの方はPodにmountされるまでが1Giのままのようです。

$ kubectl get pv,pvc           
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
persistentvolume/pvc-abbd7a41-937c-40c4-bf8d-99b8fd22afc5   3Gi        RWO            Delete           Bound    default/task-pv-claim     default                 2m46s

NAME                                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/task-pv-claim   Bound    pvc-abbd7a41-937c-40c4-bf8d-99b8fd22afc5   1Gi        RWO            default        2m48s

vCenterを見ると実際にExtend a virtual disk to the new capacityというTaskが実行されています。

image

またContainer Volumesを確認すると、該当のVolumeが確かに3Giになっていることがわかります。

image


TKG 1.3.0でCSI ResizerによってPVをOffline Volume Expansionするworkaroundを紹介しました。TKG 1.3.1で対応されていて欲しいですね。

なお、現在のバージョンのCSI DriverではOnline Volume Expansionはできません。 利用中のPVをresizeしたい場合、Pod(Deployment)を削除した状態で、PVがattachされているVMを削除しOffline状態にすれば成功しました。削除されたVMはCluster APIのMachine Health Checkで復旧します。