How to successfully create a **StorageClass** and a **StatefulSet** to deploy **SQL Server** on Kubernetes using **Azure File Share** as persistent storage. However, let me walk you through what each part of the YAML file does and check for any issues or improvements that may be needed.
### 1. **StorageClass** Explanation
The **StorageClass** defines how persistent volumes are provisioned in your Kubernetes cluster using Azure File Share.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile-csi-custom
provisioner: file.csi.azure.com
parameters:
skuName: Standard_LRS
mountOptions:
- dir_mode=0777
- file_mode=0777
- uid=1000
- gid=1000
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true
```
- **provisioner: file.csi.azure.com**: This tells Kubernetes that the Azure File CSI driver will be used to provision the persistent volume.
- **parameters: skuName: Standard_LRS**: This defines the storage replication type as **Standard Locally Redundant Storage (LRS)**.
- **mountOptions**: Ensures that directories and files in the Azure File Share have the permissions `0777` (read, write, execute for all users) and are owned by the user `uid=1000` and group `gid=1000`.
- **reclaimPolicy: Retain**: When the PersistentVolumeClaim (PVC) is deleted, the data in the Azure File Share is retained.
- **volumeBindingMode: Immediate**: The PV is created and bound to a PVC immediately after the PVC is created.
- **allowVolumeExpansion: true**: Allows the volume size to be expanded if needed.
### 2. **StatefulSet** Explanation
The **StatefulSet** ensures that the SQL Server pods are provided persistent storage and that the storage remains consistent across pod restarts or scaling.
```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql-statefulset
spec:
serviceName: "mssql-service"
replicas: 1
selector:
matchLabels:
app: mssql
template:
metadata:
labels:
app: mssql
spec:
containers:
- name: mssql
image: mcr.microsoft.com/mssql/server:2019-latest
ports:
- containerPort: 1433
name: mssql
env:
- name: ACCEPT_EULA
value: "Y"
- name: SA_PASSWORD
value: "password@123"
- name: MSSQL_TELEMETRY_OPTOUT
value: "1"
volumeMounts:
- name: mssql-data
mountPath: /var/opt/mssql
tolerations:
- key: "kubernetes.azure.com/scalesetpriority"
operator: "Equal"
value: "spot"
effect: "NoSchedule"
volumeClaimTemplates:
- metadata:
name: mssql-data
spec:
accessModes: ["ReadWriteMany"]
storageClassName: "azurefile-csi-custom"
resources:
requests:
storage: 20Gi
```
- **replicas: 1**: Only one replica (instance) of the MSSQL Server is created. You can scale this if needed.
- **ACCEPT_EULA: "Y"**: This is required to accept the Microsoft SQL Server license agreement.
- **SA_PASSWORD**: Sets the password for the SQL Server `sa` (system administrator) account. Remember to change this to a strong password in production.
- **MSSQL_TELEMETRY_OPTOUT**: Disables SQL Server telemetry for privacy concerns.
- **volumeMounts**: The volume is mounted at `/var/opt/mssql`, which is the default path where MSSQL Server stores its data in Linux.
- **tolerations**: Allows the pod to be scheduled on **spot instances** (preemptible instances). Make sure this is what you want—since spot instances can be interrupted, it might not be ideal for databases.
### 3. **Persistent Volume Claim (PVC) Template**
The **volumeClaimTemplates** section creates a Persistent Volume Claim (PVC) for the SQL Server instance. The PVC uses the `azurefile-csi-custom` storage class, and requests **20GiB** of storage.
### Troubleshooting or Things to Consider
#### a. **Spot Instances Consideration**
Since you are tolerating `kubernetes.azure.com/scalesetpriority=spot:NoSchedule`, the SQL Server pod can be scheduled on **spot instances**. **Spot instances** are subject to preemption, meaning they can be taken down at any time, which may not be ideal for a database like SQL Server. You should use regular nodes if you want to ensure data consistency and avoid potential interruptions.
If you want to avoid running this workload on spot instances, you can remove the `tolerations` section or set it only for specific non-critical applications.
#### b. **PVC Binding**
Make sure that the **PersistentVolumeClaim** (PVC) is created and **bound** properly to a **PersistentVolume** (PV). You can check the status of PVC using:
```bash
kubectl get pvc
```
Make sure the status is `Bound`, which means the storage has been correctly provisioned.
#### c. **Check Pod Status**
Ensure the pod is running correctly with:
```bash
kubectl get pods
```
If the pod is not in the **Running** state, describe the pod to check for any issues:
```bash
kubectl describe pod <pod-name>
```
#### d. **Accessing Logs**
Check SQL Server logs to ensure it's running properly:
```bash
kubectl logs <pod-name>
```
#### e. **Access Modes**
You are using `ReadWriteMany` (`accessModes: ["ReadWriteMany"]`), which means that multiple nodes can read and write to this storage at the same time. This is fine for Azure Files, but you might want to verify if this access mode is necessary based on your deployment needs. If you plan to scale your SQL Server pods in the future, **ReadWriteMany** is suitable. Otherwise, you could use `ReadWriteOnce` if you’re only running a single instance.
### Conclusion
- The **StorageClass** and **StatefulSet** configuration looks good overall.
- Consider the potential risks of running on **spot instances**.
- Ensure the **PersistentVolumeClaim** is **bound** and storage is provisioned.
- Regularly check the status of the pods and volumes.
If you have any specific issues or errors during deployment, let me know, and I can assist with troubleshooting!