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
IOPS
andbandwidth
, 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 withallowedTopologies
. ThevolumeBindingMode: WaitForFirstConsumer
delays volume binding until the Kubernetes scheduler selects a suitable node that matches theallowedTopologies
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> -
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.
-
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 totrue
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-accessSave this YAML in a file
pvc.yaml
. - (Optional)
-
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.
-
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 -
(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.
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
Secret
for 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-key
as 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_NAMESPACE
environment variable in theStorageCluster
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 thesecure
parameter totrue
in theStorageClass
specification. - To encrypt a specific PVC, add the annotation
px/secure: "true"
in the PVC specification.