Skip to main content
Version: 25.8

Dynamic Provisioning of FlashArray Block Volumes

Use PX-CSI to dynamically provision block volumes on FlashArray. This page walks you through creating a StorageClass, provisioning a PersistentVolumeClaim (PVC), mounting it to a pod, and optionally enabling encryption and topology-aware placement.

By default, PX-CSI enables automatic discard (TRIM/UNMAP) for all volumes except NVMe-based volumes. You can control the discard behavior by specifying the discard option in the mountOptions field of the StorageClass specification.

When PX-CSI is deployed, the following StorageClass objects are automatically created. You can use these directly or create custom StorageClass configurations:

kubectl get storageclass
NAME                        PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
px-fa-direct-access pxd.portworx.com Delete Immediate true 4d17h
px-fb-direct-access-nfsv3 pxd.portworx.com Delete Immediate true 4d17h
px-fb-direct-access-nfsv4 pxd.portworx.com Delete Immediate true 4d17h

(Optional) Create a custom StorageClass

Define a custom StorageClass that specifies the backend type, performance limits, and optional settings such as encryption and access control.

For FlashArray block volumes, backend type must be "pure_block". You can also configure parameters like IOPS and bandwidth.

Example StorageClass specification:

  1. Create a new StorageClass to add parameters such as IOPS and bandwidth, as shown below:

    • (Optional) max_bandwidth The bandwidth limit must range between 1 MB/s and 512 GB/s.
    • (Optional) max_iops: The IOPS limit must range between 100 and 100 million.
    • (Optional) secure: Set this to true to enable encryption on PVCs that reference this StorageClass. A cluster-wide secret key must be created for encryption. For more information, see Encrypt FADA volumes.
    • (Optional) allowedTopologies - Uses topology labels to select arrays with matching labels for volume placement.
    • volumeBindingMode: If you have enabled CSI topology, ensure you specify the volumeBindingMode: WaitForFirstConsumer parameter along with allowedTopologies. The volumeBindingMode: WaitForFirstConsumer delays volume binding until the Kubernetes scheduler selects a suitable node that matches the allowedTopologies labels.
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
    name: sc-fa-direct-access
    provisioner: pxd.portworx.com
    parameters:
    backend: "pure_block"
    #pure_fa_pod_name: "<fa-pod-name>" Use this parameter to specify the Pure FlashArray pod within the realm defined in pure.json when using the secure multi-tenancy feature of FlashArray.
    max_bandwidth: "10G"
    max_iops: "30000"
    #secure: "true" # Uncomment this line to encrypt all PVCs associated with this `StorageClass`
    # (Optional) Below lines are required only if you are using CSI topology
    volumeBindingMode: WaitForFirstConsumer
    allowedTopologies:
    - matchLabelExpressions:
    - key: topology.portworx.io/zone
    values:
    - <zone-1>
    - key: topology.portworx.io/region
    values:
    - <region-1>
  2. Apply this YAML to your cluster:

    kubectl apply -f sc.yaml
    storageclass.storage.k8s.io/sc-fa-direct-access created

Create a PVC

Once you’ve created a StorageClass, request storage by defining a PersistentVolumeClaim (PVC). The PVC references the StorageClass to dynamically provision a volume with the specified parameters.

  1. To create a PVC, define the specifications and reference the StorageClass you previously created by specifying its name in the spec.storageClassName field.

    • (Optional) metadata.annotations.px/secure:: If encryption is not enabled in the StorageClass and you want to enable it for a specific PVC, set this to true to enable encryption on a PVC. A cluster-wide secret key must be created for encryption. For more information, see Encrypt FADA volumes.

    Example PVC specification:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
    name: pure-claim-fa
    annotations:
    #px/secure: "true" # Uncomment this line to encrypt only this PVC.
    labels:
    app: nginx
    spec:
    accessModes:
    - ReadWriteOnce
    resources:
    requests:
    storage: 20Gi
    storageClassName: sc-fa-direct-access

    Save this YAML in a file pvc.yaml.

  2. Apply this YAML to your cluster:

    kubectl apply -f pvc.yaml 
    persistentvolumeclaim/pure-claim-fa created

Mount a PVC to a pod

To make the volume available to your workload, create a pod and attach the PVC using a volume mount. This section also shows how to use node affinity to control pod scheduling based on storage topology.

  1. Create a Pod and specify the PVC name in the persistentVolumeClaim.claimName field. Here is an example pod specification:

    kind: Pod
    apiVersion: v1
    metadata:
    name: nginx-pod
    labels:
    app: nginx
    spec:
    volumes:
    - name: pure-vol
    persistentVolumeClaim:
    claimName: pure-claim-fa
    containers:
    - name: nginx
    image: nginx
    volumeMounts:
    - name: pure-vol
    mountPath: /data
    ports:
    - containerPort: 80
  2. (Optional) To control pod scheduling based on node labels, add the nodeAffinity field to the Pod specification. For example:

    spec:
    affinity:
    nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchExpressions:
    - key: topology.portworx.io/zone
    operator: In
    values:
    - zone-0
    - key: topology.portworx.io/region
    operator: In
    values:
    - region-0

Verify pod status

After deploying the pod, check its status to confirm that the volume is bound and attached successfully.

watch kubectl get pods

Wait for the STATUS to show as Running. Once the pod is running, verify that it is connected to the volume.

(Optional) Encrypt FADA volumes

PX-CSI supports encryption for FADA volumes. To encrypt FADA volumes, create a cluster-wide encryption key and enable encryption in the StorageClass or PVC manifest.

note

Encryption is not supported for FADA raw block volumes.

Create a cluster-wide secret key for encryption

To ensure consistent and secure encryption of PersistentVolumeClaims (PVCs), use a cluster-wide encryption key. This guarantees that all encrypted PVCs in the cluster adhere to a uniform and secure encryption standard. Follow these steps to create the key:

  1. Create a Kubernetes Secret for the encryption key:

    kubectl -n <portworx> create secret generic px-vol-encryption \
    --from-literal=cluster-wide-secret-key=<value>
  2. Configure PX-CSI to use cluster-wide-secret-key as the default encryption key for all volumes:

    1. Read the name of the data key from the secret created in step 1:

      DATA_KEY=$(kubectl -n <portworx> get secret px-vol-encryption -o jsonpath='{.data}' | jq -r 'keys[]')
    2. Get the PX-CSI cluster name to build the required secret name:

      CLUSTER_NAME=$(kubectl get stc -n <portworx> -o jsonpath='{.items[0].metadata.name}')
    3. Create the PX-CSI secret in the Portworx namespace:

      kubectl -n <portworx> create secret generic ${CLUSTER_NAME}-px-secret \
      --from-literal=px_value="${DATA_KEY}"
note
  • PX-CSI checks for the cluster-wide encryption key in the Portworx namespace by default. If you create it in a different namespace, set the PX_SECRETS_NAMESPACE environment variable in the StorageCluster manifest to specify the correct namespace.
  • If you modify a Kubernetes Secret after creating a cluster-wide encryption key, use the --overwrite flag in the command above to update the key.

Enable encryption

After creating the cluster-wide secret key, follow one of the options below to encrypt FADA volumes:

  • To encrypt all PVCs associated with a StorageClass, enable encryption by setting the secure parameter to true in the StorageClass specification.
  • To encrypt a specific PVC, add the annotation px/secure: "true" in the PVC specification.