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:
-
Create a new StorageClass to add parameters such as
IOPSandbandwidth, 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
trueto 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: WaitForFirstConsumerparameter along withallowedTopologies. ThevolumeBindingMode: WaitForFirstConsumerdelays volume binding until the Kubernetes scheduler selects a suitable node that matches theallowedTopologieslabels.
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> -
Apply this YAML to your cluster:
kubectl apply -f sc.yamlstorageclass.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.
-
To create a PVC, define the specifications and reference the StorageClass you previously created by specifying its name in the
spec.storageClassNamefield.- (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 totrueto 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-accessSave this YAML in a file
pvc.yaml. - (Optional)
-
Apply this YAML to your cluster:
kubectl apply -f pvc.yamlpersistentvolumeclaim/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.
-
Create a Pod and specify the PVC name in the
persistentVolumeClaim.claimNamefield. 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 -
(Optional) To control pod scheduling based on node labels, add the
nodeAffinityfield 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.
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:
-
Create a Kubernetes
Secretfor the encryption key:kubectl -n <portworx> create secret generic px-vol-encryption \
--from-literal=cluster-wide-secret-key=<value> -
Configure PX-CSI to use
cluster-wide-secret-keyas the default encryption key for all volumes:-
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[]') -
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}') -
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}"
-
- 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_NAMESPACEenvironment variable in theStorageClustermanifest to specify the correct namespace. - If you modify a Kubernetes
Secretafter creating a cluster-wide encryption key, use the--overwriteflag 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 thesecureparameter totruein theStorageClassspecification. - To encrypt a specific PVC, add the annotation
px/secure: "true"in the PVC specification.