Set Up NFS File Share for Azure Kubernetes Service (AKS)

This article describes how to create an NFS Storage Account and NFS File Share to mount as a Persistent Volume in AKS deployment. Setting up an NFS file share for AKS involves configuring an Azure Storage Account with NFS support, setting up networking via a Private Endpoint, and mounting the file share inside AKS pods as a Persistent Volume.

NOTES:

  • The majority of this setup can be performed using Azure Cloud Shell, including creating the storage account, NFS share, Kubernetes manifests, and applying them with kubectl. For some networking and access control settings (such as Root Squash or manual mount testing), the Azure Portal or an Azure VM in the same VNet may be required.
  • Premium Storage is required for NFS storage by Azure (and NFS is required by Metric Insights as a Linux-based application). See the Azure Files planning article at https://learn.microsoft.com/en-us/azure/storage/files/storage-files-planning for more details.

Prerequisites:

  • An existing Azure Kubernetes Service (AKS) cluster.
  • az CLI installed and configured.
  • Access to create resources in the Azure subscription.
  • A virtual network (VNet) shared by both the AKS node pool and the storage Private Endpoint.

Table of Contents:

  1. Create a Premium File Storage Account with NFS Enabled
    1. Create a Storage Account
    2. Create and Configure NFS File Share
      1. Create New File Share
      2. Configure NFS Basics
      3. Configure Backup
      4. Review and Create NFS
  2. Create a Private Endpoint for the Storage Account
    1. Create New Private Endpoint
    2. Configure Basics
    3. Configure Resource
    4. Configure Virtual Network
    5. Configure DNS
    6. Review and Create Private Endpoint
    7. Locate NIC Address
  3. Configure Storage Account
    1. Disable Secure Transfer
    2. Copy NFS Address
  4. Configure Networking Settings
  5. Create a PersistentVolume and PersistentVolumeClaim
  6. Mount the Volume in a Deployment

1. Create a Premium File Storage Account with NFS Enabled

1.1. Create a Storage Account

Create a Premium File Storage Account in the Azure Portal:

  1. Select a Resource group or create a new one.
  2. Enter a Storage account name.
  3. Primary service: Azure Files.
  4. Performance: Premium.
  5. [Review + create]

Alternatively, use the Azure CLI:

az storage account create \
  --name <storageAccountName> \
  --resource-group <resourceGroupName> \
  --location <location> \
  --sku Premium_LRS \
  --kind FileStorage

NOTE: --enable-large-file-share is not required with the FileStorage kind; however, enabling it increases the maximum IOPS.

1.2. Create and Configure NFS File Share

Create an NFS File Share in the Azure Portal as described below, or alternatively use the Azure CLI. The example below provisions 100 GiB, provision more depending on the environment (e.g. Production vs Development):

az storage share-rm create \
  --resource-group <resourceGroupName> \
  --storage-account <storageAccountName> \
  --name <nfsShareName> \
  --enabled-protocol NFS \
  --quota 100

1.2.1. Create New File Share

  1. From the Storage account, access Data storage > File shares
  2. [+ File share]

1.2.2. Configure NFS Basics

  1. Enter a Name
  2. Provisioned storage (GiB): Select 100 or more, depending on the environment (e.g. Production vs Development).
  3. Protocol: NFS
  4. Root Squash: No Root Squash
  5. [Next: Backup]

1.2.3. Configure Backup

Skip to [Review + create] unless a specific configuration is required.

1.2.4. Review and Create NFS

Verify NFS configuration details, then [Create].

2. Create a Private Endpoint for the Storage Account

2.1. Create New Private Endpoint

  1. From the NFS File Share, access Overview > Connect from Linux
  2. Under Network configuration, select [Review options]
  3. [Setup a private endpoint]
  4. [+ Private endpoint]

2.2. Configure Basics

  1. Select a Resource group or create a new one.
  2. Enter a Name.
  3. [Next: Resource]

2.3. Configure Resource

  1. Target sub-resource: file
  2. [Next: Virtual Network]

2.4. Configure Virtual Network

  1. Virtual Network and Subnet: Set the same as the AKS node pool, or peered.
    • NOTE: Ensure the subnet selected is the same one where the AKS cluster has its worker instances deployed.
  2. [Next: DNS]

2.5. Configure DNS

[Next: Tags], then skip to Review + create.

2.6. Review and Create Private Endpoint

Review the configured private endpoint, then [Create].

2.7. Locate NIC Address

  1. Go to the Private Endpoint's Network Interface (NIC).
  2. Note the private IP address (e.g. 10.0.0.4).

3. Configure Storage Account

3.1. Disable Secure Transfer

Access Storage account

  1. Access Configuration
  2. Disable Secure transfer required
  3. [Save]

3.2. Copy NFS Address

Access Data storage > Classic file shares

  1. Access Data storage > Classic file shares
  2. Access the NFS share.
  3. Copy the NFS share full path, it will be required in Step 5.

4. Configure Networking Settings

Access NFS Storage > Security + networking > Networking

  1. Public network access scope: Enable from selected networks
  2. Under Virtual Networks section, click [+ Add a virtual network] to include the AKS subnet or peered subnet in the allowed list.

5. Create a PersistentVolume and PersistentVolumeClaim

In our example the NFS path is: docsstorage.file.core.windows.net:/docsstorage/aksdata, where:

  • docsstorage.file.core.windows.net is the NFS server address,
  • /docsstorage/aksdata is the remote subfolder.
  1. Create the nfs-pv.yaml file to define the Persistent Volume (PV) and Persistent Volume Claim (PVC):
apiVersion: v1
kind: PersistentVolume
metadata:
  name: metricinsights-data
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: default
  nfs:
    server: <private-ip-of-storage> # e.g., docsstorage.file.core.windows.net
    path: /<nfsShareName>           # e.g., /docsstorage/aksdata
  mountOptions:
    - vers=4.1
    - minorversion=1
    - sec=sys
    - proto=tcp
    - rsize=1048576
    - wsize=1048576
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: metricinsights-data
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: default
  resources:
    requests:
      storage: 100Gi
  volumeName: metricinsights-data
  1. Apply the manifest:
kubectl apply -f nfs-pv.yaml
  1. Verify the PV and PVC status. A status of Bound confirms the connection was successfully established and the volume is ready to use in Kubernetes.

6. Mount the Volume in a Deployment

The example below shows how to mount the volume inside a pod. The PVC created in Step 5 (metricinsights-data) can be referenced directly in the Metric Insights Kubernetes deployment manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-nfs-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-nfs-demo
  template:
    metadata:
      labels:
        app: nginx-nfs-demo
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - mountPath: "/opt/mi/data"
          name: data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: metricinsights-data
  1. Apply the deployment:
kubectl apply -f deployment.yaml

Then verify the deployment with the following commands:

  1. kubectl get deployment
  2. kubectl get pods
  3. Enter the running pod's container, using the pod name from the previous command:
kubectl exec -it <pod-name> -- bash
  1. Locate the mounted NFS share:
df -h
  • The NFS share appears in the output, mounted at /opt/mi/data.
  1. List the NFS share's content:
cd /opt/mi/data
ls -l
  1. Create a new file:
touch 1.txt
  1. Check the file's ownership:
ls -l
  • By default, new files are owned by root:root.
  1. Change the owner of the created file to www-data:www-data:
chown www-data:www-data 1.txt
  1. Verify that the ownership has changed:
ls -l

The file should now show www-data www-data as the owner and group.

NOTES:

  • If the pod is running, the Network Shared Storage is successfully connected. The default owner of the NFS volume is root, verify that ownership can be changed as needed.
  • A custom PVC can be provided to the installer during Kubernetes manifest generation. If a custom PVC is provided, no additional PVC definition is added to the manifest, as the PV and PVC are expected to be created manually before deploying the Metric Insights application.
    • The option is available via the --persistent-volume-claim flag:
./installer.py kubernetes --persistent-volume-claim <name>
  • Or via the installer wizard (step 16):
./installer.py kubernetes --wizard

When prompted, enter the PVC name (e.g. metricinsights-data) or leave empty to use the default value.