Using Azure Files with Kubernetes (Full Script + Troubleshooting)
If you're running workloads on Azure Kubernetes Service and need multiple pods to read and write the same directory, you need:
ReadWriteMany (RWX) storage
In this tutorial, we’ll:
- Deploy shared storage using Azure Files
- Mount it in multiple pods
- Prove cross-pod writes
- Cover real-world troubleshooting scenarios
Why RWX Matters
By default, many Kubernetes volumes are:
ReadWriteOnce (RWO)
Meaning:
- Mounted by only one node at a time.
RWX allows:
- Multiple pods
- Across different nodes
- Simultaneous read/write access
Perfect for:
- WordPress clusters
- Shared uploads
- ML distributed training
- Batch processing
- CI runners
Architecture Overview
Pods (2 replicas)
↓
PersistentVolumeClaim (RWX)
↓
azurefile-csi StorageClass
↓
Azure File Share
Prerequisites
- AKS cluster running
-
kubectlconfigured - Azure File CSI driver enabled (default in modern AKS)
Verify:
kubectl get csidrivers
You should see:
file.csi.azure.com
Also confirm storage class:
kubectl get sc
You should see:
azurefile-csi
Full End-to-End Script
Save as:
rwx-demo.sh
#!/bin/bash
set -e
echo "========================================"
echo "AKS RWX Shared Storage Demo"
echo "========================================"
NAMESPACE="rwx-demo"
echo "1️⃣ Creating namespace..."
kubectl create namespace $NAMESPACE || true
echo "2️⃣ Creating RWX PVC (Azure Files)..."
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rwx-demo-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile-csi
resources:
requests:
storage: 5Gi
EOF
echo "Waiting for PVC to bind..."
for i in {1..30}; do
STATUS=$(kubectl get pvc rwx-demo-pvc -n $NAMESPACE -o jsonpath='{.status.phase}')
if [ "$STATUS" = "Bound" ]; then
echo "PVC is Bound ✅"
break
fi
echo "Still waiting..."
sleep 5
done
echo "3️⃣ Deploying 2 writer pods..."
cat <<EOF | kubectl apply -n $NAMESPACE -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: rwx-writer
spec:
replicas: 2
selector:
matchLabels:
app: rwx-writer
template:
metadata:
labels:
app: rwx-writer
spec:
containers:
- name: writer
image: busybox
command: ["/bin/sh", "-c"]
args:
- |
while true; do
echo "Written by \$(hostname) at \$(date)" >> /shared/output.txt
sleep 5
done
volumeMounts:
- mountPath: /shared
name: shared-volume
volumes:
- name: shared-volume
persistentVolumeClaim:
claimName: rwx-demo-pvc
EOF
echo "Waiting for pods..."
kubectl rollout status deployment/rwx-writer -n $NAMESPACE
echo "4️⃣ Listing pods..."
kubectl get pods -o wide -n $NAMESPACE
echo "5️⃣ Showing shared file content..."
POD=$(kubectl get pod -n $NAMESPACE -l app=rwx-writer -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n $NAMESPACE $POD -- sh -c "sleep 10 && cat /shared/output.txt"
echo ""
echo "========================================"
echo "✅ RWX demo completed successfully!"
echo "========================================"
echo "To clean up:"
echo "kubectl delete namespace $NAMESPACE"
Run the Demo
chmod +x rwx-demo.sh
./rwx-demo.sh
You should see output like:
Written by rwx-writer-xxxx at ...
Written by rwx-writer-yyyy at ...
That proves:
- Both pods
- Writing to the same file
- Across potentially different nodes
- Backed by Azure Files
- Using ReadWriteMany
Production Use Cases
| Workload | Shared Path |
|---|---|
| WordPress HA | /wp-content/uploads |
| ML training |
/dataset, /checkpoints
|
| Batch jobs | /output |
| CI runners | /workspace |
Troubleshooting Guide
1️⃣ PVC Stuck in Pending
Run:
kubectl describe pvc rwx-demo-pvc -n rwx-demo
Check the Events section.
Common causes:
StorageClass name mismatch
Check available classes:
kubectl get sc
Update:
storageClassName: azurefile-csi
2️⃣ Permission / Authorization Errors
If you see:
AuthorizationFailed
AKS identity likely lacks permissions.
Find node resource group:
az aks show \
--resource-group <rg> \
--name <cluster> \
--query nodeResourceGroup -o tsv
Grant Contributor role to AKS identity.
3️⃣ CSI Driver Not Installed
Check:
kubectl get csidrivers
If missing:
az aks update \
--resource-group <rg> \
--name <cluster> \
--enable-azure-file-csi-driver
4️⃣ kubectl wait Timeout
Sometimes kubectl wait misses the transition.
Use polling instead:
kubectl get pvc -n rwx-demo
If STATUS = Bound → provisioning succeeded.
Performance Tips
- For Linux-only clusters, consider NFS-based Azure Files
- For high-performance ML or analytics workloads, evaluate Azure NetApp Files
- Monitor IOPS and throughput for scaling decisions
Final Thoughts
RWX storage unlocks:
- True HA CMS deployments
- Distributed batch processing
- Shared AI datasets
- Multi-replica CI environments
And with AKS + Azure Files, it’s fully managed and production-ready.

Top comments (0)