Detailed tutorial on Kubernetes cron job scheduler

Job resources run their pods immediately when you create the Job resource. But many batch jobs need to be run at a specific time in the future or repeatedly in the specified interval. In Linux- and UNIX-like operating systems, these jobs are better known as cron jobs. Kubernetes supports them, too.

A cron job in Kubernetes is configured by creating a CronJob resource. The schedule for running the job is specified in the well-known cron format, so if you’re familiar with regular cron jobs, you’ll understand Kubernetes’ CronJobs in a matter of seconds.

Advertisement

At the configured time, Kubernetes will create a Job resource according to the Job template configured in the CronJob object. When the Job resource is created, one or more pod replicas will be created and started according to the Job’s pod template, as you learned in the previous section. There’s nothing more to it.

 

Structure of scheduling CronJob

Let us first understand the basics of cron job. You can get the structure of different fields in crontab in /etc/crontab file:

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

Here I have taken an example cron job to help you understand the different field of crontab:

0   5     *     *     1     tar -zcf /var/backups/home.tgz /home/
  • The first section of a cron job, a 0 in this example, refers to the minute that the job will happen. Since 0 is used here, the minutes section is :00.
  • The next section is the hour; 5 in this case. Therefore, we can gather so far that the command will be run at 5:00 a.m. (cron uses military time).
  • The third section refers to the day of the month, but we have an asterisk (*) here. The asterisk, in this case, means that it doesn't matter what day of the month it is; just run it.
  • The fourth section is another asterisk. In this example, it means we don't care which month it is. So far, we have a command we want to run at 5:00 a.m., regardless of the date.
  • The fifth field is set to 1 in our example, and this field represents the day of the week. Since we have 1 here, it means that we want to run the command on Mondays. (Sunday would have been 0).
  • Finally, the command that we want to execute is listed.
  • If we put it all together, this line means we want to run the following command every Monday at 5:00 a.m:

 

Get details of CronJob in Kubernetes

First of all we need the KIND name for using the cron job with Kubernetes, so we can list the api-resources and look out for your Job KIND

[root@controller ~]# kubectl api-resources | grep -iE 'KIND|cron'
NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
cronjobs                          cj           batch                          true         CronJob

So we know that our KIND is CronJob, to get the apiVersion value of the CronJob type we can use:

 ~]# kubectl explain cronjob.spec
KIND:     CronJob
VERSION:  batch/v1beta1

...

Alternatively you can also use:

Advertisement
~]# kubectl explain cronjob.spec.schedule
KIND:     CronJob
VERSION:  batch/v1beta1

FIELD:    schedule 

DESCRIPTION:
     The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.

So we have the KIND and apiVersion value to create a cron job scheduler with Kubernetes.

 

Create CronJob in Kubernetes

Imagine you need to run the batch job from your previous example every 2 minutes. To do that, create a CronJob resource with the following specification.

[root@controller ~]# cat pod-cronjob.yml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: pod-cronjob
spec:
  schedule: "*/2 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: pod-cronjob
            image: busybox
            args:
            - /bin/sh
            - -c
            -  date; echo hello from k8s cluster
          restartPolicy: OnFailure

The highlighted section is the template for the Job resources that will be created by this CronJob where our defined task will run every 2 minutes.

Now to create a cronjob we use following command:

[root@controller ~]# kubectl create -f pod-cronjob.yml
cronjob.batch/pod-cronjob created

 

List available CronJob with Kubernetes

To get the list of available scheduled cron jobs with Kubernetes we will use:

[root@controller ~]# kubectl get cronjobs.batch
NAME          SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
pod-cronjob   */2 * * * *   False     0                  20s

 

Monitor status of CronJob in Kubernetes

Job resources will be created from the CronJob resource at approximately the scheduled time. The Job then creates the pods. Once a cronjob is started, you can first use kubectl get cronjobs.batch to list the available cron jobs. Now when the job is planned to be executed then you can use following command to get the LIVE runtime status:

[root@controller ~]# kubectl get jobs --watch
NAME                     COMPLETIONS   DURATION   AGE
pod-cronjob-1606577040   0/1                      0s
pod-cronjob-1606577040   0/1           0s         0s

Here as you see the first planned cronjob has started, you can get more details using following command where you can see that a new job pod-cronjob-1606577040-tnnb5 is started with current status as ContainerCreating:

[root@controller ~]# kubectl get pods -o wide
NAME                           READY   STATUS              RESTARTS   AGE     IP          NODE                   NOMINATED NODE   READINESS GATES
nginx                          1/1     Running             1          9h      10.44.0.1   worker-2.example.com   <none>           <none>
nginx-lab                      1/1     Running             1          9h      10.44.0.2   worker-2.example.com   <none>           <none>
pod-add-settime-capability     1/1     Running             1          8h      10.44.0.4   worker-2.example.com   <none>           <none>
pod-as-user-guest              1/1     Running             1          8h      10.44.0.3   worker-2.example.com   <none>           <none>
pod-cronjob-1606577040-tnnb5   0/1     ContainerCreating   0          7s      <none>      worker-1.example.com   <none>           <none>
pod-drop-chown-capability      1/1     Running             1          7h50m   10.44.0.5   worker-2.example.com   <none>           <none>
pod-privileged                 1/1     Running             1          8h      10.36.0.3   worker-1.example.com   <none>           <none>

In few seconds once the JOB is complete, you can see that the status of the respective job is shown as completed:

Advertisement
[root@controller ~]# kubectl get jobs --watch
NAME                     COMPLETIONS   DURATION   AGE
pod-cronjob-1606577040   1/1           12s        12s

Now similarly another job will start in another 2 minutes as planned in our kubernetes job scheduler:

[root@controller ~]# kubectl get jobs --watch
NAME                     COMPLETIONS   DURATION   AGE
pod-cronjob-1606577040   1/1           12s        109s
pod-cronjob-1606577160   0/1                      0s
pod-cronjob-1606577160   0/1           0s         0s

In some time once the job is executed, then the status should be again shown as completed for the respective Pod:

[root@controller ~]# kubectl get pods
NAME                           READY   STATUS      RESTARTS   AGE
nginx                          1/1     Running     1          9h
nginx-lab                      1/1     Running     1          9h
pod-add-settime-capability     1/1     Running     1          8h
pod-as-user-guest              1/1     Running     1          8h
pod-cronjob-1606577040-tnnb5   0/1     Completed   0          2m16s
pod-cronjob-1606577160-75xbm   0/1     Completed   0          15s
pod-drop-chown-capability      1/1     Running     1          7h52m

 

Delete Kubernetes Cron Job

To delete your cron job you can execute following syntax:

 ~]# kubectl delete cronjobs.batch <cron_job_name>

For example to delete our cron job here:

[root@controller ~]# kubectl delete cronjobs.batch pod-cronjob
cronjob.batch "pod-cronjob" deleted

 

Conclusion

In this Kubernetes Tutorial we learned about Kubernetes job scheduler for jobs that need to run sometime in the future can be created through CronJob resources. In normal circumstances, a CronJob always creates only a single Job for each execution configured in the schedule, but it may happen that two Jobs are created at the same time, or none at all. To combat the first problem, your jobs should be idempotent (running them multiple times instead of once shouldn’t lead to unwanted results). For the second problem, make sure that the next job run performs any work that should have been done by the previous (missed) run.

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment