Skip to main content

Rob Pankow Rob Pankow

Platform Engineering After the VMware Exit: Self-Service Storage, Multi-Tenancy, and GitOps

Aug 4, 2026  |  7 min read

Platform Engineering After the VMware Exit: Self-Service Storage, Multi-Tenancy, and GitOps

Most VMware-exit content stops at the migration: convert the VMs, land them on KubeVirt or Red Hat® OpenShift® Virtualization, confirm they boot. That gets workloads across the line, but it leaves the platform team’s actual job undone. On vSphere, that job was self-service with guardrails: a developer requests a VM, a storage policy enforces the replication and performance tier, DRS keeps it balanced, and a template makes provisioning repeatable. None of that disappears when the hypervisor changes. It has to be rebuilt on Kubernetes, and the rebuild is a storage and platform-engineering problem first, not a virtualization one.

What the vSphere Admin Actually Owned

A VMware platform team’s day-to-day was rarely about the hypervisor itself. It was policy administration: assigning a vSAN storage policy (replication factor, stripe width, failure-domain awareness) to a VM at deploy time, then letting vCenter enforce it. DRS handled placement and rebalancing. Templates and content libraries made “give team X a database VM with the right tier of storage” a five-minute, self-service request instead of a ticket to infrastructure.

That model maps cleanly onto Kubernetes, term for term, but only if someone builds the mapping deliberately:

VMware conceptKubernetes-native equivalentWhat it enforces
vSAN storage policyStorageClassReplication factor, performance tier, provisioner behavior
DRS placement/limitsNamespace ResourceQuota + schedulerPer-team capacity ceilings, node placement rules
VM template / content libraryHelm chart or Kustomize base + PVC templateRepeatable, self-service provisioning
vCenter click-ops changeGit-committed manifest (GitOps)Auditable, reviewed, rollback-capable changes

A platform team that skips this mapping does not remove the policy layer. It just loses it, and every team ends up hand-rolling its own StorageClass and quota conventions, which is how a Kubernetes cluster ends up with fifteen near-identical StorageClasses six months after a VMware exit.

StorageClasses as the Storage-Policy Layer

The direct replacement for a vSAN storage policy is a StorageClass, and the direct replacement for “assign a policy per VM” is “define one StorageClass per tier, per team, or per both.” A platform team coming from vSphere should design this the same way they designed storage policies: a small number of named tiers (for example fast-nvme, standard, archive) with parameters that map to actual replication and performance behavior, not one StorageClass per application.

On a CSI driver like simplyblock, that StorageClass parameter set controls things a vSAN policy also controlled: how many copies of the data exist, what NVMe pool backs the volume, and what QoS ceiling applies. Simplyblock’s NVMe/TCP fabric means multiple StorageClasses can point at the same underlying pool with different QoS parameters, so “fast” and “standard” tiers do not require separate physical hardware the way a vSAN all-flash vs. hybrid disk group split did. A platform team publishing three or four well-defined StorageClasses, with clear names and documented guarantees, gives application teams the same self-service experience they had picking a storage policy from a dropdown, without a ticket back to platform for every new volume.

How VMware storage policy and DRS concepts map onto Kubernetes StorageClasses, quotas, and GitOps

Multi-Tenancy: Quotas Where DRS Used to Be

DRS kept a shared vSphere cluster fair: no single VM or team could starve the others of CPU, memory, or (with Storage DRS) datastore capacity. The Kubernetes-native equivalent is a namespace-scoped ResourceQuota covering PVC count and total requested capacity per StorageClass, paired with per-tenant isolation on the storage backend itself so one namespace’s I/O burst cannot degrade another’s latency, the same concern this blog covered in more depth in Kubernetes multi-tenant storage isolation.

The gap most VMware-exit migrations hit here is not the quota object, which is a native Kubernetes primitive. It is that the underlying storage often cannot honor per-tenant QoS the way vSAN’s storage policies could, because generic CSI drivers on top of local disks or a shared SAN LUN do not carry per-volume performance isolation the way a policy-driven vSAN datastore did. Simplyblock’s NVMe/TCP storage enforces QoS at the volume level, so a namespace’s ResourceQuota is backed by actual performance isolation on the pool underneath it, not just a capacity accounting number that quietly allows noisy-neighbor I/O contention across tenants.

GitOps: Replacing vCenter Click-Ops With Reviewed Manifests

The last piece platform teams tend to underweight is the workflow itself. A vCenter change, assigning a new storage policy, resizing a datastore, adjusting DRS rules, happened through a UI, logged in vCenter’s own audit trail but rarely reviewed before it took effect. On Kubernetes, the equivalent objects (StorageClass, VolumeSnapshotClass, ResourceQuota, PVC templates) are just YAML, which means they can go through the same pull-request review, CI validation, and Argo CD or Flux-driven reconciliation as application code.

This is where “platform engineering” as a discipline actually shows up: not a new tool, but treating storage policy the way the rest of the platform treats configuration, versioned, reviewed, and reconciled automatically rather than clicked into place by whoever is on call. A storage policy change reviewed in a pull request and rolled out by a GitOps controller is strictly safer than the same change made by hand in vCenter at 2am, and it gives the platform team an audit trail that satisfies compliance requirements a screenshot of a vCenter settings page never did.

Rebuilding self-service storage after a VMware exit shouldn’t mean starting from zero. Talk to us about mapping your vSAN storage policies to StorageClasses and quotas before your next migration wave. Talk to a storage architect

Where This Fits With the Rest of the Migration

Platform engineering is the layer above the storage-ops mechanics already covered elsewhere on this blog: Day 2 storage operations after the VMware exit handles snapshot, DR, and observability once workloads are running, and why CSI alone isn’t enough for stateful Kubernetes covers the control-plane limitations that show up at scale. This post is about the layer platform teams build on top of both: the self-service, quota, and GitOps conventions that let application teams provision storage the way they did on vSphere, without reopening a platform ticket for every request. Get that layer right once, and every subsequent migration wave inherits it instead of reinventing it.

Questions and Answers

How do I map a vSAN storage policy to a Kubernetes StorageClass? Identify what the policy actually enforces (replication factor, failure-domain awareness, performance tier) and encode the same guarantees as StorageClass parameters on your CSI driver. Publish a small, named set of tiers (for example fast-nvme, standard) rather than a StorageClass per application, the same way most vSphere shops kept a handful of named policies rather than one per VM.

Can Kubernetes enforce per-tenant storage performance the way vSAN storage policies did? Only if the underlying CSI driver supports volume-level QoS. Generic drivers backed by local disks or a shared SAN LUN typically cannot isolate one tenant’s I/O burst from another’s. simplyblock enforces QoS at the volume level on its NVMe/TCP fabric, so a namespace ResourceQuota reflects real performance isolation, not just a capacity number.

Does GitOps work for storage policy changes, or only for application deployments? StorageClass, VolumeSnapshotClass, and ResourceQuota objects are ordinary Kubernetes YAML, so Argo CD or Flux can reconcile them the same way they reconcile application manifests. A storage policy change goes through a pull request and CI validation instead of a manual vCenter edit, which gives platform teams an audit trail and a rollback path they did not reliably have on vSphere.

Does this replace the Day 2 storage-ops work (snapshots, DR) covered elsewhere on this blog? No. Platform engineering, self-service provisioning, quotas, and GitOps, sits above the operational mechanics. See Day 2 storage operations after the VMware exit for the snapshot, DR, and observability layer once workloads are running.

Does simplyblock’s pricing model fit a platform team doing internal chargeback? Simplyblock licenses per usable TB provisioned per year, not per core or per node, which maps directly onto capacity-based chargeback: a team’s storage cost scales with the volumes it actually provisions, not with how many nodes happen to host its pods. That is a more predictable basis for internal billing than a per-core license that can shift with cluster resizing.

You may also like:

NVMe/TCP vs NVMe/RoCE for Kubernetes Storage: Choosing the Right Fabric
NVMe/TCP vs NVMe/RoCE for Kubernetes Storage: Choosing the Right Fabric

NVMe over Fabrics gives Kubernetes clusters low-latency block storage over the network. The transport you pick, TCP or RoCE, determines your latency floor, infrastructure cost, and operational complexity. Here is how to choose.

We Break Our Storage So You Never Have To
We Break Our Storage So You Never Have To

Simplyblock runs 100+ hours of automated chaos engineering before every release: real NVMe hardware, real FIO workloads, four failure types injected under live load. This is what we test, why it is necessary, and what it means for your infrastructure.

NVMe Storage Cost Optimization in 2026: Erasure Coding, Thin Provisioning, and Compute Efficiency
NVMe Storage Cost Optimization in 2026: Erasure Coding, Thin Provisioning, and Compute Efficiency

NVMe drives deliver the performance Kubernetes stateful workloads need, but triple replication and thick provisioning multiply their cost fast. Here is a practical breakdown of erasure coding economics, thin provisioning, and how sub-millisecond latency reduces compute waste.