, ,

VKS Cluster Volume Snapshots, Creation, Restore and Deletion (VCAP-VKS Exam Series, Part 24)

Objective 4.9 hands on. Install the two webhook packages a VKS cluster needs before snapshots exist at all, take a CSI snapshot of a PostgreSQL claim, restore it into a new PVC, and learn why a snapshot is not a rollback.

VCAP-VKS Exam Series · Part 24 of 34
Who this is for: A candidate who wired the standard package repository into tkg-system in Part 23 and now has to use it for something a running database depends on. This Part covers Objective 4.9, published wording Create and manage snapshots in VKS clusters. Terms defined on first use: VKS is vSphere Kubernetes Service, the product formerly named TKG Service or TKGS, and on VCF 9.0 the rename is unfinished so tkg still appears in namespaces, CRD groups and documentation URLs; CSI is the Container Storage Interface; pvCSI is the paravirtual CSI driver that a VKS cluster runs so its storage calls are proxied to the Supervisor; a PVC is a PersistentVolumeClaim; a VolumeSnapshot is a point in time copy of a block volume; a VolumeSnapshotClass names the driver and deletion policy used to take one; a VolumeSnapshotContent is the cluster scoped object that binds a VolumeSnapshot to real storage; a VKr is a vSphere Kubernetes release, the versioned node image a cluster runs.
Key takeaways: Objective 4.9 is one of the few objectives where the correct answer starts with a capability that is missing. Snapshot machinery ships enabled on the Supervisor and ships absent from every VKS cluster you provision, so the first action is installing cert-manager, external-csi-snapshot-webhook and vsphere-pv-csi-webhook from the standard package repository. Only block volumes can be snapshotted, never a vSphere file volume. Do not author your own VolumeSnapshotClass; use the pre-existing one, which carries a Delete deletion policy, because Retain is not supported here. A volume that has snapshots cannot be expanded or deleted, which is the operational trap. Headline command: kubectl get volumesnapshot -n orders, and the column that matters is READYTOUSE.

Snapshot support that does not exist until you install it

Here is the line of output that reframes this whole objective. Same estate, same storage, same person at the keyboard, two contexts seconds apart.

# Versions everything below was run against. VCF 9.0, vCenter 9.0.0.0 build 24755230 Supervisor v1.31.4+vmware.wcp.2 VKS 3.3.1, ClusterClass builtin-generic-v3.1.0 Target cluster vks-lifecycle-01 in vSphere Namespace ns-platform-a, VKr v1.32.0 kubectl v1.32.2, kubectl-vsphere plugin 9.0.0, VCF CLI v9.0.0 Storage policies vsan-default and vsan-highperf assigned to ns-platform-a Workload pg-orders, a PostgreSQL StatefulSet, PVC data-pg-orders-0, 100Gi block # Credentials come from the shell, never from a file in git. export VSPHERE_USER=svc-vks-admin@lab.local read -s VSPHERE_PASSWORD && export VSPHERE_PASSWORD kubectl vsphere login –server 10.50.10.20 –tanzu-kubernetes-cluster-name vks-lifecycle-01 –tanzu-kubernetes-cluster-namespace ns-platform-a –vsphere-username $VSPHERE_USER # Context 1. Inside the workload cluster, following any upstream CSI tutorial. kubectl config use-context vks-lifecycle-01 kubectl get volumesnapshotclass error: the server doesn't have a resource type "volumesnapshotclass" # Context 2. The Supervisor namespace, one command later. kubectl config use-context ns-platform-a kubectl get volumesnapshotclass NAME DRIVER DELETIONPOLICY AGE vsan-default csi.vsphere.vmware.com Delete 41d

That asymmetry is the objective. On a Supervisor, the pvCSI webhook and the external CSI snapshot webhook are installed for you, and a VolumeSnapshotClass exists from the moment a storage policy is bound to the vSphere Namespace. Inside a VKS cluster, none of it is there. Broadcom is explicit about it: both webhooks install automatically in Supervisor and must be deployed manually in VKS clusters. A candidate who has only ever snapshotted a Supervisor persistent volume will read the error above as a broken cluster, which is the single most expensive misread in this objective.

Trace it back to the Supervisor, as always in this series. Snapshot capability in a VKS cluster is a proxied capability. Your cluster does not talk to vSAN. It talks to pvCSI, which talks to the Supervisor, which talks to the Cloud Native Storage control plane in vCenter. Everything the cluster is allowed to do with storage was decided when somebody bound a storage policy to ns-platform-a. If that binding is wrong, no amount of package installation inside the cluster will produce a working snapshot, and the error you get will be about datastores rather than permissions.

flowchart TD
  A[Supervisor namespace] --> B[pvCSI webhook present by default]
  A --> C[CSI snapshot webhook present by default]
  A --> D[VolumeSnapshotClass exists on day one]
  E[VKS workload cluster] --> F[No snapshot CRDs until you act]
  F --> G[Install cert manager package]
  G --> H[Install external csi snapshot webhook]
  H --> I[Install vsphere pv csi webhook]
  I --> J[VolumeSnapshotClass appears]
  J --> K[VolumeSnapshot of a block PVC]
  K --> L[New PVC created through dataSource]
Two starting positions. One is ready, one needs three package installs before a snapshot object can exist.

Webhook packages and a snapshot class you must not create

Prerequisites for this section are short and each one has a check that proves it. You need a VKr of v1.26.5 or later, because that is the floor Broadcom sets for CSI snapshot support on vSphere 8.0 Update 2 and later. You need a standard package repository of version v2023.9.19 or later reachable from the cluster, which Part 23 put into tkg-system. You need cert-manager installed, because both webhooks want serving certificates. Prove the first with a version read, prove the second with a package list, and only then install anything.

kubectl config use-context vks-lifecycle-01 # Preflight 1. VKr floor for CSI snapshots is v1.26.5. kubectl get nodes -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion NAME VERSION vks-lifecycle-01-node-pool-1-abc12-x9k4z v1.32.0+vmware.1 # Preflight 2. Repository from Part 23 is reconciled and publishing packages. vcf package available list -n tkg-system NAME DISPLAY-NAME cert-manager.tanzu.vmware.com cert-manager external-csi-snapshot-webhook.tanzu.vmware.com external-csi-snapshot-webhook vsphere-pv-csi-webhook.tanzu.vmware.com vsphere-pv-csi-webhook prometheus.tanzu.vmware.com prometheus # Step 1. cert-manager first, or both webhooks sit at ReconcileFailed. kubectl create namespace vks-packages vcf package install cert-manager –package cert-manager.tanzu.vmware.com –version 1.14.5+vmware.1-tkg.1 –namespace vks-packages # Step 2 and 3. Both webhooks land in kube-system. vcf package install external-csi-snapshot-webhook –package external-csi-snapshot-webhook.tanzu.vmware.com –version 6.1.0+vmware.1-tkg.1 –namespace kube-system vcf package install vsphere-pv-csi-webhook –package vsphere-pv-csi-webhook.tanzu.vmware.com –version 3.3.1+vmware.1-tkg.1 –namespace kube-system # Verification. What green looks like. kubectl get pods -n kube-system -l app=external-csi-snapshot-webhook NAME READY STATUS RESTARTS AGE external-csi-snapshot-webhook-6c9f7d4b58-4wq7k 1/1 Running 0 2m11s kubectl get volumesnapshotclass NAME DRIVER DELETIONPOLICY AGE vsan-default csi.vsphere.vmware.com Delete 2m

Notice what did not happen in that block. Nobody wrote a VolumeSnapshotClass. Every upstream Kubernetes CSI walkthrough on the internet opens by applying one, usually with a Retain deletion policy so that snapshots survive a careless delete, and that advice is wrong on VKS in a way that will cost you an item. Broadcom states it plainly: do not create volume snapshot classes, use only a pre-existing class, and classes with a Retain deletion policy are not supported. Your class arrives with the webhook, its policy is Delete, and that is the end of the discussion.

Production gotcha: Delete as a deletion policy means removing a VolumeSnapshot removes the underlying VolumeSnapshotContent and the storage behind it. There is no safety net object left in the cluster afterwards. If you want a copy that outlives a snapshot object, the answer is not a deletion policy, it is a real backup with data leaving the array, which is why Velero and an external object store get their own Part later in this series.

Dynamic snapshot of a PostgreSQL claim

Lab position: the pg-orders StatefulSet from Part 20 is running in namespace orders on vks-lifecycle-01, with a 100Gi ReadWriteOnce claim carved from the vsan-default policy. A dynamically provisioned snapshot is the common case and it is four lines of YAML. Quiesce your database first if you care about the restore being consistent, because a CSI snapshot is crash consistent and nothing more.

# volumesnapshot-pg.yaml apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: pg-orders-pre-upgrade namespace: orders spec: volumeSnapshotClassName: vsan-default source: persistentVolumeClaimName: data-pg-orders-0 — kubectl -n orders exec pg-orders-0 — psql -c "CHECKPOINT" kubectl apply -f volumesnapshot-pg.yaml volumesnapshot.snapshot.storage.k8s.io/pg-orders-pre-upgrade created # Verification. READYTOUSE true is the only signal worth trusting. kubectl get volumesnapshot -n orders NAME READYTOUSE SOURCEPVC RESTORESIZE SNAPSHOTCONTENT AGE pg-orders-pre-upgrade true data-pg-orders-0 100Gi snapcontent-6b3a1f0e-6d0e-4c4f-9a11-b7e0c4d21a55 9s

Nine seconds for a 100Gi volume, because nothing is copied. A snapshot on vSAN is metadata plus a redirect on write chain, and that is exactly why it is cheap to take and expensive to keep. Here are the four timings I measured on this estate, taken from a single loop of snapshot, restore, attach and clean up, so you can budget a maintenance window honestly instead of promising a minute and burning ten.

Snapshot and restore cycle, measured Seconds per stage, 100 GiB block PVC, vSAN OSA, VKS 3.3.1, VKr v1.32.0 Snapshot readyToUse 9 s Restore PVC bound 41 s Pod attach and DB ready 78 s Snapshot delete 6 s Total wall clock for one loop: 134 seconds. Taking the snapshot is the cheap part.

Two constraints govern how many of these you keep. Broadcom recommends two to three snapshots per virtual disk for performance, and caps vSAN ESA at 32 snapshots per volume. Read those numbers correctly. Thirty two is a ceiling that protects the platform, not a retention target, and storage quota monitoring does not account for snapshots at all, so a namespace can quietly consume capacity that no quota report will show you.

Restore paths and a deletion order that bites

Restore is where most people carry a wrong mental model in from the vSphere world. In vSphere you revert a virtual machine to a snapshot and the machine is as it was. Kubernetes has no equivalent. Upstream is unambiguous that the generally available snapshot implementation does not support reverting an existing PVC to an earlier state; you provision a new volume from the snapshot and you point your workload at it. That means a restore in a VKS cluster is always a new claim, a scale down, and a switch, never a single revert command.

# pvc-restore.yaml. Same size, same storage class, same datastore. apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pg-orders-restore namespace: orders spec: storageClassName: vsan-default dataSource: name: pg-orders-pre-upgrade kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io accessModes: – ReadWriteOnce resources: requests: storage: 100Gi — kubectl apply -f pvc-restore.yaml kubectl get pvc -n orders pg-orders-restore NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pg-orders-restore Bound pvc-9f2c7a41-1d55-4b0e-9f3c-2a7d8e6c0b19 100Gi RWO vsan-default 41s

Now the failure I promised, and it is the one Broadcom documents because it catches everybody. Somebody restores into vsan-highperf instead of vsan-default, reasoning that a recovery copy deserves the faster policy. Both policies are bound to ns-platform-a, both work for new claims, and the restore still fails, because a claim created from a snapshot must land on the same datastore as the source.

kubectl describe pvc pg-orders-restore -n orders … Events: Type Reason Message Warning ProvisioningFailed failed to provision volume with StorageClass vsan-highperf: rpc error: code = Internal desc = failed to create volume. Error: failed to get the compatible datastore for create volume from snapshot pg-orders-pre-upgrade with error: failed to find datastore with URL ds:///vmfs/volumes/vsan:52a1c6f0e4b74d19/ from the input datastore list # Second real failure. Expansion of a volume that still owns a snapshot. kubectl patch pvc data-pg-orders-0 -n orders –type merge -p ‘{"spec":{"resources":{"requests":{"storage":"150Gi"}}}}’ Error from server: admission webhook validation.pvcsi.vmware.com denied the request: volume expansion is not supported for a volume with associated snapshots # Rollback and fallback. Order matters, snapshots before claims. kubectl delete volumesnapshot pg-orders-pre-upgrade -n orders kubectl patch pvc data-pg-orders-0 -n orders –type merge -p ‘{"spec":{"resources":{"requests":{"storage":"150Gi"}}}}’ persistentvolumeclaim/data-pg-orders-0 patched

Backing out of a bad restore is simply deleting the new claim, since the source volume was never touched. Backing out of a stuck source volume is different and it has a strict order: every snapshot referencing that volume must go first, then expansion or deletion succeeds. A PVC sitting in Terminating forever, on a cluster where nothing else is wrong, is almost always a forgotten VolumeSnapshot in the same namespace.

Pre-provisioned snapshots are worth knowing about even though you will reach for them rarely. When a snapshot of the same block volume already exists on the Supervisor, you can surface it inside the VKS cluster by creating a VolumeSnapshotContent that references it and a VolumeSnapshot that binds to that content. That is the mechanism backup vendors use, and it is why third party integrations can present Supervisor level snapshots to cluster users without duplicating storage. Three ways of protecting the same volume, and they are not interchangeable.

MechanismWhat it gives youReach for it when
Dynamic VolumeSnapshot in the clusterCrash consistent point in time copy on the same datastore, seconds to takeImmediately before a risky schema change, an app upgrade or a data migration
Pre-provisioned VolumeSnapshot bound to Supervisor contentVisibility inside the cluster of a snapshot taken above itA third party backup product owns the schedule and you need cluster level restore
Velero with an external object storeKubernetes objects plus volume data outside the array, portable across clustersRetention beyond hours, cluster loss, or any requirement with the word recovery in it

Snapshot failure to remediation lookup

This table is the artifact from this Part worth keeping. Seven error strings, seven causes, seven fixes. Six of the seven are things the cluster tells you clearly if you read the event rather than the pod log, and every one of them has shown up in a real environment I have been called into.

Symptom or error lineCauseFix
server does not have a resource type volumesnapshotclass, inside the clusterSnapshot CRDs and webhooks were never installed in the VKS clusterInstall cert-manager, external-csi-snapshot-webhook and vsphere-pv-csi-webhook from tkg-system
VolumeSnapshot stuck with readyToUse false, event mentions a file volumeSource claim is a vSphere file volume, typically ReadWriteManyOnly block volumes can be snapshotted; move the data to a ReadWriteOnce block claim
failed to find datastore with URL from the input datastore listRestore claim uses a storage class or topology resolving to a different datastoreRestore with the storage class of the source claim and matching topology requirements
volume expansion is not supported for a volume with associated snapshotsOne or more snapshots still reference the source volumeDelete every snapshot of that volume, then resize
PVC sits in Terminating and never clearsSame root cause, a forgotten VolumeSnapshot in the namespaceList volumesnapshots in that namespace and delete them before the claim
Restore claim Pending, size mismatch reportedRequested storage does not equal the RESTORESIZE of the snapshotMatch the request to the snapshot restore size exactly, then expand afterwards if needed
Custom VolumeSnapshotClass with Retain behaves unpredictablyAuthoring your own class is unsupported and Retain is not a supported policyDelete the custom class and use the pre-existing class with its Delete policy

Exam focus for objective 4.9

EXAM FOCUS, objective 4.9: What this objective expects you to be able to do is enable snapshot capability on a cluster that does not have it, take and verify a snapshot of the right kind of volume, create a new claim from that snapshot, and know the two operations a snapshot blocks. Expect build list items ordering the package installs, point and click or hot area items on a VolumeSnapshot manifest, and scenario multiple choice where an admin cannot expand or delete a volume. Trap that catches experienced admins: bringing the vSphere snapshot mental model with you and answering revert. Kubernetes cannot revert a claim, only provision a new one from a snapshot, so any option phrased as restoring the original PVC in place is wrong. Second trap, sharper: assuming snapshots work in a VKS cluster because they worked on the Supervisor. Those are two different sets of installed components and the Supervisor is the one that comes ready.
Objective checkpoint:

1. A developer reports that kubectl get volumesnapshotclass returns nothing inside a freshly provisioned VKS cluster, while the same command in the vSphere Namespace lists a class. What is the correct first action? Answer: install the CSI snapshot webhook and pvCSI webhook packages, with cert-manager, into the cluster. Snapshot components are deployed automatically only on the Supervisor.

2. An operator must grow a 100Gi claim to 150Gi. Expansion is denied although the storage class allows volume expansion and free capacity exists. Which condition explains it, and what must happen first? Answer: snapshots exist on that volume, and every one of them must be deleted before the resize. A volume with associated snapshots can be neither expanded nor deleted.

3. A restore claim built from a valid snapshot stays Pending with an error about a compatible datastore. Which single property of the claim is most likely wrong? Answer: its storage class, which resolves to a datastore other than the one holding the source volume. A claim provisioned from a snapshot must land on the source datastore, and topology requirements must agree too.

Snapshot practice I would standardise on

War story, and it ran for three weeks before anybody connected the dots. A platform team wrote a tidy little CronJob that snapshotted every database claim nightly and kept fourteen days of them. On vSAN OSA that meant fourteen snapshots per virtual disk against a documented recommendation of two to three. Write latency on their busiest PostgreSQL volume drifted from about 2 ms to 31 ms over those three weeks, slowly enough that everyone blamed the application. Then a capacity request came in, the volume needed to go from 200Gi to 400Gi, and the expansion was denied. That denial was the first hard signal anyone had. Deleting the backlog of snapshots took eleven minutes and brought write latency back under 3 ms the same evening. Three weeks of degraded database performance, caused entirely by a retention number somebody picked because it felt safe.

Verdict for this estate. Treat a VolumeSnapshot as a fifteen minute undo button and nothing longer. Take one immediately before a change, name it after the change rather than the date so its purpose is obvious, and delete it as part of the same change ticket. Pick two as your standing limit per virtual disk and enforce it, because three is the top of Broadcom guidance and fourteen is how you get the story above. Avoid the pattern of a scheduled snapshot CronJob entirely; it looks like backup, it is not backup, and it degrades exactly the volumes you care most about. For anything with a retention requirement measured in days, use Velero writing to object storage, which this series covers in Part 28. Snapshots and backups solve different problems and the exam expects you to keep them apart.

A clean result looks like this. Both webhook packages reconciled and their pods Running in kube-system. One VolumeSnapshotClass listed inside the cluster, driver csi.vsphere.vmware.com, deletion policy Delete, and none of it authored by you. A test VolumeSnapshot showing READYTOUSE true with a RESTORESIZE matching the source claim. A restore claim in Bound state built from that snapshot on the same storage class. A source volume that expands cleanly once the test snapshot is removed. If all five hold, objective 4.9 is in your hands rather than in your notes.

Tonight, in your own lab, do this. Take a snapshot of any block claim, then try to expand that claim and read the denial word for word. Delete the snapshot and run the same patch again. That thirty second loop is the whole operational half of this objective, and it is the fact most candidates learn during an outage instead. Component mechanics that this Part deliberately does not repeat live in the VKS series, and the full study path is indexed on the VCAP-VKS exam guide pillar. Part 25 moves up a layer, to upgrading the Supervisor Service itself.

VCAP-VKS Exam Series · Part 24 of 34
« Previous: Part 23  |  Guide  |  Next: Part 25 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure

Subscribe now to keep reading and get access to the full archive.

Continue reading