Provision Azure NetApp Files NFS volumes for Azure Kubernetes Service
After you configure Azure NetApp Files for Azure Kubernetes Service, you can provision Azure NetApp Files volumes for Azure Kubernetes Service.
Azure NetApp Files supports volumes using NFS (NFSv3 or NFSv4.1), SMB, or dual-protocol (NFSv3 and SMB, or NFSv4.1 and SMB).
- This article describes details for provisioning NFS volumes statically or dynamically.
- For information about provisioning SMB volumes statically or dynamically, see Provision Azure NetApp Files SMB volumes for Azure Kubernetes Service.
- For information about provisioning dual-protocol volumes statically, see Provision Azure NetApp Files dual-protocol volumes for Azure Kubernetes Service
Statically configure for applications that use NFS volumes
This section describes how to create an NFS volume on Azure NetApp Files and expose the volume statically to Kubernetes. It also describes how to use the volume with a containerized application.
Create an NFS volume
Define variables for later usage. Replace myresourcegroup, mylocation, myaccountname, mypool1, premium, myfilepath, myvolsize, myvolname, vnetid, and anfSubnetID with an appropriate value from your account and environment. The filepath must be unique within all ANF accounts.
RESOURCE_GROUP="myresourcegroup" LOCATION="mylocation" ANF_ACCOUNT_NAME="myaccountname" POOL_NAME="mypool1" SERVICE_LEVEL="premium" # Valid values are Standard, Premium, and Ultra UNIQUE_FILE_PATH="myfilepath" VOLUME_SIZE_GIB="myvolsize" VOLUME_NAME="myvolname" VNET_ID="vnetId" SUBNET_ID="anfSubnetId"
Create a volume using the
az netappfiles volume create
command. For more information, see Create an NFS volume for Azure NetApp Files.az netappfiles volume create \ --resource-group $RESOURCE_GROUP \ --location $LOCATION \ --account-name $ANF_ACCOUNT_NAME \ --pool-name $POOL_NAME \ --name "$VOLUME_NAME" \ --service-level $SERVICE_LEVEL \ --vnet $VNET_ID \ --subnet $SUBNET_ID \ --usage-threshold $VOLUME_SIZE_GIB \ --file-path $UNIQUE_FILE_PATH \ --protocol-types NFSv3
Create the persistent volume
List the details of your volume using
az netappfiles volume show
command. Replace the variables with appropriate values from your Azure NetApp Files account and environment if not defined in a previous step.az netappfiles volume show \ --resource-group $RESOURCE_GROUP \ --account-name $ANF_ACCOUNT_NAME \ --pool-name $POOL_NAME \ --volume-name "$VOLUME_NAME -o JSON
The following output is an example of the above command executed with real values.
{ ... "creationToken": "myfilepath2", ... "mountTargets": [ { ... "ipAddress": "10.0.0.4", ... } ], ... }
Create a file named
pv-nfs.yaml
and copy in the following YAML. Make sure the server matches the output IP address from Step 1, and the path matches the output fromcreationToken
above. The capacity must also match the volume size from the step above.apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs spec: capacity: storage: 100Gi accessModes: - ReadWriteMany mountOptions: - vers=3 nfs: server: 10.0.0.4 path: /myfilepath2
Create the persistent volume using the
kubectl apply
command:kubectl apply -f pv-nfs.yaml
Verify the status of the persistent volume is Available by using the
kubectl describe
command:kubectl describe pv pv-nfs
Create a persistent volume claim
Create a file named
pvc-nfs.yaml
and copy in the following YAML. This manifest creates a PVC namedpvc-nfs
for 100Gi storage andReadWriteMany
access mode, matching the PV you created.apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs spec: accessModes: - ReadWriteMany storageClassName: "" resources: requests: storage: 100Gi
Create the persistent volume claim using the
kubectl apply
command:kubectl apply -f pvc-nfs.yaml
Verify the Status of the persistent volume claim is Bound by using the
kubectl describe
command:kubectl describe pvc pvc-nfs
Mount with a pod
Create a file named
nginx-nfs.yaml
and copy in the following YAML. This manifest defines anginx
pod that uses the persistent volume claim.kind: Pod apiVersion: v1 metadata: name: nginx-nfs spec: containers: - image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine name: nginx-nfs command: - "/bin/sh" - "-c" - while true; do echo $(date) >> /mnt/azure/outfile; sleep 1; done volumeMounts: - name: disk01 mountPath: /mnt/azure volumes: - name: disk01 persistentVolumeClaim: claimName: pvc-nfs
Create the pod using the
kubectl apply
command:kubectl apply -f nginx-nfs.yaml
Verify the pod is Running by using the
kubectl describe
command:kubectl describe pod nginx-nfs
Verify your volume has been mounted on the pod by using
kubectl exec
to connect to the pod, and then usedf -h
to check if the volume is mounted.kubectl exec -it nginx-nfs -- sh
/ # df -h Filesystem Size Used Avail Use% Mounted on ... 10.0.0.4:/myfilepath2 100T 384K 100T 1% /mnt/azure ...
Dynamically configure for applications that use NFS volumes
Astra Trident may be used to dynamically provision NFS or SMB files on Azure NetApp Files. Dynamically provisioned SMB volumes are only supported with windows worker nodes.
This section describes how to use Astra Trident to dynamically create an NFS volume on Azure NetApp Files and automatically mount it to a containerized application.
Install Astra Trident
To dynamically provision NFS volumes, you need to install Astra Trident. Astra Trident is NetApp's dynamic storage provisioner that is purpose-built for Kubernetes. Simplify the consumption of storage for Kubernetes applications using Astra Trident's industry-standard Container Storage Interface (CSI) driver. Astra Trident deploys on Kubernetes clusters as pods and provides dynamic storage orchestration services for your Kubernetes workloads.
Trident can be installed using the Trident operator (manually or using Helm) or tridentctl
. To learn more about these installation methods and how they work, see the Astra Trident Install Guide.
Install Astra Trident using Helm
Helm must be installed on your workstation to install Astra Trident using this method. For other methods of installing Astra Trident, see the Astra Trident Install Guide.
To install Astra Trident using Helm for a cluster with only Linux worker nodes, run the following commands:
helm repo add netapp-trident https://netapp.github.io/trident-helm-chart helm install trident netapp-trident/trident-operator --version 23.04.0 --create-namespace --namespace trident
The output of the command resembles the following example:
NAME: trident LAST DEPLOYED: Fri May 5 13:55:36 2023 NAMESPACE: trident STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Thank you for installing trident-operator, which will deploy and manage NetApp's Trident CSI storage provisioner for Kubernetes. Your release is named 'trident' and is installed into the 'trident' namespace. Please note that there must be only one instance of Trident (and trident-operator) in a Kubernetes cluster. To configure Trident to manage storage resources, you will need a copy of tridentctl, which is available in pre-packaged Trident releases. You may find all Trident releases and source code online at https://github.com/NetApp/trident. To learn more about the release, try: $ helm status trident $ helm get all trident
To confirm Astra Trident was installed successfully, run the following
kubectl describe
command:kubectl describe torc trident
The output of the command resembles the following example:
Name: trident Namespace: Labels: app.kubernetes.io/managed-by=Helm Annotations: meta.helm.sh/release-name: trident meta.helm.sh/release-namespace: trident API Version: trident.netapp.io/v1 Kind: TridentOrchestrator Metadata: ... Spec: IPv6: false Autosupport Image: docker.io/netapp/trident-autosupport:23.04 Autosupport Proxy: <nil> Disable Audit Log: true Enable Force Detach: false Http Request Timeout: 90s Image Pull Policy: IfNotPresent k8sTimeout: 0 Kubelet Dir: <nil> Log Format: text Log Layers: <nil> Log Workflows: <nil> Namespace: trident Probe Port: 17546 Silence Autosupport: false Trident Image: docker.io/netapp/trident:23.04.0 Windows: false Status: Current Installation Params: IPv6: false Autosupport Hostname: Autosupport Image: docker.io/netapp/trident-autosupport:23.04 Autosupport Proxy: Autosupport Serial Number: Debug: false Disable Audit Log: true Enable Force Detach: false Http Request Timeout: 90s Image Pull Policy: IfNotPresent Image Pull Secrets: Image Registry: k8sTimeout: 30 Kubelet Dir: /var/lib/kubelet Log Format: text Log Layers: Log Level: info Log Workflows: Probe Port: 17546 Silence Autosupport: false Trident Image: docker.io/netapp/trident:23.04.0 Message: Trident installed Namespace: trident Status: Installed Version: v23.04.0 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Installing 2m59s trident-operator.netapp.io Installing Trident Normal Installed 2m31s trident-operator.netapp.io Trident installed
Create a backend
To instruct Astra Trident about the Azure NetApp Files subscription and where it needs to create volumes, a backend is created. This step requires details about the account that was created in a previous step.
Create a file named
backend-secret.yaml
and copy in the following YAML. Change theClient ID
andclientSecret
to the correct values for your environment.apiVersion: v1 kind: Secret metadata: name: backend-tbc-anf-secret type: Opaque stringData: clientID: abcde356-bf8e-fake-c111-abcde35613aa clientSecret: rR0rUmWXfNioN1KhtHisiSAnoTherboGuskey6pU
Create a file named
backend-anf.yaml
and copy in the following YAML. Change thesubscriptionID
,tenantID
,location
, andserviceLevel
to the correct values for your environment. Use thesubscriptionID
for the Azure subscription where Azure NetApp Files is enabled. Obtain thetenantID
,clientID
, andclientSecret
from an application registration in Microsoft Entra ID with sufficient permissions for the Azure NetApp Files service. The application registration includes the Owner or Contributor role predefined by Azure. The location must be an Azure location that contains at least one delegated subnet created in a previous step. TheserviceLevel
must match theserviceLevel
configured for the capacity pool in Configure Azure NetApp Files for AKS workloads.apiVersion: trident.netapp.io/v1 kind: TridentBackendConfig metadata: name: backend-tbc-anf spec: version: 1 storageDriverName: azure-netapp-files subscriptionID: 12abc678-4774-fake-a1b2-a7abcde39312 tenantID: a7abcde3-edc1-fake-b111-a7abcde356cf location: eastus serviceLevel: Premium credentials: name: backend-tbc-anf-secret
For more information about backends, see Azure NetApp Files backend configuration options and examples.
Apply the secret and backend using the
kubectl apply
command. First apply the secret:kubectl apply -f backend-secret.yaml -n trident
The output of the command resembles the following example:
secret/backend-tbc-anf-secret created
Apply the backend:
kubectl apply -f backend-anf.yaml -n trident
The output of the command resembles the following example:
tridentbackendconfig.trident.netapp.io/backend-tbc-anf created
Confirm the backend was created by using the
kubectl get
command:kubectl get tridentbackends -n trident
The output of the command resembles the following example:
NAME BACKEND BACKEND UUID tbe-kfrdh backend-tbc-anf 8da4e926-9dd4-4a40-8d6a-375aab28c566
Create a storage class
A storage class is used to define how a unit of storage is dynamically created with a persistent volume. To consume Azure NetApp Files volumes, a storage class must be created.
Create a file named
anf-storageclass.yaml
and copy in the following YAML:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: azure-netapp-files provisioner: csi.trident.netapp.io parameters: backendType: "azure-netapp-files" fsType: "nfs"
Create the storage class using the
kubectl apply
command:kubectl apply -f anf-storageclass.yaml
The output of the command resembles the following example:
storageclass/azure-netapp-files created
Run the
kubectl get
command to view the status of the storage class:kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE azure-netapp-files csi.trident.netapp.io Delete Immediate false
Create a PVC
A persistent volume claim (PVC) is a request for storage by a user. Upon the creation of a persistent volume claim, Astra Trident automatically creates an Azure NetApp Files volume and makes it available for Kubernetes workloads to consume.
Create a file named
anf-pvc.yaml
and copy in the following YAML. In this example, a 1-TiB volume is needed with ReadWriteMany access.kind: PersistentVolumeClaim apiVersion: v1 metadata: name: anf-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 1Ti storageClassName: azure-netapp-files
Create the persistent volume claim with the
kubectl apply
command:kubectl apply -f anf-pvc.yaml
The output of the command resembles the following example:
persistentvolumeclaim/anf-pvc created
To view information about the persistent volume claim, run the
kubectl get
command:kubectl get pvc
The output of the command resembles the following example:
kubectl get pvc -n trident NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE anf-pvc Bound pvc-bffa315d-3f44-4770-86eb-c922f567a075 1Ti RWO azure-netapp-files 62s
Use the persistent volume
After the PVC is created, Astra Trident creates the persistent volume. A pod can be spun up to mount and access the Azure NetApp Files volume.
The following manifest can be used to define an NGINX pod that mounts the Azure NetApp Files volume created in the previous step. In this example, the volume is mounted at /mnt/data
.
Create a file named
anf-nginx-pod.yaml
and copy in the following YAML:kind: Pod apiVersion: v1 metadata: name: nginx-pod spec: containers: - name: nginx image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine resources: requests: cpu: 100m memory: 128Mi limits: cpu: 250m memory: 256Mi volumeMounts: - mountPath: "/mnt/data" name: volume volumes: - name: volume persistentVolumeClaim: claimName: anf-pvc
Create the pod using the
kubectl apply
command:kubectl apply -f anf-nginx-pod.yaml
The output of the command resembles the following example:
pod/nginx-pod created
Kubernetes has created a pod with the volume mounted and accessible within the
nginx
container at/mnt/data
. You can confirm by checking the event logs for the pod usingkubectl describe
command:kubectl describe pod nginx-pod
The output of the command resembles the following example:
[...] Volumes: volume: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: anf-pvc ReadOnly: false default-token-k7952: Type: Secret (a volume populated by a Secret) SecretName: default-token-k7952 Optional: false [...] Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 15s default-scheduler Successfully assigned trident/nginx-pod to brameshb-non-root-test Normal SuccessfulAttachVolume 15s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-bffa315d-3f44-4770-86eb-c922f567a075" Normal Pulled 12s kubelet Container image "mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine" already present on machine Normal Created 11s kubelet Created container nginx Normal Started 10s kubelet Started container nginx
Next steps
Astra Trident supports many features with Azure NetApp Files. For more information, see:
Azure Kubernetes Service