vSphere CSI Driver - Volume Expansion

CSI Volume Expansion was introduced as an alpha feature in Kubernetes 1.14 and it was promoted to beta in Kubernetes 1.16. The vSphere CSI driver supports volume expansion for dynamically/statically created block volumes only.

Kubernetes supports two modes of volume expansion - offline and online. When the PVC is being used by a Pod i.e it is mounted on a node, the resulting volume expansion operation is termed as an online expansion. In all other cases, it is an offline expansion.

Refer to the table below to know the minimum version of the vSphere CSI driver, vCenter and ESXi release versions for this feature.

Minimum vSphere CSI Driver release Minimum vCenter Release Minimum ESXi Release
Offline volume expansion v2.0 7.0 7.0
Online volume expansion v2.2 7.0u2 7.0u2

Make sure all the ESXi hosts of the cluster are on the same version as the vCenter. For volume expansion to work, the vCenter and all the ESX hosts of the cluster need to be on the supported versions of the feature i.e version 7.0 and above, otherwise volume resize operation fails with A general system error occurred: Failed to lock the file: api = DiskLib_Grow error.

Refer to the compatibility matrix page for more details.

Feature Gate

Expand CSI Volumes feature was promoted to beta in kubernetes 1.16, therefore it is enabled by default. For Kubernetes releases before 1.16, ExpandCSIVolumes feature gate needs to be enabled for this feature to support volume expansion in CSI drivers.

Sidecar Container

An external-resizer sidecar container implements the logic of watching the Kubernetes API for Persistent Volume claim edits, issuing the ControllerExpandVolume RPC call against a CSI endpoint and updating the PersistentVolume object to reflect the new size. This container has already been deployed for you as a part of the vsphere-csi-controller pod.

Requirements

To use this feature, first step is to modify the StorageClass definition in the Kubernetes Cluster as mentioned below.

StorageClass

Create a new StorageClass or edit the existing StorageClass to set allowVolumeExpansion to true.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: example-block-sc
provisioner: csi.vsphere.vmware.com
allowVolumeExpansion: true

Proceed to create/edit a PVC by using this storage class.

Expand PVC

Prior to increasing the size of a PVC make sure that the PVC is in Bound state. If you are using a statically provisioned PVC, ensure that the PVC and the PV specs have the storageClassName parameter pointing to a storage class which has allowVolumeExpansion set to true.

Online mode

Consider a scenario where you deployed a PVC with a StorageClass in which allowVolumeExpansion is set to true and then created a pod to use this PVC.

$ kubectl get pvc,pv,pod
NAME                                      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS           AGE
persistentvolumeclaim/example-block-pvc   Bound    pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd   1Gi        RWO            example-block-sc       8m5s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS           REASON   AGE
persistentvolume/pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd   1Gi        RWO            Delete           Bound    default/example-block-pvc   example-block-sc                7m59s

NAME                    READY   STATUS    RESTARTS   AGE
pod/example-block-pod   1/1     Running   0          7m1s

Patch the PVC to increase its requested storage size (in this case, to 2Gi):

$ kubectl patch pvc example-block-pvc -p '{"spec": {"resources": {"requests": {"storage": "2Gi"}}}}'
persistentvolumeclaim/example-block-pvc patched

This will trigger an expansion in the volume associated with the PVC in vSphere Cloud Native Storage.

The PVC and the PV will reflect the increase in size after the volume underneath has expanded. The describe output of the PVC will look similar to the following:

$ kubectl describe pvc example-block-pvc
Name:          example-block-pvc
Namespace:     default
StorageClass:  example-block-sc
Status:        Bound
Volume:        pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
               volume.beta.kubernetes.io/storage-provisioner: csi.vsphere.vmware.com
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      2Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Mounted By:    example-block-pod
Events:
  Type     Reason                      Age   From                                                                                                Message
  ----     ------                      ----  ----                                                                                                -------
  Normal   ExternalProvisioning        19m   persistentvolume-controller                                                                         waiting for a volume to be created, either by external provisioner "csi.vsphere.vmware.com" or manually created by system administrator
  Normal   Provisioning                19m   csi.vsphere.vmware.com_vsphere-csi-controller-5d8c5c7d6-9r9kv_7adc4efc-10a6-4615-b90b-790032cc4569  External provisioner is provisioning volume for claim "default/example-block-pvc"
  Normal   ProvisioningSucceeded       19m   csi.vsphere.vmware.com_vsphere-csi-controller-5d8c5c7d6-9r9kv_7adc4efc-10a6-4615-b90b-790032cc4569  Successfully provisioned volume pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd
  Warning  ExternalExpanding           75s   volume_expand                                                                                       Ignoring the PVC: didn't find a plugin capable of expanding the volume; waiting for an external controller to process this PVC.
  Normal   Resizing                    75s   external-resizer csi.vsphere.vmware.com                                                             External resizer is resizing volume pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd
  Normal   FileSystemResizeRequired    69s   external-resizer csi.vsphere.vmware.com                                                             Require file system resize of volume on node
  Normal   FileSystemResizeSuccessful  6s    kubelet, k8s-node-072                                                                               MountVolume.NodeExpandVolume succeeded for volume "pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd"

The PVC will go through events Resizing to FileSystemResizeRequired to finally FileSystemResizeSuccessful.

The PV will also reflect the expanded size.

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS           REASON   AGE
pvc-84c89bf9-8455-4633-a8c8-cd623e155dbd   2Gi        RWO            Delete           Bound    default/example-block-pvc   example-block-sc                25m

This marks the completion of the online volume expansion operation.

Offline mode

Consider a scenario where you deployed a PVC with a StorageClass in which allowVolumeExpansion is set to true.

$ kubectl get pvc,pv
NAME                                      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS           AGE
persistentvolumeclaim/example-block-pvc   Bound    pvc-9e9a325d-ee1c-11e9-a223-005056ad1fc1   1Gi        RWO            example-block-sc       5m5s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS           REASON   AGE
persistentvolume/pvc-9e9a325d-ee1c-11e9-a223-005056ad1fc1   1Gi        RWO            Delete           Bound    default/example-block-pvc   example-block-sc                5m18s

Patch the PVC to increase its requested storage size (in this case, to 2Gi):

$ kubectl patch pvc example-block-pvc -p '{"spec": {"resources": {"requests": {"storage": "2Gi"}}}}'
persistentvolumeclaim/example-block-pvc patched

This will trigger an expansion in the volume associated with the PVC in vSphere Cloud Native Storage which finally gets reflected on the capacity of the corresponding PV object. Note that the capacity of the PVC will not change until the PVC is used by a Pod i.e mounted on a node.

$ kubectl get pv
NAME                                       CAPACITY ACCESS MODES RECLAIM POLICY STATUS   CLAIM                       STORAGECLASS           REASON AGE
pvc-9e9a325d-ee1c-11e9-a223-005056ad1fc1   2Gi           RWO         Delete     Bound    default/example-block-pvc   example-block-sc              6m44s

$ kubectl get pvc
NAME                STATUS VOLUME                                     CAPACITY ACCESS MODES   STORAGECLASS       AGE
example-block-pvc   Bound  pvc-9e9a325d-ee1c-11e9-a223-005056ad1fc1   1Gi           RWO       example-block-sc   6m57s

As you can see above, the capacity of the PVC is unchanged. You will also notice a FilesystemResizePending condition applied on the PVC when you describe it.

Now create a pod to use the PVC:

apiVersion: v1
kind: Pod
metadata:
  name: example-block-pod
spec:
  containers:
  - name: test-container
    image: gcr.io/google_containers/busybox:1.24
    command: ["/bin/sh", "-c", "echo 'hello' > /mnt/volume1/index.html  && chmod o+rX /mnt /mnt/volume1/index.html && while true ; do sleep 2 ; done"]
    volumeMounts:
    - name: test-volume
      mountPath: /mnt/volume1
  restartPolicy: Never
  volumes:
  - name: test-volume
    persistentVolumeClaim:
      claimName: example-block-pvc
$ kubectl create -f example-pod.yaml
pod/example-block-pod created

The Kubelet on the node will trigger the filesystem expansion on the volume when the PVC is attached to the Pod.

$ kubectl get pod
NAME               READY STATUS  RESTARTS AGE
example-block-pod   1/1  Running 0        65s
$ kubectl get pvc
NAME                STATUS VOLUME                                    CAPACITY ACCESS MODES STORAGECLASS     AGE
example-block-pvc   Bound  pvc-24114458-9753-428e-9c90-9f568cb25788   2Gi         RWO      example-block-sc 2m12s

$ kubectl get pv
NAME                                       CAPACITY ACCESS MODES RECLAIM POLICY STATUS   CLAIM                     STORAGECLASS           REASON AGE
pvc-24114458-9753-428e-9c90-9f568cb25788   2Gi           RWO        Delete      Bound    default/example-block-pvc example-block-sc              2m3s

You will notice that the capacity of PVC has been modified and the FilesystemResizePending condition has been removed from the PVC. Offline volume expansion is complete.

results matching ""

    No results matching ""