On this, the last blog post of a three-blog series on using Kubernetes, let’s learn how we can save our SQL application databases on a persistent volume or storage. We will do this to ensure we never lose any data, for when the POD is redeployed, destroyed, or just decommissioned.
In this blog post, I will demonstrate how we can save our MS-SQL databases to a persistent volume. To begin, we need a NAS server, in addition to the Kubernetes cluster where we will mount the NFS path to the Cluster nodes. We will use this NFS path to attach to the MS-SQL POD. So, let’s get started:
Prepare the NAS folder
I am using a TrueNas in my lab. I created an NFS share called NFS that I will use through this demonstration. After the NFS share is created at the storage side, we must mount the share on to all the Cluster Nodes. Use the following command to mount the share:
sudo mount -t nfs [NAS-IP-Address]:/mnt/ProdNas/nfs /mnt/nfs/
note: /mnt/ProdNas/nfs is the path of the NAS folder
To ensure the NFS share is persistent and will remount after reboot – add the following line to the /etc/fstab file:
[NAS-IP-Address]:/mnt/ProdNas/nfs /mnt/nfs nfs defaults 0 0
Create the Kubernetes Volume
After the NFS folder has mounted on each of the cluster nodes, we are ready to create the PersistentVolume by creating a .yaml file, lets call it nfs-pvol.yaml, and paste the following script into it:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pvol
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
– ReadWriteMany
nfs:-pvol.yaml
server: [NAS_IP_Address]
path: “[NAS/Path]”
Save the nfs-pvol.yaml file and close it.
Now that we have created the PersistentVolume, we are ready to create the PersistentVolumeClaim .yaml file, let’s call it nfs-pvc.yaml, to be able to claim the storagevolume space, and then use it with our applications. To do so, we must paste the following script into our .yaml file:
piVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
storageClassName: manual
accessModes:
– ReadWriteMany
resources:
requests:
storage: 5Gi
Save the nfs-pvc.yaml file and close it.
After we have completed creating the two .yaml files above, we can use the following commands to execute the mounting of, and claiming the storage for, the NFS volume:
To attach the Volume, run this command: kubectl apply -f nfs-pvol.yaml
To claim the storage space for the volume, run this command: kubectl apply -f nfs-pvc.yaml
After those commands above have run successfully, let’s confirm that the Volume and VolumeClaim are attached as expected by running the following command:
kubectl get pv,pvc
Note: The yellow highlighted text in the screenshot above shows that the persistentvolume/nfs-pvol of 5Gi is bound and claimed by the persistentvolumeclaim/nfs-pvc of 5Gi; and that the access mode is RWX (Access Modes – RWS is not highlighted in the screenshot).
Update the MS-SQL .yaml file
The next step is to update the MS-SQL .yaml file to use the NFS path to store our databases.
From our last blog post in Part 2, we learned how to deploy the MS-SQL server. All that is required now is to modify the .yaml file to include the PersistentVolume, as shown below:
apiVersion: apps/v
kind: Deployment
metadata:
name: mssql-express
labels:
app: mssql-express
spec:
replicas: 1
selector:
matchLabels:
app: mssql-express
template:
metadata:
labels:
app: mssql-express
spec:
volumes:
– name: nfsvolume01
persistentVolumeClaim:
claimName: nfs-pvc
containers:
– name: mssql-express
image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
volumeMounts:
– name: nfsvolume01
mountPath: “/var/opt/mssql/data”
ports:
– containerPort: 1433
env:
– name: SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql-secret
key: mssql-password
– name: ACCEPT_EULA
value: ‘Y’
– name: MSSQL_PID
value: Express
If you examine that file above (same as on the previous blog post) you can notice several differences; they are:
volumes:
– name: nfsvolume01
persistentVolumeClaim:
claimName: nfs-pvc
In this first section, we instruct the deployment to use the volumeClaim, called: nfs-pvc, and assign a volume name: nfsvolume01. The second difference is:
volumeMounts:
– name: nfsvolume01
mountPath: “/var/opt/mssql/data”
In this part, we mount the volumeClaim name nfsvolume01 to the /var/opt/mssql/data, which is a path inside the pod OS. This path is the default path for MS-SQL databases and log files.
Put it all together
When I build my own application deployments, I like to consolidate all the .yaml files into one big file that includes all the application deployment configuration. For example, the following mssqldeployment.yaml file will deploy the MS-SQL application, and includes the following configuration steps:
- PersistentVolume configuration
- PersistentVolumeClain configuration
- SQL password Secret
- SQL Deployment
- SQL Service expose
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pvol
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
– ReadWriteMany
nfs:
server: 192.168.33.180
path: “/mnt/ProdNas/nfs”
—
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
storageClassName: manual
accessModes:
– ReadWriteMany
resources:
requests:
storage: 9Gi
—
apiVersion: v1
kind: Secret
metadata:
name: mssql-secret
type: Opaque
data:
mssql-password: UEBzc3cwcmQK
—
apiVersion: apps/v1
kind: Deployment
metadata:
name: mssql-express
labels:
app: mssql-express
spec:
replicas: 1
selector:
matchLabels:
app: mssql-express
template:
metadata:
labels:
app: mssql-express
spec:
volumes:
– name: nfsvolume01
persistentVolumeClaim:
claimName: nfs-pvc
containers:
– name: mssql-express
image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
volumeMounts:
– name: nfsvolume01
mountPath: “/var/opt/mssql/data”
ports:
– containerPort: 1433
env:
– name: SA_PASSWORD
valueFrom:
secretKeyRef:
name: mssql-secret
key: mssql-password
– name: ACCEPT_EULA
value: ‘Y’
– name: MSSQL_PID
value: Express
—
apiVersion: v1
kind: Service
metadata:
name: mssql-express-service
spec:
selector:
app: mssql-express
type: LoadBalancer
ports:
– protocol: TCP
port: 1433
targetPort: 1433
Summary
At the successful completion of the application deployment, we can create a database to check on the OS NFS mount point folder. If the database was created successfully, the newly created database should be alongside all the SQL default datebases, as shown in the following screenshot:
Following the two previous, and this Get Started with Kubernetes blog posts will help you get started with this great technology. It will assist you to build your application while you are learning the Kubernetes concepts.
In the next blog post, I will take you on a deep dive into each Kubernetes topic to give you a better understanding of the concepts and frameworks used in this and the two previous blog posts. Until then, I hope you have been able to follow the steps so far. Please let me know if you have any questions.