Right, let’s talk about getting data into your pods. You’ve built this brilliant, ephemeral, self-healing microservice. Fantastic. Now it needs to read a config file. Or write a log. Or store a user’s uploaded picture of their cat. Suddenly, your perfectly stateless world needs state. This is where the Container Storage Interface (CSI) drivers come in—they’re the well-mannered bouncers that translate your pod’s polite request for storage into the specific API calls Azure understands.

The old in-tree storage drivers were baked directly into Kubernetes core code, which meant updating your storage meant updating all of Kubernetes. It was a mess. The CSI standard fixed this by moving storage logic into out-of-tree drivers you can install and update independently. Azure provides two primary CSI drivers: one for block storage (AzureDisk) and one for file storage (AzureFiles). Your job is to know which one to use and when.

AzureDisk CSI: Your Go-To for Performance

When you need a high-performance block volume for a single pod, AzureDisk is your workhorse. It provisions either a Premium SSD (backed by NVMe) or a Standard HDD (backed by, well, spinning disks) and attaches it directly to your node. Your pod then gets exclusive read/write access. This is ideal for databases (like PostgreSQL or Redis), message queues, or any other stateful application that screams if another process tries to touch its disk.

You define what you need in a PersistentVolumeClaim (PVC). This is your ticket, your request to the system. Here’s one asking for a fast 100GiB disk:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-azure-disk-pvc
spec:
  accessModes:
    - ReadWriteOnce  # Key point: one pod at a time.
  storageClassName: managed-csi-premium  # This triggers the Azure Disk CSI driver
  resources:
    requests:
      storage: 100Gi

And then you’d mount that claim into a pod:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - mountPath: "/mnt/data"
      name: volume
  volumes:
  - name: volume
    persistentVolumeClaim:
      claimName: my-azure-disk-pvc  # Matching the PVC above

The magic is in the storageClassName. managed-csi-premium is the built-in class that uses the CSI driver for Premium SSDs. Azure AKS sets this up for you automatically. The big thing to remember here is ReadWriteOnce (RWO). It means what it says: one writer. You cannot attach this disk to multiple pods simultaneously. If you try, the second pod will sit around looking sad and Pending until the first one lets go.

AzureFiles CSI: Shared Storage for the Masses

Need multiple pods to read and write the same data? Welcome to AzureFiles. This driver provisions an Azure File Share (SMB 3.x) under the hood and mounts it into your pods. It’s perfect for shared configuration, content management systems, or legacy applications that expect a classic network drive.

The catch? It’s slower. You’re going over the network (even if it’s within Azure’s backbone) versus the local attach of an AzureDisk. It’s a trade-off: shared access for a performance hit.

Here’s a PVC for a 100GiB Azure File share. Notice the critical difference in accessModes:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-azure-files-pvc
spec:
  accessModes:
    - ReadWriteMany  # The key! Many pods can access this.
  storageClassName: azurefile-csi-premium  # This triggers the Azure Files CSI driver
  resources:
    requests:
      storage: 100Gi

The pod definition looks identical; you just reference the different PVC name. The azurefile-csi-premium storage class is, again, pre-provisioned for you on AKS. The ReadWriteMany (RWX) mode is what makes this work for multiple pods.

The Gotchas: Where They Get You

No solution is perfect. Here’s what to watch for.

  1. Performance Realities: An AzureDisk will always crush AzureFiles on IOPS and latency. If you have a high-throughput workload, AzureDisk is the only sane choice. Use AzureFiles for what it’s good at: sharing, not speed.

  2. The Secret Sauce (Literally): The AzureFiles driver needs your Azure Storage Account credentials to create the share. AKS handles this by creating a secret named azure-storage-account-<name>-secret in the kube-system namespace. The PVC dynamically provisions the share. For AzureDisk, it uses a managed identity attached to your node pool to talk to the Azure API—no secrets needed. This is a much cleaner and more secure approach, frankly.

  3. Pod Stuck in Pending? This is almost always one of three things:

    • Quota: You’ve hit your subscription’s limit on total storage or number of disks in that region. Go check your quota in the Azure portal.
    • Access Mode Mismatch: You defined a deployment with multiple replicas and tried to use an AzureDisk (RWO) PVC. A ReadWriteOnce volume can only be attached to one node. Your other pods will wait forever. Use AzureFiles (RWX) or a StatefulSet with individual disks for each replica.
    • Bad Storage Class: You typo’d the storageClassName or you’re trying to use a class that hasn’t been defined on your cluster.
  4. The Zone Redundancy Trap: This one’s important. Standard SSDs (managed-csi) are zonal resources. If you provision a PV in Zone 1, it cannot be attached to a node in Zone 2. If your pod gets scheduled to a different zone after a failure, it will fail to attach the volume. The solution? Use Premium SSDs (managed-csi-premium), which are, as of now, zone-redundant (ZRS) by default and can fail over across zones. Plan your availability strategy around your storage choice.