About Me

My photo
I am an MCSE in Data Management and Analytics, specializing in MS SQL Server, and an MCP in Azure. With over 19+ years of experience in the IT industry, I bring expertise in data management, Azure Cloud, Data Center Migration, Infrastructure Architecture planning, as well as Virtualization and automation. I have a deep passion for driving innovation through infrastructure automation, particularly using Terraform for efficient provisioning. If you're looking for guidance on automating your infrastructure or have questions about Azure, SQL Server, or cloud migration, feel free to reach out. I often write to capture my own experiences and insights for future reference, but I hope that sharing these experiences through my blog will help others on their journey as well. Thank you for reading!

 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!



No comments: