Let’s install SQL Server in a free Kubernetes cluster on IBM Cloud.
Kubernetes installation
Installing Kubernetes on IBM Cloud is free. Simply search for Kubernetes, select the Kubernetes service or use this link), and create a free cluster in the desired resource group.
After 5-10 minutes, the cluster should be created.
To test the connection to the cluster, select the Kubernetes cluster and then click Actions > Connect via CLI. The command we are looking for is the second one.
Now, if you run this command in the IBM Cloud console, you should see a success message, indicating that you can now interact with the cluster.
To retrieve cluster nodes, run the following command:
kubectl get nodes
The response should resemble the following:
NAME STATUS ROLES AGE VERSION
10.144.214.202 Ready <none> 17m v1.25.10+IKS
Permanent storage
Most databases deployed in Kubernetes require persistent storage. In the case of IBM Cloud, this is represented by IBM Cloud Object Storage bucket(s).
To create a free IBM Cloud Object Storage, search for Object Storage, select the Object Storage option (or use this link), and choose the Lite (free) plan.
To attach the storage to our Kubernetes cluster, we first need to generate IBM Cloud Object Storage service credentials.
To do this:
- Navigate to the object storage instance.
- Click on Service Credentials and then New credential.
- Enter a name for the service credential.
- Select the Writer role, which is required for the dynamic bucket provisioning feature.
- click Add.
The service credential is now created. Make a note of the apikey
as we will need it later to communicate with Cloud Object Storage.
Generate the kubernetes secret
Before mapping the storage, we need to generate a Kubernetes secret using the apikey obtained earlier and the resource ID.
To obtain the resource ID, run the following command in the IBM Cloud console, replacing <service_name>
with the correct object storage name.
ibmcloud resource service-instance <service_name> | grep GUID
Now let’s generate the Kubernetes secret required to connect to our object storage instance. Run the following command, replacing <apikey>
and <GUID>
with the correct values
kubectl create secret generic cos-write-access --type=ibm/ibmc-s3fs --from-literal=api-key=<apikey> --from-literal=service-instance-id=<GUID>
Install the storage plug-in
First, add the IBM Cloud Helm repo by running the following command:
helm repo add ibm-helm https://raw.githubusercontent.com/IBM/charts/master/repo/ibm-helm
Next, update the Helm repos:
helm repo update
If you have previously installed the IBM Cloud Object Storage Helm plug-in, remove the ibmc plug-in using the following command:
helm plugin uninstall ibmc
Next, download and unpack the chart to the current directory for configuration:
helm fetch --untar ibm-helm/ibm-object-storage-plugin
Edit ibm-object-storage-plugin/templates/provisioner-sa.yaml
and change line 69 as follows:
From:
rules:
- apiGroups: [""]
resources: ["secrets"]
#resourceNames: [""]
verbs: ["get"]
to:
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["cos-write-access"]
verbs: ["get"]
where cos-write-access
is the above secret we created.
Now, let’s proceed with installing the Helm plug-in:
helm plugin install ./ibm-object-storage-plugin/helm-ibmc
Once the plug-in is installed, we can proceed to install the storage plug-in in our cluster using the following command:
helm ibmc install ibm-object-storage-plugin ibm-helm/ibm-object-storage-plugin --set license=true
If you encounter an error such as Error: fork/exec /path/.local/share/helm/plugins/helm-ibmc/ibmc.sh: permission denied
, grant the necessary permissions to the file:
chmod 777 /path/.local/share/helm/plugins/helm-ibmc/ibmc.sh
Installing SQL Server
To install Microsoft SQL Server on Kubernetes, we first need to create a secret for the sa
password. Run the following command:
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD='<strong password here>'
Next, we will use a modified version of the YAML file provided by Microsoft in order to utilize our persistent storage.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mssql
spec:
serviceName: "mssql"
replicas: 1
selector:
matchLabels:
app: mssql
template:
metadata:
labels:
app: mssql
spec:
securityContext:
fsGroup: 10001
containers:
- name: mssql
image: mcr.microsoft.com/mssql/server:2022-latest
ports:
- containerPort: 1433
name: tcpsql
env:
- name: ACCEPT_EULA
value: "Y"
- name: MSSQL_ENABLE_HADR
value: "1"
- name: MSSQL_AGENT_ENABLED
value: "1"
- name: MSSQL_SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql
key: MSSQL_SA_PASSWORD
volumeMounts:
- name: mssql
mountPath: "/var/opt/mssql"
volumeClaimTemplates:
- metadata:
name: mssql
annotations:
ibm.io/auto-create-bucket: "true"
ibm.io/auto-delete-bucket: "true"
ibm.io/tls-cipher-suite: "default"
ibm.io/secret-name: "cos-write-access"
spec:
storageClassName: "ibmc-s3fs-standard-cross-region"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
If everything is set up correctly, apply the YAML file using the command:
kubectl apply -f mssql.yml
The installation process should now commence.
Testing
Let’s perform some tests to ensure everything is working as expected.
First, check if the persistent volume claim is ready by running:
kubectl get pvc
The expected result should be:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mssql-mssql-0 Bound pvc-6131e4c7-c1e8-444b-b612-7a0229272986 8Gi RWO ibmc-s3fs-standard-cross-region 71s
Next, check the actual persistent volume by running:
kubectl get pv
If everything is functioning correctly, the result should be:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-6131e4c7-c1e8-444b-b612-7a0229272986 8Gi RWO Delete Bound default/mssql-mssql-0 ibmc-s3fs-standard-cross-region 3m38s
Finally, check the status of the pod by running:
kubectl get pods
You should see a result similar to:
NAME READY STATUS RESTARTS AGE
mssql-0 1/1 Running 0 4m50s
To log in to the SQL Server pod, execute the following command:
kubectl exec -it mssql-0 -- /bin/bash
Then, connect to the SQL Server using sqlcmd
:
./opt/mssql-tools/bin/sqlcmd -U sa
If everything is set up correctly, you should be able to run any SQL command.
Documentation and links:
- Kubernetes StatefulSets documentation - https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
- IBM Cloud Object Storage in Kubernetes Guide - https://cloud.ibm.com/docs/containers?topic=containers-storage-cos-understand
- Deploy SQL Server Linux containers on Kubernetes with StatefulSets guide - https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-kubernetes-best-practices-statefulsets?view=sql-server-ver16
- SQLCMD Utility Documentation - https://learn.microsoft.com/en-us/sql/tools/sqlcmd/sqlcmd-use-utility?view=sql-server-ver16