Manually expanding VMware VMDK Persistent Volume in OpenShift

Edmond Chan
4 min readFeb 25, 2021

--

You may have application running inside OpenShift Container Platform, and that uses a Persistent Volume provisioned from vSphere VMDK. One day, when you find the disk becoming full and nothing could be cleaned up, the problem arise. How to directly expand the volume without losing any data?

Suppose you have a Deployment called MyApp , with PVC MyApp-pvc and PV MyApp-pv , here is how to expand the storage.

Step 1) Stop the application

Stop the application by scaling down the deployment to 0 replicas:

oc scale deploy MyApp --replicas=0

Step 2) Identify the VMDK file of the Persistent Volume

Use below command to get the name of the VMDK disk including its path.

oc get pv MyApp-pv -o jsonpath='{.spec.vsphereVolume.volumePath}' && echo

Step 3) Expand the vSphere VMDK disk

You need to find a Linux VM as helper machine to expand the VMDK disk.

From vCenter web console, attach the VMDK disk to the Linux helper machine.

Verify the VMDK disk has been attached. In below example, it is sdb .

[root@helper ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 600M 0 part /boot/efi
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 198.4G 0 part
├─rhel-root 253:0 0 50G 0 lvm /
├─rhel-swap 253:1 0 7.9G 0 lvm [SWAP]
└─rhel-home 253:2 0 140.5G 0 lvm /home
sdb 8:16 0 50G 0 disk

Go back to vCenter console again, change the size of the VMDK disk to the new desired size. For example, changing it from 50G to 200G.

In the helper machine, rescan the disk and verify that it has been expanded.

[root@helper ~]# echo 1>/sys/class/block/sdb/device/rescan
[root@helper ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 200G 0 disk
├─sda1 8:1 0 600M 0 part /boot/efi
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 198.4G 0 part
├─rhel-root 253:0 0 50G 0 lvm /
├─rhel-swap 253:1 0 7.9G 0 lvm [SWAP]
└─rhel-home 253:2 0 140.5G 0 lvm /home
sdb 8:16 0 200G 0 disk

Step 4) Expand the filesystem

Mount the disk on the helper machine, check the current filesystem size and verify the contents accordingly.

[root@helper ~]# mkdir /mnt/datadisk
[root@helper ~]# mount -t ext4 /dev/sdb /mnt/datadisk
[root@helper ~]# cd /mnt/datadisk
[root@helper ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
...
/dev/sdb ext4 49G 49G 0 100% /mnt/datadisk
[root@helper ~]# ls -l
...

Expand the filesystem.

[root@helper ~]# resize2fs /dev/sdb

Verify that the filesystem has been expanded.

[root@helper ~]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
...
/dev/sdb ext4 199G 49G 150G 25% /mnt/datadisk

Umount the disks from the helper machine.

[root@helper ~]# umount /mnt/datadisk

Step 5) Detach the vSphere VMDK disk from the helper machine

You can now detach the VMDK disk from your helper machine via vCenter web console.

Step 6) Update the PV configuration

Check if the PV’s Reclaim Policy is Retain. If not, modify it accordingly.

$ oc get pv MyApp-pv -o jsonpath='{.spec.persistentVolumeReclaimPolicy}' && echo
Delete
$ oc patch pv MyApp-pv --patch '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}' --type=merge
persistentvolume/MyApp-pv patched
$ oc get pv MyApp-pv -o jsonpath='{.spec.persistentVolumeReclaimPolicy}' && echo
Retain

Modify the capacity of the PV to match with the new disk size.

$ oc patch pv MyApp-pv --patch '{"spec":{"capacity":{"storage":"200Gi"}}}' --type=merge
persistentvolume/MyApp-pv patched
$ oc get pv MyApp-pv -o jsonpath='{.spec.capacity.storage}' && echo
200Gi

Step 7) Recreate the PVC

Dump the current PVC config.

oc get pvc MyApp-pvc -o yaml > MyApp-pvc.yaml

Edit the YAML file of the PVC with the new storage size.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
pv.kubernetes.io/bind-completed: "yes"
pv.kubernetes.io/bound-by-controller: "yes"
volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/vsphere-volume
finalizers:
- kubernetes.io/pvc-protection
name: MyApp-pvc
namespace: MySpace
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
storageClassName: vsphere
volumeMode: Filesystem
volumeName: MyApp-pv

Delete the current PVC and create it again using the YAML file.

oc delete pvc MyApp-pvc
oc create -f MyApp-pvc.yaml

Check the status of the PVC, you will find that it could not be bound.

$ oc get pvc -n openshift-monitoring
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
MyApp-pvc Lost MyApp-pv 0 vsphere 56s

To fix this, patch the PVs by setting the claimRef to null .

oc patch pv MyApp-pv -p '{"spec":{"claimRef": null}}'

Verify the status of the PVC again, it should now be bound.

$ oc get pvc -n openshift-monitoring
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
MyApp-pvc Bound MyApp-pv 200G vsphere 3m

Step 8) Resume the application

Resume the application by scaling up the deployment back to 1 replicas:

oc scale deploy MyApp --replicas=1

The application is now resumed with all existing data persisted, and has a larger disk to contain more new data.

--

--

Edmond Chan
Edmond Chan

Written by Edmond Chan

Infrastructure Architect experienced in design and implementation of IT solutions for enterprises

No responses yet