Create a cronjob on a kubernetes cluster

3 min read | by Jordi Prats

The cronjob object haven't been GA until Kubernetes v1.21, even though the Job object have been GA for a long time. Let's take a look how it works:

$ kubectl create job demo --image nginx --dry-run=client -o yaml  | head -n1
apiVersion: batch/v1
$ kubectl create cronjob demo --image nginx --schedule="*/1 * * * *" -o yaml --dry-run=client | head -n1
apiVersion: batch/v1beta1

Using the kubectl we get how a cronjob yaml will look like. It is quite similar a what a deployment is since it has a spec.template that is also used for creating the actual pods that will actually execute the job:

$ kubectl create cronjob my-cronjob --image=busybox --schedule="*/1 * * * *" -o yaml --dry-run=client -- echo test
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  creationTimestamp: null
  name: my-cronjob
spec:
  jobTemplate:
    metadata:
      creationTimestamp: null
      name: my-cronjob
    spec:
      template:
        metadata:
          creationTimestamp: null
        spec:
          containers:
          - command:
            - echo
            - test
            image: busybox
            name: my-cronjob
            resources: {}
          restartPolicy: OnFailure
  schedule: '*/1 * * * *'
status: {}

Let's create an simple cronjob to check how it executes the job:

$ kubectl create cronjob demo-cronjob --image=busybox --schedule="* * * * *" -- echo test
cronjob.batch/demo-cronjob created

After waiting for a while we will be able to see the executions on the events section of a kubectl describe:

$ kubectl describe cronjob demo-cronjob 
Name:                          demo-cronjob
Namespace:                     default
Labels:                        <none>
Annotations:                   <none>
Schedule:                      * * * * *
Concurrency Policy:            Allow
Suspend:                       False
Successful Job History Limit:  3
Failed Job History Limit:      1
Starting Deadline Seconds:     <unset>
Selector:                      <unset>
Parallelism:                   <unset>
Completions:                   <unset>
Pod Template:
  Labels:  <none>
  Containers:
   demo-cronjob:
    Image:      busybox
    Port:       <none>
    Host Port:  <none>
    Command:
      echo
      test
    Environment:     <none>
    Mounts:          <none>
  Volumes:           <none>
Last Schedule Time:  Tue, 05 Jan 2021 21:07:00 +0100
Active Jobs:         <none>
Events:
  Type    Reason            Age    From                Message
  ----    ------            ----   ----                -------
  Normal  SuccessfulCreate  3m19s  cronjob-controller  Created job demo-cronjob-1609866240
  Normal  SawCompletedJob   2m58s  cronjob-controller  Saw completed job: demo-cronjob-1609866240, status: Complete
  Normal  SuccessfulCreate  2m18s  cronjob-controller  Created job demo-cronjob-1609866300
  Normal  SawCompletedJob   2m7s   cronjob-controller  Saw completed job: demo-cronjob-1609866300, status: Complete
  Normal  SuccessfulCreate  77s    cronjob-controller  Created job demo-cronjob-1609866360
  Normal  SawCompletedJob   67s    cronjob-controller  Saw completed job: demo-cronjob-1609866360, status: Complete
  Normal  SuccessfulCreate  16s    cronjob-controller  Created job demo-cronjob-1609866420
  Normal  SawCompletedJob   5s     cronjob-controller  Saw completed job: demo-cronjob-1609866420, status: Complete
  Normal  SuccessfulDelete  5s     cronjob-controller  Deleted job demo-cronjob-1609866240

To be able to get the execution log we will have to first describe the job that gets created:

$ kubectl describe job demo-cronjob-1609866420
Name:           demo-cronjob-1609866420
Namespace:      default
Selector:       controller-uid=81e2745e-0a73-49fa-8f01-890f9dafebda
Labels:         controller-uid=81e2745e-0a73-49fa-8f01-890f9dafebda
                job-name=demo-cronjob-1609866420
Annotations:    <none>
Controlled By:  CronJob/demo-cronjob
Parallelism:    1
Completions:    1
Start Time:     Tue, 05 Jan 2021 21:07:06 +0100
Completed At:   Tue, 05 Jan 2021 21:07:13 +0100
Duration:       7s
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=81e2745e-0a73-49fa-8f01-890f9dafebda
           job-name=demo-cronjob-1609866420
  Containers:
   demo-cronjob:
    Image:      busybox
    Port:       <none>
    Host Port:  <none>
    Command:
      echo
      test
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From            Message
  ----    ------            ----   ----            -------
  Normal  SuccessfulCreate  2m20s  job-controller  Created pod: demo-cronjob-1609866420-f4dv7
  Normal  Completed         2m14s  job-controller  Job completed

Then we can use kubectl logs to get the output of the pod that this cronjob creates, again we can see it on the events section:

$ kubectl logs demo-cronjob-1609866420-f4dv7
test

Posted on 20/01/2021