
If you are not familiar with the oc command, refer to OpenShift - Getting Started with the oc command.
If you are not familiar with Volume Snapshots, check out my article OpenShift - Getting Started with Volume Snapshots.
This assumes you have already Created a Volume Snapshot.
Let's say you have a pod that has a Persistent Volume Claim mounted. For more details on mounting a Persistent Volume Claim in a container, check out my article OpenShift - Mount a Persistent Volume Claim in a container. For example, perhaps my-deployment has Persistent Volume Claim my-pvc mounted to /var/data in my-container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
template:
spec:
containers:
- name: my-container
volumeMounts:
- mountPath: /var/data
name: my-volume
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc
You can also see this in the OpenShift console at Workloads > Pods > your pod.

And let's say there is a file named foo.txt at /var/data that contains Hello World.
~]$ oc exec pod/ose-hello-openshift-rhel8-69f4d74fbc-k5r4p --namespace my-project -- ls -l /var/data
-rw-r--r--. 1 1001060000 1001060000 12 Apr 29 01:30 foo.txt
~]$ oc exec pod/ose-hello-openshift-rhel8-69f4d74fbc-k5r4p --namespace my-project -- cat /var/data/foo.txt
Hello World
You can also see this in the OpenShift console at Workloads > Pods > your pod > Terminal.

Volume Snapshot
And let's say you created a Volume Snapshot of Persistent Volume Claim my-pvc. The oc get volumesnaphot command can then be used to list the Volume Snapshots that have been taken. It is important to recognize that the Volume Snapshot does not actually contain the content of the volume. Instead, the Volume Snapshot Content (more on this in a moment) contains the actual content of the volume. The Volume Snapshot is like the parent resource that ultimately attempts to create the Volume Snapshot Content.
]$ oc get volumesnapshots --namespace my-project
NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE
my-volume-snapshot true my-pvc 1Gi csi-vsphere-vsc snapcontent-ee26485f-499e-42db-85d4-d4b6f6d7b9bc 3m14s 11m
Or in the OpenShift console, at Storage > VolumeSnapshots.

Volume Snapshot Content
You can then view the YAML of the volume snapshot and something like this should be returned. Notice in this example that the status shows the volume snapshot has been taken and there is a Volume Snapshot Content. Nice.
]$ oc get volumesnapshot my-volume-snapshot --namespace m-project --output yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
creationTimestamp: "2025-04-25T01:22:11Z"
finalizers:
- snapshot.storage.kubernetes.io/volumesnapshot-as-source-protection
- snapshot.storage.kubernetes.io/volumesnapshot-bound-protection
generation: 1
name: my-pvc-volume-snapshot
namespace: my-project
resourceVersion: "505318001"
uid: ee26485f-499e-42db-85d4-d4b6f6d7b9bc
spec:
source:
persistentVolumeClaimName: my-pvc
volumeSnapshotClassName: csi-vsphere-vsc
status:
boundVolumeSnapshotContentName: snapcontent-ee26485f-499e-42db-85d4-d4b6f6d7b9bc
creationTime: "2025-04-25T01:29:59Z"
readyToUse: true
restoreSize: 1Gi
Or, in the OpenShift console, Storage > VolumeSnapshots if you select the Volume Snapshot and you see VolumeSnapshotContent then a snapshot of the volume has been taken.

The oc get VolumeSnapshotContent command can be used to list the Volume Snapshot Contents that have been taken.
]$ oc get volumesnapshotcontent --namespace my-project
NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT VOLUMESNAPSHOTNAMESPACE AGE
snapcontent-d1e3b556-fb07-40b9-b032-976c9b5a84d7 true 1073741824 Delete csi.vsphere.vmware.com csi-vsphere-vsc my-volume-snapshot my-project 7m45s
Or in the OpenShift console at Storage > VolumeSnapshotContents.

Now let's make some change to the content in Persistent Volume my-pv. For example, let's overwrite foo.txt to have "Goodbye World" instead of "Hello World".
~]$ oc exec pod/ose-hello-openshift-rhel8-69f4d74fbc-k5r4p -it --namespace my-project -- /bin/bash
bash-4.4$ echo "Goodbye World" > /var/data/foo.txt
bash-4.4$ exit
~]$ oc exec pod/ose-hello-openshift-rhel8-69f4d74fbc-k5r4p --namespace my-project -- cat /var/data/foo.txt
Goodbye World
This can also be done in the OpenShift console at Workloads > Pods > your pod > Terminal.

Now foo.txt in the Volume Snapshot Content should have "Hello World" since the snapshot was taken before foo.txt was overwritten to have "Goodbye World" and foo.txt in Persistent Volume my-pv has "Goodbye World".
Restore Volume Snapshot Content
Let's create a new Persistent Volume Claim from the snapshot. For example, let's say you have the following in a YAML file. In this example, the Persistent Volume Claim will be created from the Volume Snapshot named my-volume-snapshot.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc-restore
namespace: my-project
spec:
accessModes:
- ReadWriteOnce
dataSource:
name: my-volume-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
resources:
requests:
storage: 1Gi
storageClassName: thin-csi
volumeMode: Filesystem
The oc apply command can be used to create the Persistent Volume Claim from the Volume Snapshot.
]$ oc apply --filename my-pvc-restore.yml
persistentvolumeclaim/my-pvc-restore created
Or this can be done in the OpenShift console at Storage > VolumeSnapshots > your volume snapshot > Restore as new PVC.

The oc get PersistentVolumeClaims command can be used to list the Persistent Volume Claims. Notice in this example that the Persistent Volume Claim status is Pending. This means that the TBD is WaitForFirstConsumer instead of Immediate.
]$ oc get PersistentVolumeClaims --namespace my-project
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
my-pvc Bound pvc-819117a8-1a79-4be6-b9e7-620845979db6 1Gi RWO thin-csi <unset> 4d
my-pvc-restore Pending thin-csi <unset> 59s
Or in the OpenShift console at Storage > PersistentVolumeClaims.

In this example, describing the Persistent Volume Claim shows that the Persistent Volume Claim is Pending because it's waiting for the first consumer.
]$ oc describe PersistentVolumeClaim my-pvc-restore --namespace my-project
Name: my-pvc-restore
Namespace: my-project
StorageClass: thin-csi
Status: Pending
Volume:
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
DataSource:
APIGroup: snapshot.storage.k8s.io
Kind: VolumeSnapshot
Name: my-volume-snapshot
Used By: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 7s (x6 over 77s) persistentvolume-controller waiting for first consumer to be created before binding
Let's update our Deployment to mount the Persistent Volume Claim in my-container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
template:
spec:
containers:
- name: my-container
volumeMounts:
- mountPath: /var/data
name: my-volume
- mountPath: /var/restore
name: my-volume-restore
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc
- name: my-volume-restore
persistentVolumeClaim:
claimName: my-pvc-restore
And now the Persistent Volume Claim should be Bound instead of Pending.
]$ oc get PersistentVolumeClaims --namespace my-project
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
my-pvc Bound pvc-819117a8-1a79-4be6-b9e7-620845979db6 1Gi RWO thin-csi <unset> 4d
my-pvc-restore Bound pvc-2af62b4a-aab6-4e35-922b-8ce73d84c5f4 1Gi RWO thin-csi <unset> 10m
Describing the Persistent Volume Claim should return additional events showing the Persistent Volume Claim was bound.
]$ oc describe PersistentVolumeClaim my-pvc-restore --namespace my-project
Name: my-pvc-restore
Namespace: my-project
StorageClass: thin-csi
Status: Bound
Volume: pvc-2af62b4a-aab6-4e35-922b-8ce73d84c5f4
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
volume.kubernetes.io/selected-node: lab001-worker-jttdr
volume.kubernetes.io/storage-provisioner: csi.vsphere.vmware.com
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWO
VolumeMode: Filesystem
DataSource:
APIGroup: snapshot.storage.k8s.io
Kind: VolumeSnapshot
Name: my-volume-snapshot
Used By: ose-hello-openshift-rhel8-6dbcf6858b-hrp26
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 4m51s (x26 over 10m) persistentvolume-controller waiting for first consumer to be created before binding
Normal Provisioning 67s csi.vsphere.vmware.com_vmware-vsphere-csi-driver-controller-5b4755745d-r29xs_f59b2dd4-0540-48e7-9e8a-4b3725a8d979 External provisioner is provisioning volume for claim "my-project/my-pvc-restore"
Normal ProvisioningSucceeded 66s csi.vsphere.vmware.com_vmware-vsphere-csi-driver-controller-5b4755745d-r29xs_f59b2dd4-0540-48e7-9e8a-4b3725a8d979 Successfully provisioned volume pvc-2af62b4a-aab6-4e35-922b-8ce73d84c5f4
And foo.txt from the restored Persistent Volume Claim should have "Hello World". Awesome!
~]$ oc exec pod/ose-hello-openshift-rhel8-69f4d74fbc-k5r4p --namespace my-project -- cat /var/data/foo.txt
Goodbye World
~]$ oc exec pod/ose-hello-openshift-rhel8-69f4d74fbc-k5r4p --namespace my-project -- cat /var/restore/foo.txt
Hello World
Did you find this article helpful?
If so, consider buying me a coffee over at