Kubernetes – Jobs and CronJobs

Kubernetes – Jobs and CronJobs

December 16, 2019 1 By Eric Shanks

Sometimes we need to run a container to do a specific task, and when its completed, we want it to quit. Many containers are deployed and continuously run, such as a web server. But other times we want to accomplish a single task and then quit. This is where a Job is a good choice.

Jobs and CronJobs – The Theory

Perhaps, we need to run a batch process on demand. Maybe we built an automation routine for something and want to kick it off through the use of a container. We can do this by submitting a job to the Kubernetes API. Kubernetes will run the job to completion and then quit.

Now, thats kind of handy, but what if we want to run this job we’ve automated at a specific time every single day. Maybe you need to perform some batch processing at the end of a workday, or perhaps you want to destroy pods at the end of the day to free up resources. There could be a myriad of things that you’d like to be done at different times during the day or night.

A Kubernetes CronJob lets you schedule a container to be run at a time, defined by you, much the same way that a linux server would schedule a cron job. Think of the CronJob as a Job with a schedule.

Jobs and CronJobs – In Action

First, we’ll deploy a simple job that will run curl against this blog just to see if it will work. I’ve created a simple alpine container with the curl installed on it. We’ll use this container image to run curl against this site. The manifest below will create our simple curl job.

apiVersion: batch/v1
kind: Job
metadata:
  name: hollow-curl
spec:
  template:
    spec:
      containers:
          - name: hollow-curl
            image: theithollow/hollowapp-blog:curl
            args:
            - /bin/sh
            - -c
            - curl https://theithollow.com
      restartPolicy: Never
  backoffLimit: 4Code language: JavaScript (javascript)

Apply the job manifest with the following command:

kubectl apply -f [job manifest file].ymlCode language: CSS (css)

Once the job has been submitted, we can see that a job was run by running a “get” on the job object. We can see that a job was run and how long it took.

To go a bit deeper, we can run a describe on our job to see additional details about it. Some interesting information is shown below for the job I submitted to my cluster.

According to the events, we can see that our job completed successfully already. Next, lets just check if there are any pods deployed. Sure enough, a pod was deployed and it has a status of completed.

Now, what if we want to run the same job on a set schedule? For this example, we’ll create a simple CronJob that will run curl against this blog at the top of the hour. We can pretend that we’re checking uptime on the website if we want it to feel more like a real world example, but your cron job could execute anything you could dream up and drop into a container.

Let’s build a manifest file to deploy a CronJob with the appropriate schedule, which in this case will be every hour, at the top of the hour. The manifest to create this CronJob is shown below.

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hollow-curl
spec:
  schedule: "0 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hollow-curl
            image: theithollow/hollowapp-blog:curl
            args:
            - /bin/sh
            - -c
            - curl https://theithollow.com
          restartPolicy: OnFailureCode language: JavaScript (javascript)

Deploy the CronJob by running:

kubectl apply -f [manifest file name].ymlCode language: CSS (css)

Once deployed, we can check to see if we can list the CronJob by running a “get” on the cronjob object.

Now, at the top of the hour, we should be able to run this again and see that its been run successfully. In my case, I ran a –watch so that I could see what happened at the top of the hour. We can see that it went from not scheduled, to active, to completed.

Summary

Jobs and CronJobs may seem like a really familiar solution to what we’ve done to run batch jobs for many years. Now we can take some of our jobs that were stored on servers and replace them with a container and drop those in our Kubernetes cluster as well. Good luck with your jobs!