Deploy MSSQL Server via Kubernetes MSSQL Server Operator

Kubernetes MSSQL Server

In today’s cloud-first era, the need for high-performance, scalable relational databases is more critical than ever. Kubernetes is the industry-standard container orchestration platform, renowned for its ability to manage containerized applications with efficiency and reliability. While it simplifies deployment and scaling for stateless applications, deploying stateful services such as databases requires additional tooling.

Microsoft SQL Server (MSSQL Server), a widely-adopted relational database management system, offers enterprise-grade solutions known for reliability, security, and advanced analytics capabilities. When deployed on Kubernetes, MSSQL Server can take advantage of the cloud-native principles of automation, scalability, and high availability, empowering businesses to meet the demands of modern, data-driven applications.

To streamline the deployment and operation of MSSQL Server on Kubernetes, the Kubernetes MSSQL Server Operator has emerged as a powerful tool. The Kubernetes MSSQL Server Operator simplifies the process of deploying, managing, and scaling MSSQL Server instances on Kubernetes clusters by automating key operational tasks. By extending Kubernetes native capabilities, this operator makes it easier to manage MSSQL Server as a declarative resource, reducing the complexity of database operations. In this article, we’ll dive into the process of deploying MSSQL Server using the Kubernetes MSSQL Server Operator, highlighting the advantages and providing a step-by-step guide.

Why MSSQL Server on Kubernetes

MSSQL Server is known for its enterprise-level performance, robust security, and seamless integration with the broader Microsoft ecosystem. It supports both OLTP (Online Transaction Processing) and OLAP (Online Analytical Processing) workloads, making it a versatile solution for businesses with varied database needs. Running MSSQL Server on Kubernetes provides enhanced flexibility, scalability, and operational efficiency, helping organizations better manage and optimize their database infrastructure.

Kubernetes offers several features that complement MSSQL Server’s capabilities. With built-in orchestration and automation, Kubernetes allows MSSQL Server to benefit from self-healing, auto-scaling, rolling updates, and high availability. These capabilities enable MSSQL Server to scale dynamically and handle growing data workloads with minimal manual intervention. Resource optimization of Kubernetes ensures that MSSQL Server instances are running efficiently, while its self-healing mechanisms reduce downtime by automatically recovering from failures, ensuring higher availability and resilience.

Additionally, deploying MSSQL Server on Kubernetes makes it easier to manage the lifecycle of your database instances. Kubernetes persistent storage solutions provide durability and data consistency, even in the event of infrastructure failures. This ensures that your MSSQL Server databases are highly available and protected against data loss, offering the stability and reliability needed for mission-critical applications.

By utilizing Kubernetes, MSSQL Server can be effortlessly integrated into cloud-native environments, allowing organizations to minimize operational complexity, streamline infrastructure management, and scale database resources to meet evolving business demands. This makes it an ideal platform for organizations seeking to optimize database performance and infrastructure efficiency in a modern, containerized ecosystem.

Deploy MSSQL Server on Kubernetes

Pre-requisites

We have to set up the environment to deploy MSSQL Server on Kubernetes using a Kubernetes MSSQL Server operator. A running Kubernetes cluster and fundamental understanding of MSSQL Server is required to conduct this tutorial. Here we are using Kind to create our Kubernetes cluster. Additionally, you should install Helm to your Kubernetes cluster.

In this tutorial, We will use the Kubernetes MSSQL Server operator KubeDB to deploy MSSQL Server on Kubernetes. We must install KubeDB to our Kubernetes cluster. To set up KubeDB in our Kubernetes cluster, we need a license. We can get a free license using the Appscode License Server. We should use Kubernetes cluster ID to get a license. Use the following command below to get the cluster ID.

$ kubectl get ns kube-system -o jsonpath='{.metadata.uid}'
89c4f6f6-39fc-4b04-ad93-11deac96d5c3

The license server will email us with a “license.txt” file attached after we provide the necessary data. Run the following commands listed below to install KubeDB.

$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \
  --version v2024.8.21 \
  --namespace kubedb --create-namespace \
  --set-file global.license=/path/to/the/license.txt \
  --set global.featureGates.MSSQLServer=true \
  --wait --burst-limit=10000 --debug

Verify the installation by the following command,

$ kubectl get pods --all-namespaces -l "app.kubernetes.io/instance=kubedb"
NAMESPACE   NAME                                            READY   STATUS    RESTARTS   AGE
kubedb      kubedb-kubedb-autoscaler-76f47cb964-ckz7c       1/1     Running   0          3m56s
kubedb      kubedb-kubedb-ops-manager-69b5bfdc4d-lm7jv      1/1     Running   0          3m56s
kubedb      kubedb-kubedb-provisioner-5dd9c86655-j7ph7      1/1     Running   0          3m56s
kubedb      kubedb-kubedb-webhook-server-867b8cf8c4-nmgpc   1/1     Running   0          3m56s
kubedb      kubedb-petset-operator-77b6b9897f-cjgtc         1/1     Running   0          3m56s
kubedb      kubedb-petset-webhook-server-556b48c68b-sc6fw   2/2     Running   0          3m56s
kubedb      kubedb-sidekick-c898cff4c-4q58x                 1/1     Running   0          3m56s

We can go on to the next stage if every pod status is running.

Create a Namespace

To keep resources isolated, we’ll use a separate namespace called demo throughout this tutorial. Run the following command to create the namespace:

$ kubectl create namespace demo
namespace/demo created

Install Cert Manager

To manage TLS certificates within Kubernetes, we need to install Cert Manager. Follow these steps to install Cert Manager using the YAML manifest:

$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.0/cert-manager.yaml
namespace/cert-manager created
...

Create Issuer

Next, we need to create an Issuer, which will be used to generate certificates for TLS settings and internal endpoint authentication of availability group replicas.

Start by generating CA certificates using OpenSSL:

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=MSSQLServer/O=KubeDB"
Generating a RSA private key
..........................................................................+++++
..+++++
writing new private key to './ca.key'
-----

Create a Kubernetes Secret to store the CA certificate:

$ kubectl create secret tls mssqlserver-ca --cert=ca.crt  --key=ca.key --namespace=demo
secret/mssqlserver-ca created

Create an Issuer using the CA certificate stored in the mssqlserver-ca Secret. Below is the YAML definition for the Issuer:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: mssqlserver-issuer
  namespace: demo
spec:
  ca:
    secretName: mssqlserver-ca

Below is the YAML definition for the Issuer:

$ kubectl apply -f issuer.yaml
issuer.cert-manager.io/mssqlserver-issuer created

Deploy MSSQL Server using Kubernetes MSSQL Server operator

Now, we can deploy an MSSQL Server Availability Group Cluster using the following YAML definition:

apiVersion: kubedb.com/v1alpha2
kind: MSSQLServer
metadata:
  name: mssqlserver-ag-cluster
  namespace: demo
spec:
  version: "2022-cu12"
  replicas: 3
  topology:
    mode: AvailabilityGroup
    availabilityGroup:
      databases:
        - music
  internalAuth:
    endpointCert:
      issuerRef:
        apiGroup: cert-manager.io
        name: mssqlserver-issuer
        kind: Issuer
  tls:
    issuerRef:
      name: mssqlserver-issuer
      kind: Issuer
      apiGroup: "cert-manager.io"
    clientTLS: false
  storageType: Durable
  storage:
    storageClassName: "standard"
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 1Gi
  deletionPolicy: WipeOut

Let’s save this yaml configuration into mssqlserver-ag-cluster.yaml Then apply the above MSSQL Server yaml,

$ kubectl apply -f mssqlserver-ag-cluster.yaml 
mssqlserver.kubedb.com/mssqlserver-ag-cluster created

You can see the detailed yaml specifications in the Kubernetes MSSQL Server documentation.

Once these are handled correctly and the MSSQLServer object is deployed, you will see that the following resources are created:

$ kubectl get all -n demo
NAME                           READY   STATUS    RESTARTS   AGE
pod/mssqlserver-ag-cluster-0   2/2     Running   0          5m29s
pod/mssqlserver-ag-cluster-1   2/2     Running   0          4m24s
pod/mssqlserver-ag-cluster-2   2/2     Running   0          3m1s

NAME                                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/mssqlserver-ag-cluster             ClusterIP   10.128.113.192   <none>        1433/TCP   6m35s
service/mssqlserver-ag-cluster-pods        ClusterIP   None             <none>        1433/TCP   6m35s
service/mssqlserver-ag-cluster-secondary   ClusterIP   10.128.213.243   <none>        1433/TCP   6m35s

NAME                                                        TYPE                     VERSION   AGE
appbinding.appcatalog.appscode.com/mssqlserver-ag-cluster   kubedb.com/mssqlserver   2022      5m31s

NAME                                            VERSION     STATUS   AGE
mssqlserver.kubedb.com/mssqlserver-ag-cluster   2022-cu12   Ready    6m35s

Let’s check if the database is ready to use,

$ kubectl get mssqlserver -n demo mssqlserver-ag-cluster
NAME                     VERSION     STATUS   AGE
mssqlserver-ag-cluster   2022-cu12   Ready    7m11s

Accessing Database Through CLI

To access your database through the CLI, you first need the credentials for the database. KubeDB will create several Kubernetes Secrets and Services for your MSSQL Server instance. To view them, use the following commands:

$ kubectl get secret -n demo -l=app.kubernetes.io/instance=mssqlserver-ag-cluster 
NAME                                   TYPE                       DATA   AGE
mssqlserver-ag-cluster-auth            kubernetes.io/basic-auth   2      8m31s
mssqlserver-ag-cluster-client-cert     kubernetes.io/tls          3      8m31s
mssqlserver-ag-cluster-dbm-login       kubernetes.io/basic-auth   1      8m31s
mssqlserver-ag-cluster-endpoint-cert   kubernetes.io/tls          3      8m31s
mssqlserver-ag-cluster-master-key      kubernetes.io/basic-auth   1      8m31s
mssqlserver-ag-cluster-server-cert     kubernetes.io/tls          3      8m31s

$ kubectl get service -n demo -l=app.kubernetes.io/instance=mssqlserver-ag-cluster 
NAME                               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
mssqlserver-ag-cluster             ClusterIP   10.128.113.192   <none>        1433/TCP   8m37s
mssqlserver-ag-cluster-pods        ClusterIP   None             <none>        1433/TCP   8m37s
mssqlserver-ag-cluster-secondary   ClusterIP   10.128.213.243   <none>        1433/TCP   8m37s

From the above list, the mssqlserver-ag-cluster-auth Secret contains the admin-level credentials needed to connect to the database. Use the following commands to obtain the username and password:

$ kubectl get secret -n demo mssqlserver-ag-cluster-auth  -o jsonpath='{.data.username}' | base64 -d
sa
$ kubectl get secret -n demo mssqlserver-ag-cluster-auth  -o jsonpath='{.data.password}' | base64 -d
dS57E93oLDi6wezv

Insert Sample Data

In this section, we will insert sample data into our MSSQL Server deployed on Kubernetes. Before we can insert data, we need to identify the primary node, as data writes are only permitted on the primary node.

To determine which pod is the primary node, run the following command to list the pods along with their roles:

$ kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}'

mssqlserver-ag-cluster-0	primary
mssqlserver-ag-cluster-1	secondary
mssqlserver-ag-cluster-2	secondary

From the output above, we can see that mssqlserver-ag-cluster-0 is the primary node. To insert data, log into the primary MSSQL Server pod. Use the following command,

$ kubectl exec -it mssqlserver-ag-cluster-0 -n demo bash
Defaulted container "mssql" out of: mssql, mssql-coordinator, mssql-init (init)
mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "dS57E93oLDi6wezv"

1> SELECT name FROM sys.databases
2> GO
name                                                                                                                            
--------------------------------------------------------------------------------------------------------------------------------
master                                                                                                                          
tempdb                                                                                                                          
model                                                                                                                           
msdb                                                                                                                            
music                                                                                                                           
kubedb_system                                                                                                                   

(6 rows affected)

# Verify that the database 'music' has been created and added to the `availability group cluster`. Then, we will insert data into this `music` database.
1> SELECT database_name
2> FROM sys.availability_databases_cluster
3> GO
database_name                                                                                                                   
--------------------------------------------------------------------------------------------------------------------------------
music                                                                                                                           

(1 rows affected)

1> USE music
2> GO
Changed database context to 'music'.

1> CREATE TABLE Playlist (Artist NVARCHAR(255), Song NVARCHAR(255));
2> GO
1> INSERT INTO Playlist(Artist, Song) VALUES ('Bobby Bare', 'Five Hundred Miles');
2> GO

(1 rows affected)
1> SELECT * FROM Playlist
2> GO

Artist                                                                          Song
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
Bobby Bare                                                                      Five Hundred Miles

(1 rows affected)
1> exit

...

# Confirm that the data inserted into the primary node has been replicated to the secondary nodes.
# Access the secondary node (Node 2) to verify that the data is present.
$ kubectl exec -it mssqlserver-ag-cluster-1 -n demo bash
Defaulted container "mssql" out of: mssql, mssql-coordinator, mssql-init (init)
mssql@mssqlserver-ag-cluster-1:/$ /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "dS57E93oLDi6wezv"

1> USE music
2> GO
Changed database context to 'music'.

1> SELECT * FROM Playlist
2> GO

Artist                                                                          Song
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
Bobby Bare                                                                      Five Hundred Miles

(1 rows affected)
1> exit

...

# Access the secondary node (Node 3) to verify that the data is present.
$ kubectl exec -it mssqlserver-ag-cluster-2 -n demo bash
Defaulted container "mssql" out of: mssql, mssql-coordinator, mssql-init (init)
mssql@mssqlserver-ag-cluster-2:/$ /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "dS57E93oLDi6wezv"

1> USE music
2> GO
Changed database context to 'music'.

1> SELECT * FROM Playlist
2> GO

Artist                                                                          Song
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
Bobby Bare                                                                      Five Hundred Miles

(1 rows affected)
1> exit

Congratulations! We’ve successfully deployed MSSQL Server on Kubernetes using Kubernetes MSSQL Server operator KubeDB. Additionally, we’ve added sample data to the MSSQL Server and access it from every node of Availability Group Cluster.

MSSQL Server on Kubernetes: Best Practices

To ensure optimal performance and reliability of your MSSQL Server instances running within Kubernetes, consider the following best practices:

  • Optimize Resource Utilization: For efficient database performance and cost management, it’s essential to allocate resources appropriately for MSSQL Server. Carefully assess CPU, memory, and storage needs based on the specific workload requirements. Implement Horizontal Pod Autoscaler (HPA) to dynamically adjust resources according to workload fluctuations, ensuring your MSSQL Server instances can handle changes in demand without manual intervention.

  • Monitoring and Observability: To maintain optimal performance, set up comprehensive monitoring and observability for your MSSQL Server instances. Monitor key metrics such as query performance, CPU utilization, disk I/O, and memory consumption. Use tools like Prometheus and Grafana to visualize performance data and identify any potential bottlenecks or issues early. Proactively implement alerting mechanisms to get notified of anomalies before they impact system performance or availability.

  • Disaster Recovery: Establish a robust disaster recovery strategy for your SQL Server instances. Leverage Kubernetes features like StatefulSets for managing persistent storage and enable Always On Availability Groups for high availability. Regularly back up your databases and test your recovery procedures to ensure minimal downtime and data loss in the event of a failure.

  • Security Configurations: Protect your SQL Server environment in Kubernetes with strong security measures. Use Kubernetes Network Policies to enforce access restrictions for SQL Server pods. Enable Transparent Data Encryption (TDE) for data at rest, and utilize SQL Server’s role-based access control (RBAC) to define user permissions.

Conclusion

Microsoft SQL Server, recognized for its robust performance and reliability in managing enterprise-grade data workloads, provides a powerful solution for organizations looking to optimize their database operations. Adopting best practices in database management, particularly within the dynamic Kubernetes environment, is essential for achieving efficiency and reliability. For more detailed information on MSSQL Server, refer to the official MSSQL Server documentation. Deploying MSSQL Server on Kubernetes using the Kubernetes MSSQL Server Operator simplifies management, combining the strengths of a traditional relational database with the scalability and flexibility of container orchestration. This approach facilitates automated provisioning, seamless scaling, and efficient resource management, ensuring high availability and optimal performance. The Kubernetes MSSQL Server Operator KubeDB streamlines these processes, supporting your infrastructure whether on-premises or in the cloud. By using this combination, you position your MSSQL Server deployments to be agile, resilient, and well-equipped to meet the demands of modern applications.

Share on social media

What They Are Talking About us

Trusted by top engineers at the most ambitious companies

faq-image

frequently asked questions

Here are a few of the questions we get the most. If you don't see what's on your mind, contact us anytime.

Can I manage multiple Databases via KubeDB?

Yes, you can manage as many databases as you want within a single subscription to KubeDB, and there is no extra charge for that!

Can I use KubeDB in any cloud?

Yes, of course! KubeDB is platform-independent. You can use KubeDB in any cloud or on-premises.

My cluster is running on bare metal. Will it be safe to use KubeDB?

KubeDB is running in production by multiple Governments and large organizations. Your data is always safe within KubeDB.

Do you have offer technical support?

We offer 24x7 technical system and maintain SLA to provide 100% reliability to our customers.

Is Stash complementary with KubeDB?

Yes, Stash is seemingly integrated with KubeDB. There is no extra charge for using Stash. It is complimentary with KubeDB.

Can we try KubeDB?

Of course! We offer a 30 days license free of cost to try fully featured KubeDB.

Is there any cancellation fee?

There is no cancellation fee. But plans are subject to minimum duration (1 year) as stated above.

What types of payment do you accept?

We prefer ACH transfer for US based customers and international wire transfer for everyone else. We can also accept all popular credit/debit cards such as Visa, Mastercard, American Express, Discover, etc.

Is my payment information safe?

Yes! For ACH transfer and wire transfer you work with your bank for payment. Our credit card processing is powerd by Stripe. You credit card data never touches our servers. For more information, please visit stripe.com.

Run and Manage your Database on Kubernetes FREE !

KubeDB is FREE to use on any supported Kubernetes engines. You can deploy and manage your database in Kubernetes using KubeDB. There is no up-front investment required. We offer a 30 days license FREE of cost to try KubeDB.