Kubernetes provides a great way to run modern infrastructure. SQL server is a widely deployed database. When you combine these two, you get a robust way of running a data pipeline using a modern platform.
Data pipelines are large part of all data infrastructure. The need to move data between different systems, is almost universal and tools/process to achieve this is generally referred to as a data pipeline. In this post we will see how we can leverage Kubernetes jobs API to build and run data pipelines. This is a great way to integrate data pipelines into CI/CD practices too.
Following steps will create an example SQL pipeline and run it against SQL server using Kubernetes. We will be running a very simple query to list all the tables.
Lets define our job in the file
sql-k8s-job.yaml
.apiVersion: batch/v1 kind: Job metadata: name: sqljob spec: template: spec: containers: - name: sqljobcontainer image: microsoft/mssql-tools command: ["/opt/mssql-tools/bin/sqlcmd"] args: [ "-S", "mysqlserver.database.windows.net", "-d", "mydatabase", "-U", "User", "-P", "PassWord", "-I", "-Q", "SELECT name FROM sys.tables" ] restartPolicy: Never
Here, we are specifying that this is a job definition(
kind: Job
) with the namesqljob
. The spec part is similar to other container specifications. We are specifying it to create a container with a namesqljobcontainer
with the imagemicrosoft/mssql-tools
. This image has all MSSQL tools installed to connect to a remote MSSQL instance. We are also specifying that it should runsqlcmd
command with the specified arguments, including server, database, password and query when it starts the container. Note that, I am specifying password in the job definition file here just for simplicity, you should use kubernetes secrets when doing anything serious.Lets run it. You can run it locally using minikube or on cloud.
kubectl create -f sql-k8s-job.yaml job "sqljob" created
You can see the details on the job.
kubectl describe jobs/sqljob Name: sqljob Namespace: default Selector: controller-uid=85530e4e-2eef-11e8-9e3f-92f68014defe Labels: controller-uid=85530e4e-2eef-11e8-9e3f-92f68014defe job-name=sqljob Annotations: <none> Parallelism: 1 Completions: 1 Start Time: Fri, 23 Mar 2018 16:11:30 -0700 Pods Statuses: 1 Running / 0 Succeeded / 2 Failed Pod Template: Labels: controller-uid=85530e4e-2eef-11e8-9e3f-92f68014defe job-name=sqljob Containers: sqljobcontainer: Image: microsoft/mssql-tools Port: <none> Command: /opt/mssql-tools/bin/sqlcmd Args: -S mysqlserver.database.windows.net -d mydatabase -U User -P PassWord -I -Q SELECT name FROM sys.tables Environment: <none> Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 30s job-controller Created pod: sqljob-qsdtg Normal SuccessfulCreate 20s job-controller Created pod: sqljob-pws2m Normal SuccessfulCreate 10s job-controller Created pod: sqljob-lb2dz
You can also see the job on the kubernetes dashboard. You can open the kubernetes dashboard using
minikube dashboard
You can see the job under jobs section in the dashboard.
Lets see the output from the job.
kubectl logs jobs/sqljob
You should see the list of all the tables in your database.
Finally you can delete the job using
kubectl delete jobs/sqljob job "sqljob" deleted
Now that you have are comfortable with this job, you can easily convert this into a recurring job. Kubernetes jobs support for cron jobs. You can include the cron syntax schedule in the container spec to convert a job into a cron job. For example, by including
schedule: "0 * * * *"
in thespec
section of the job, your job will run every 1-hour. Crontab syntax is hard to remember and undertstand, but luckily you can just use crontab.guru.
Thats it. Go build your pipeline !