Persistent Volumes are provisioned on Local Datastores Instead of vSAN
search cancel

Persistent Volumes are provisioned on Local Datastores Instead of vSAN

book

Article ID: 429109

calendar_today

Updated On:

Products

Tanzu Kubernetes Runtime

Issue/Introduction

  • Persistent Volumes (PVs) created via the default StorageClass are unexpectedly provisioned on node-local datastores (e.g., local boot volumes or scratch disks) instead of the shared vSAN datastore.
  • The PVs may become inaccessible if the pod is rescheduled to a different node, as the local storage is not shared across the cluster.

Environment

2.x

Cause

  • The default StorageClass configuration is missing the storagePolicyName parameter.
  • The csi.vsphere.vmware.com provisioner relies on vSphere Storage Policy Based Management (SPBM) to determine where to place volumes.
  • If the storagePolicyName parameter is omitted from the StorageClass, the CSI driver does not enforce any specific placement rules.
  • Hence, vCenter may select any available datastore accessible to the host—including local, non-shared datastores—to satisfy the volume creation request

    Example of incorrect configuration:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: default
    provisioner: csi.vsphere.vmware.com
    # Missing parameters section defining the storage policy

Resolution

To ensure PVs are correctly provisioned on vSAN, define a StorageClass that explicitly references a vSphere Storage Policy compatible with your vSAN datastore.

1. Identify the Correct vSphere Storage Policy

  1. Log in to the vSphere Client.

  2. Navigate to Policies and Profiles > VM Storage Policies.

  3. Identify the policy used for your vSAN (e.g., "vSAN Default Storage Policy" or "Tanzu Storage Policy").

  4. Note the exact name (case-sensitive).

2. Create a New StorageClass Definition

Create a YAML file (e.g., vsan-storageclass.yaml) with the following content. Ensure you update the storagePolicyName to match the policy identified in Step 1.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: vsan-default
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: csi.vsphere.vmware.com
parameters:
  storagePolicyName: "vSAN Default Storage Policy"  # Update this name to match your environment
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer


3. Apply the New StorageClass

  1.  Remove default annotation from the old class:

    kubectl patch storageclass default -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

  2. Apply the new StorageClass:

    kubectl apply -f vsan-storageclass.yaml