Ultimate Guide to SQL Server Backup in Kubernetes Using NFS Volumes
This guide explains how to create backups of a SQL Server Availability Group using the DxEnterpriseSqlAg custom resource. The recommended method is to attach a volume to the SQL Server container and direct SQL Server backups to write data to this volume.
Overview
SQL Server supports writing database backups to any mounted filesystem path accessible inside the container. In Kubernetes, this is typically exposed via a volumeMount backed by an NFS share (or any other supported PV type).
DH2i recommends mounting an NFS export to /var/opt/mssql/backup, which is the SQL Server standard backup directory on Linux.
Prerequisites
- A working Kubernetes cluster (for example, Minikube, AKS, EKS, GKE).
- DxOperator installed and running (DxOperator Quick Start Guide)
Minikube running with the WSL2 driver has known limitations with NFS-backed Kubernetes volumes:
- The kubelet may present a different source IP than the Minikube VM.
- WSL2 networking often rewrites ephemeral ports, causing:
mount.nfs: access denied by serverrpc.mountd: illegal port/unmatched host
- Kubernetes mounts occur from the kubelet namespace, not the interactive
minikube sshsession.
This can result in failed NFS volume mounts even when manual tests appear successful.
Use the Hyper-V driver instead:
minikube start --driver=hyperv
Configure the NFS Server
The following example demonstrates how to export /exports/sqlbackups from an RHEL or Ubuntu-based NFS server for use by Kubernetes.
- Install and enable NFS services
- RHEL
- Ubuntu
sudo dnf install -y nfs-utils
sudo systemctl enable --now nfs-server
sudo apt update
sudo apt install nfs-kernel-server -y
- Create the export directory
sudo mkdir -p /exports/sqlbackups
sudo chmod 0777 /exports/sqlbackups
In production, consider using a dedicated service account and more restrictive permissions. For testing and lab environments, 0777 is often acceptable.
- Configure
/etc/exports
Configure an NFS export rule similar to the following to make the backup directory available to your Kubernetes nodes:
/exports/sqlbackups *(rw,sync,no_root_squash,no_subtree_check,insecure)
Explanation of options:
rw- allow read/write access.sync- commit writes to disk before replying (safer for database backups).no_root_squash- preserve root privileges from the client (required for many containerized SQL Server workloads).no_subtree_check- improves reliability when exporting subdirectories.insecure- allow mounts from high source ports; often required for Kubernetes nodes and Minikube.
- Apply the NFS export rule:
sudo exportfs -ra
sudo exportfs -v
- Open firewall ports for nfs, mountd, and rpc-bind.
- RHEL
- Ubuntu
sudo firewall-cmd --permanent --add-service=nfs
sudo firewall-cmd --permanent --add-service=mountd
sudo firewall-cmd --permanent --add-service=rpc-bind
sudo firewall-cmd --reload
sudo ufw allow 111/tcp
sudo ufw allow 111/udp
sudo ufw allow 2049/tcp
sudo ufw allow 2049/udp
sudo ufw allow 20048/tcp
sudo ufw allow 20048/udp
sudo ufw reload
- Enable read/write access to all exported NFS file systems if SELinux is in enforcing mode
sudo setsebool -P nfs_export_all_rw 1
Configure the DxEnterpriseSqlAg Custom Resource
The following example mounts an NFS share exposed at /exports/sqlbackups to /var/opt/mssql/backup in each SQL Server pod.
---
apiVersion: dh2i.com/v1
kind: DxEnterpriseSqlAg
metadata:
name: dxesqlag
spec:
synchronousReplicas: 3
asynchronousReplicas: 0
configurationOnlyReplicas: 0
availabilityGroupListenerPort: 14033
availabilityGroupName: AG1
availabilityGroupOptions: null
availabilityGroupClusterType: EXTERNAL
createLoadBalancers: true
template:
metadata:
labels:
label: example
annotations:
annotation: example
spec:
# --- Add the NFS volume definition here ---
volumes:
- name: nfs-backup-volume
nfs:
server: 10.1.100.62
path: /exports/sqlbackups
dxEnterpriseContainer:
image: "docker.io/dh2i/dxe:latest"
imagePullPolicy: Always
acceptEula: true
clusterSecret: dxe
vhostName: VHOST1
joinExistingCluster: false
volumeClaimConfiguration:
storageClassName: null
resources:
requests:
storage: 1Gi
mssqlServerContainer:
image: "mcr.microsoft.com/mssql/server:latest"
imagePullPolicy: Always
mssqlSecret: mssql
acceptEula: true
mssqlPID: Developer
mssqlConfigMap: null
volumeClaimConfiguration:
storageClassName: null
resources:
requests:
storage: 2Gi
# --- Mount the NFS share into the SQL Server container ---
volumeMounts:
- name: nfs-backup-volume
mountPath: /var/opt/mssql/backup
Key points:
volumes[].nfs.serveris the IP or DNS name of your NFS server.volumes[].nfs.pathis the exported directory on the NFS server.mssqlServerContainer.volumeMounts[].mountPathis the path used for SQL Server backups inside the container.
Verify the NFS Backup Path Inside the SQL Container
- After applying the DxEnterpriseSqlAg manifest and waiting for all pods to reach
2/2 Running:
kubectl get pods
Example:
NAME READY STATUS RESTARTS AGE
dxesqlag-0 2/2 Running 0 10m
dxesqlag-1 2/2 Running 0 10m
dxesqlag-2 2/2 Running 0 10m
- Check the mount inside the SQL Server container:
kubectl exec -it dxesqlag-0 -c mssql -- df -h /var/opt/mssql/backup
You should see the NFS export mounted:
Filesystem Size Used Avail Use% Mounted on
10.1.100.62:/exports/sqlbackups 50G 6.4G 44G 13% /var/opt/mssql/backup
- Test write access from within the container:
kubectl exec -it dxesqlag-0 -c mssql -- bash -c "echo 'nfs-test' > /var/opt/mssql/backup/container-test.txt"
On the NFS server:
ls -l /exports/sqlbackups/container-test.txt
Performing a SQL backup to NFS
Once the NFS mount is verified, you can back up databases from inside the SQL container directly to the mounted path.
Example using sqlcmd:
kubectl exec -it dxesqlag-0 -c mssql -- /opt/mssql-tools/bin/sqlcmd \
-S localhost -U sa -P '<YourSAPassword>' \
-Q "BACKUP DATABASE [master] TO DISK='/var/opt/mssql/backup/master_test.bak' WITH INIT"
On the NFS server:
ls -lh /exports/sqlbackups/master_test.bak
You should see a .bak file at the expected location.
References
-
Kubernetes NFS volumes https://v1-32.docs.kubernetes.io/docs/concepts/storage/volumes/#nfs
-
SQL Server backup and restore on Linux https://learn.microsoft.com/sql/linux/sql-server-linux-backup-and-restore-database