As organizations are adopting Kubernetes at scale, simplicity has become one of the key design principles. Users want to do more with their limited time and resources. This is where the NetApp® ASA r2 systems help users: by simplifying their storage footprint for Kubernetes applications.
NetApp Trident™ software, our Container Storage Interface (CSI)–compliant storage orchestrator, already supports these systems using the iSCSI and NVMe/TCP protocol. With Trident 25.10, support has been extended for FCP Protocol. This support can provide further scalability and performance benefits of FCP with ASA r2 systems.
In this article, we’ll explore the cutting-edge features of the ASA r2 systems, demonstrate how to seamlessly integrate them with your Kubernetes workloads, and explore how to use them in Trident with FCP protocol. So, let's dive in.
Introducing the ASA r2 systems
Before we begin, let’s look at what ASA r2 systems are and, at a high level, what they offer. The NetApp ASA r2 systems, which include the NetApp ASA A1K, ASA A90, ASA A70, ASA A50, ASA A30, and ASA A20 models, offer a unified hardware and software solution tailored to the specific needs of SAN-only customers. Built on the new NetApp ONTAP® design center architecture, these systems introduce a revolutionary approach to storage provisioning, which makes them an ideal choice for modern Kubernetes workloads.
One of the key differentiators of the ASA r2 systems is their disaggregated architecture. Unlike traditional systems, they don’t expose the concept of aggregates to the user. Instead, these systems treat LUN (logical unit number) as a first-class citizen, eliminating the need for wrapping LUNs inside volumes. This innovative design enables a simplified and streamlined experience for managing block storage.
NetApp Trident and CSI integration
To enable integration with ASA r2 systems, NetApp Trident™ software, NetApp's Container Storage Interface (CSI)–compliant storage orchestrator, now supports provisioning block storage using the FCP protocol starting with the 25.10 release. The best part is that if you’re an existing Trident customer, you can seamlessly transition to using ASA r2 systems with minimal changes. All you need to do is provide the right credentials in the Trident backend, and everything else is dynamically determined
Prerequisites
- Netapp Trident 25.10 or latest.
Configure zoning on the FC switch using WWPNs of the Host and target.
Refer to the respecive switch vendor documentation for information.
Refer to the following ONTAP documentation for details:
Provisioning Steps:
Whether or not you’re a new Trident user, the process of provisioning storage with Trident is straightforward. Here are the simple steps.
Step 1: Create a Trident backend.
Start by creating a Trident backend with the storage driver ontap-san. You can do this either by configuring the TridentBackendConfig (TBC) custom resource definition using the Kubernetes-native approach or by using a custom JSON file with tridentctl, a command-line utility for managing Trident. You can either use a cluster management IP with administrator credentials or specify a specific storage virtual machine (SVM) with its management IP and credentials. For more information, refer to ONTAP SAN driver details in the Trident documentation. # Kubernetes secret required for creating Trident backend from TBC
[core@cp1 trident-installer]$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: asa-r2-fcp-secret
type: Opaque
stringData:
username: <username>
password: <password>
[core@cp1 trident-installer]$ kubectl create -f secret.yaml -n trident
secret/asa-r2-fcp-secret created
[core@cp1 trident-installer]$ kubectl get secret asa-r2-fcp-secret -n trident
NAME TYPE DATA AGE
asa-r2-fcp-secret Opaque 2 18s
# Kubernetes CR TridentBackendConfig (TBC)
[core@cp1 trident-installer]$ cat tbc.yaml
apiVersion: trident.netapp.io/v1
kind: TridentBackendConfig
metadata:
name: asa-r2-fcp-backend-tbc
spec:
version: 1
backendName: asa-r2-fcp-backend
storageDriverName: ontap-san
managementLIF: 1.2.3.4
svm: svm0
sanType: fcp
credentials:
name: asa-r2-fcp-secret
# Or, Trident backend json
[core@cp1 trident-installer]$ cat backend.json
{
"version": 1,
"storageDriverName": "ontap-san",
"managementLIF": "1.2.3.4",
"backendName": "asa-r2-fcp-backend"
"svm": "svm0",
"username": "<username>",
"password": "<password>",
"sanType": "fcp"
}- Step 2: Add the backend.
Once the backend is configured, you can add it to Trident using either kubectl or tridentctl. These tools provide a convenient way to add the newly configured backend to Trident and make it available for use.
# Create Trident Backend via kubectl
[core@cp1 trident-installer]$ kubectl create -f tbc.yaml -n trident
tridentbackendconfig.trident.netapp.io/asa-r2-fcp-backend-tbc created
[core@cp1 trident-installer]$ kubectl get tbc asa-r2-fcp-backend-tbc -n trident
NAME BACKEND NAME BACKEND UUID PHASE STATUS
asa-r2-fcp-backend-tbc asa-r2-fcp-backend 36f3227c-bdbb-4052-94f2-79123a004990 Bound Success
[core@cp1 trident-installer]$ ./tridentctl -n trident get b
+--------------------+----------------+--------------------------------------+--------+------------+---------+
| NAME | STORAGE DRIVER | UUID | STATE | USER-STATE | VOLUMES |
+--------------------+----------------+--------------------------------------+--------+------------+---------+
| asa-r2-fcp-backend | ontap-san | 36f3227c-bdbb-4052-94f2-79123a004990 | online | normal | 0 |
+--------------------+----------------+--------------------------------------+--------+------------+---------+
# Or, create Trident Backend via tridentctl
[core@cp1 trident-installer]$ tridentctl create b -f backend.json -n trident
+--------------------+----------------+--------------------------------------+--------+------------+---------+
| NAME | STORAGE DRIVER | UUID | STATE | USER-STATE | VOLUMES |
+--------------------+----------------+--------------------------------------+--------+------------+---------+
| asa-r2-fcp-backend | ontap-san | 82141337e-e35c-6dex-2017-0h2282614f7 | online | normal | 0|
+--------------------+----------------+--------------------------------------+--------+------------+---------+​
- Step 3: Define a storage class.
Create a storage class that corresponds to the type of storage driver you require. This step allows you to define the characteristics of the storage you want to dynamically provision.
[core@cp1 trident-installer]$ cat sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: asa-r2-fcp-sc
parameters:
backendType: ontap-san
storagePools: "asa-r2-fcp-backend:.*"
provisioner: csi.trident.netapp.io
[core@cp1 trident-installer]$ kubectl create -f sc.yaml
storageclass.storage.k8s.io/asa-r2-fcp-sc created
[core@cp1 trident-installer]$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
asa-r2-fcp-sc csi.trident.netapp.io Delete Immediate false 7s
Now that everything is ready for dynamic provisioning of storage on the ASA r2 system, let's see an example of how to use it.
- Step 4: Create a PVC.
Define a PersistentVolumeClaim (PVC) that specifies the amount of storage you need and references the appropriate storage class. This step ensures that your Kubernetes application has access to the required block storage.
[core@cp1 trident-installer]$ cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: asa-r2-fcp-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: asa-r2-fcp-sc
[core@cp1 trident-installer]$ kubectl create -f pvc.yaml
persistentvolumeclaim/asa-r2-fcp-pvc created​ - Step 5: Confirm PVC binding.
After the PVC is created, verify that it’s successfully bound to a persistent volume (PV). This confirmation ensures that the block storage is ready for use by your applications. [core@cp1 trident-installer]$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
asa-r2-fcp-pvc Bound pvc-0794ae01-b0ae-4135-801e-2417437e9d7f 1Gi RWO asa-r2-fcp-sc <unset> 14s​
Step 6: Use the PVC.
Congratulations! You’re now ready to use the PVC in any pod of your choice. Mount the PVC in your pod's specification, and your application will have seamless access to the high-performance block storage provided by the ASA r2 systems using FCP protocol.
[core@cp1 trident-installer]$ cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: asa-r2-fcp-pod
spec:
containers:
- image: nginx:alpine
name: nginx
volumeMounts:
- mountPath: mnt/pvc
name: local-storage
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
volumes:
- name: local-storage
persistentVolumeClaim:
claimName: asa-r2-fcp-pvc
[core@cp1 trident-installer]$ kubectl create -f pod.yaml
pod/asa-r2-fcp-pod created
[core@cp1 trident-installer]$ kubectl get po
NAME READY STATUS RESTARTS AGE
asa-r2-fcp-pod 1/1 Running 0 8s
[core@cp1 trident-installer]$ kubectl exec -it asa-r2-fcp-pod -- /bin/ash -c "mount | fgrep mnt/pvc"
/dev/mapper/3600a09803831504c315d58684978384c on /mnt/pvc type ext4 (rw,seclabel,relatime,stripe=16)​</code></span></li></ul><h2 id="ASAr2FCPBlog-Troubleshootingmadeeasy">Troubleshooting made easy</h2><p><span>If you encounter any issues, we've got you covered with some handy commands for troubleshooting. Use </span>kubectl describe<span> on the problematic resource to gather detailed information. For more insights into the system's behavior, you can check the Trident logs by using </span>kubectl<span> or </span>tridentctl<span>.<br></span></p><pre class="lia-code-sample language-markup"><code>[core@cp1 trident-installer]$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
asa-r2-fcp-pvc Bound pvc-0794ae01-b0ae-4135-801e-2417437e9d7f 1Gi RWO asa-r2-fcp-sc <unset> 2m55s
[core@cp1 trident-installer]$ kubectl describe pvc asa-r2-fcp-pvc
Name: asa-r2-fcp-pvc
Namespace: default
StorageClass: asa-r2-fcp-sc
Status: Bound
Volume: pvc-0794ae01-b0ae-4135-801e-2417437e9d7f
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: csi.trident.netapp.io
volume.kubernetes.io/storage-provisioner: csi.trident.netapp.io
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: asa-r2-fcp-pod
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Provisioning 3m11s csi.trident.netapp.io_trident-controller-84d7f798fc-kv8xc_9c6963aa-60f5-43a4-b25c-b8cca37b6171 External provisioner is provisioning volume for claim "default/asa-r2-fcp-pvc"
Normal ExternalProvisioning 3m11s persistentvolume-controller Waiting for a volume to be created either by the external provisioner 'csi.trident.netapp.io' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.
Normal ProvisioningSuccess 3m6s csi.trident.netapp.io provisioned a volume
Normal ProvisioningSucceeded 3m6s csi.trident.netapp.io_trident-controller-84d7f798fc-kv8xc_9c6963aa-60f5-43a4-b25c-b8cca37b6171 Successfully provisioned volume pvc-0794ae01-b0ae-4135-801e-2417437e9d7f
[core@cp1 trident-installer]$
#For more troubleshooting check controller logs using: kubectl logs <trident-controller> -n trident
ConclusionWith the power of NetApp ASA r2 systems and integration provided by NetApp Trident, provisioning high-performance block storage for your Kubernetes applications has never been easier. Notably, ASA r2’s support for the FCP protocol leveraged by Trident enables you to deliver low-latency, scalable storage to your Kubernetes workloads with exceptional efficiency and flexibility. We hope this article has equipped you with the knowledge and confidence to configure your Kubernetes workloads on ASA r2 systems, taking advantage of FCP support. Happy configuring, and may your Kubernetes journey be smooth and successful.