What is a Kubernetes CronJob: Types, Key Settings & Tools
“I just love doing tedious, repetitive tasks” is not something you’ll ever hear Kubernetes admins say. And luckily for them, carrying out repetitive tasks manually isn’t necessary thanks to Kubernetes CronJobs, which make it easy to automate the process. That said, like many components of Kubernetes, CronJobs can be complex, which is why it’s important to understand how to set them up effectively – not to mention how to troubleshoot CronJobs when something goes awry.
Keep reading for tips on all of the above as we explain how a Kubernetes CronJob works, how to configure one, how to manage CronJobs, and best practices for getting the most from CronJobs in a Kubernetes cluster.
What is a Kubernetes CronJob?

A Kubernetes CronJob is an action that Kubernetes automatically performs at a scheduled time. Usually, CronJobs run on a recurring, repetitive basis. For example, an admin might configure a CronJob to execute once per hour or once per day.
CronJobs are a type of Kubernetes object and are executed by the Kubernetes job scheduler. Like other objects, you can define them using YAML code. Here’s a simple example of a CronJob in Kubernetes:
This tells the cronjob controller to execute the command /bin/sh -c echo Hello from Kubernetes at $(date) every minute. Here are the details of what’s happening in this example:
- The schedule is set in the schedule field under the CronJob’s spec (we’ll explain more in a moment about how the schedule definitions work).
- The job runs by launching a container named hello, which is based on an image named busybox.
- The command and arguments to run are defined under args.
CronJobs in Kubernetes are so-called because they’re similar to cron jobs in Linux and other Unix-like operating systems. On those systems, admins can use cron jobs to tell the operating system to execute commands or scripts based on a preset schedule. CronJobs in Kubernetes extend a similar concept to the world of containers and container orchestration.
Why are Kubernetes CronJobs important?
Since we just told you that Kubernetes CronJobs basically emulate the cron job functionality that is built into Linux, you might be wondering why you’d want to set up a Kubernetes CronJob in the first place instead of just using the cron utility that comes with your host servers’ operating system.
The answer is that CronJobs in Kubernetes help you do a variety of things that would be challenging to achieve using an operating system’s cron features:
- Running jobs in a cluster on a schedule: For starters, CronJobs in Kubernetes let you execute tasks within a Kubernetes cluster on a fixed schedule. This means that regardless of how each node in your cluster is configured or which tools are installed on each node, you can run jobs within the cluster at whatever intervals you require.
- Saving cluster resources: Because CronJobs only consume resources when they’re running, they help to avoid wasting cluster resources. Without CronJobs, you’d have to have a Deployment or a similar resource running (and consuming resources) continuously, even if it’s only active part of the time.
- Reliable job timing in busy systems: CronJobs execute independently of other types of Kubernetes resources. This helps to ensure that they will reliably execute at the scheduled time. This is another advantage over Deployments or similar resources, which run a higher risk of being delayed when executing tasks due to issues like resource constraints or pod pending problems.
Types of Kubernetes CronJobs and key settings
CronJobs in Kubernetes call into several distinct categories based on how they are configured. Here’s a look at the main types.
#1. Regularly scheduled CronJobs
The simplest type of Kubernetes CronJob is one that runs on a preset schedule, without other constraints or variables. The schedule is configured in the spec field of the CronJob. Here’s an example:
Notice that there are five space-separated columns defined in this schedule. Each column corresponds to a different unit of time:
- Column one represents minutes of the hour.
- Column two is for hours of the day.
- Column three refers to the day of the month.
- Column four is for the month of the year.
- Column five is for the day of the week.
So, in this example, the CronJob settings tell Kubernetes to execute at 12:01 a.m. every day. Cron in Unix-like operating systems uses this same multi-column format to define job schedules – so if it seems confusing, complain to Unix developers, not Kubernetes developers…
Regularly scheduled CronJobs are ideal for tasks that need to occur regularly, without any other conditions factored in. Common examples include data backups or cleanup operations, which might take place once every day or week.

2. CronJobs with concurrency policies
Optionally, CronJobs can include concurrency policies. These tell Kubernetes what to do if a new job is scheduled to start but the previous one hasn’t completed yet – which could happen if, for example, you use CronJobs to run hourly data backups, but your data becomes so large in scope that it takes more than an hour to complete each backup.
You can choose from one of three options when setting up a concurrency policy:
- Allow, which tells the cronjob controller to run the new job even if a currently running job is still active.
- Forbid, which prevents the new job from running until the previous job run finishes.
- Replace, which stops the existing job and starts the new one in its place.
You define a concurrency policy in the spec field of a CronJob. Here’s an example that configures a Forbid policy:
Concurrency policies are useful because they provide a way of preventing multiple concurrent jobs, which could waste resources or, in an extreme case, cause your cluster to crash. At the same time, however, they provide the flexibility to ensure that multiple jobs will run at the same time if necessary.
3. CronJobs with history controls
You can also optionally configure history controls for Kubernetes CronJobs. History controls define how many records from previous job runs Kubernetes should keep on hand. You can set requirements for both successful job run records (using the successfulJobsHistoryLimit variable) and failed jobs (using failedJobsHistoryLimit). A failed job is one that doesn’t run successfully; for example, if the CronJob skips a job because concurrency policies prevent it from running, it would count as a failed job.)
Here again, you use the CronJob spec field to define history controls. For example:
This keeps 5 records on hand for successful jobs and 2 for failed jobs.
History controls are useful mainly because they help prevent Kubernetes from wasting resources storing previous job run records. Without controls, Kubernetes may try to retain a record of every successful and failed job, which can add up over time and become a burden on etcd (which is where job records are stored).
In addition, retaining a certain number of previous job run records can be important for auditing and compliance purposes. Regulatory requirements may mandate that you keep records on hand for tracing what occurred in a Kubernetes cluster, including CronJob operations.
Advanced CronJob timing rules
Beyond the types of CronJob settings we just explored, there are some advanced timing configurations that are useful to know about:
- Cron expressions: As we mentioned above, CronJob schedules use a five-column format to define when a job should run. You can use wildcard characters in any of these columns. An asterisk (*) matches all values – so a setting of * * * * * would tell Kubernetes to run a job at every minute of every hour of every day. You can also use a comma (,) to define a list of multiple values for a single column. Kubernetes CronJobs support ranges using the range (-) operator as well.
- Time zone-specific scheduling: By default, most Kubernetes distributions use Universal Coordinated Time (UCT) as their timezone – so if you schedule a task to run at midnight, for example, it will run at midnight UTC time. If you want to use a different timezone, you can configure one using the timeZone variable within a job’s spec. For example, timeZone: "America/New_York" would set the timezone to New York time.
Real-life examples of Kubernetes CronJobs at work
To illustrate how you might use a CronJob in the real world, let’s take a look at a couple of examples.
Daily data backup
Imagine you want to back up data stored in data volumes within your Kubernetes cluster. You could do so by creating a CronJob like the following:
This runs a tar command once per day to copy data from a volume mount named data-storage to one named backup-storage. It has a Forbid concurrency policy, which prevents overlapping backup operations.
Weekly cluster performance reporting
As another example, imagine that you want to generate a report each week that summarizes your Kubernetes cluster’s performance. You could do it using a CronJob like this:
This CronJob executes various commands that collect data about cluster performance (such as summaries of node and pod status, as well as resource consumption data), then writes it to a text file stored on a data volume named reports. This would be a handy way of automatically reporting on the status and performance of a cluster.
How to set up a Kubernetes CronJob in simple steps
Defining a CronJob is simple enough. Here are the key steps.
Step 1: Create a CronJob template
Start by creating a template for your CronJob. You can do this by opening a text file and adding the header data that tells Kubernetes that the object being defined is a CronJob. Specifically, you’d add these lines:
Step 2: Name your CronJob
Next, give your Job a name using the CronJob metadata field. For example:
Step 3: Set a schedule
Now you can set a schedule by creating a spec section for your CronJob and adding the schedule field. Again, you use the five-column cron format for defining a schedule. Here’s an example that runs a job every day at midnight:
Step 4: Specify a container
You also need to tell Kubernetes which container to launch when running the CronJob. You can do this using a jobTemplate section. For instance:
This runs a container named example-container based on the image some-image.
Step 5: Specify a command
Next, define the command or commands you want Kubernetes to execute when running the job. These are standard Linux or Unix command-line commands, and they go under the jobTemplate section. For example:
Although it’s possible to squeeze the entire command into one line, it’s best practice to create different lines for the command and corresponding arguments. This helps keep the template more readable.
Step 6: (Optional) Define concurrency rules and history controls
If desired, you can also set concurrency rules and history controls for your CronJob. See above for details on using these.
Step 7: Deploy the CronJob
After generating all of the configuration data for your CronJob, the last step is to deploy it. Do this by saving the CronJob template to a file (such as my-cronjob.yaml), then using kubectl to apply it to the cluster with:
You can verify the state of a deployed CronJob using the command kubectl get cronjobs.
Tools for managing Kubernetes CronJobs
To work effectively with CronJobs in Kubernetes, it helps to familiarize yourself with a few key tools.
Kubectl
First, you’ll need kubectl, the primary command-line administration tool for Kubernetes. As we just showed, you use kubectl to deploy CronJobs. You can also use it to check the status of running CronJobs.
Helm for automated CronJob deployment
While you don’t strictly need Helm to deploy CronJobs, it can be a handy way of automating CronJob installation. This is possible because Helm charts can include CronJob specifications.
CronJob monitoring utilities
Some Kubernetes monitoring utilities allow you to track the status of CronJobs and quickly collect more details than you could conveniently pull using kubectl alone. Popular examples include K9s (a monitoring tool for the terminal) and Lens (which provides a graphical interface that includes an overview of CronJobs).
Monitoring with Prometheus and Grafana
For even more detail and context about CronJob status, open source monitoring tools like Prometheus and Grafana are useful. While these aren’t designed for CronJob monitoring specifically, they can provide a variety of data points and visualizations that are useful for understanding the overall status of a cluster and the state of CronJobs running within it.
Deep visibility with groundcover
For the deepest level of visibility into CronJob status and overall cluster health and performance, a tool like groundcover is vital. By comprehensively monitoring all components of your cluster in real time, groundcover doesn’t just clue you into issues like failed CronJobs or jobs that are wasting resources. It also provides the context you need to troubleshoot and resolve CronJob errors.
How to troubleshoot Kubernetes CronJobs
If a CronJob doesn’t run as expected, you can troubleshoot the issue by working through common causes of CronJob failures, including:
- Concurrency settings: If a concurrency policy is in place, it might have prevented a CronJob from starting because a preceding one hadn’t finished yet. In that case, either figure out why the first job is taking so long to run, or (if it actually needs a long time) change the schedule to allow longer intervals between jobs.
- Image pull errors: Since each CronJob requires a container image, ImagePullBackOff and similar image-related issues can prevent a job from running. If this happens, make sure that the container image and registry names are properly spelled. Be sure, too, that your cluster can connect to the registry.
- Resource constraints: A CronJob could fail to run if a cluster is so starved of resources that Kubernetes can’t start the container necessary to run the job. The solution here is to free up cluster resources.
- Buggy commands: If the commands specified in the CronJob template contain typos or call buggy utilities, the CronJob will fail to execute. To fix this issue, fix the commands.
- Commands not available: Along similar lines, if you specify a CronJob command that requires a utility that isn’t available within the associated container, Kubernetes won’t be able to run it. Be sure that any commands you run are actually supported by the container image you plan to use. For clarity’s sake, note that Kubernetes CronJobs execute commands inside containers, not host nodes, so any utilities you want to run need to be available inside the container that is deployed as part of the CronJob. For CronJob purposes, it doesn’t matter which utilities are installed on your cluster’s host servers.
Best practices for managing CronJobs
To get the most from Kubernetes CronJobs, consider the following best practices.
Track job status and output logs
Rather than assuming that your jobs will always run reliably, ensure that you have visibility into job status. Use kubectl get cronjobs to check on active jobs, and view output logs (which your CronJob containers should be configured to produce) to verify the output of job runs.
Use resource requests and limits properly
It’s possible to specify job resource requests and limits within a CronJob’s jobTemplate. These can be useful for preventing jobs from consuming excessive resources and disrupting other workloads. However, be sure to provide enough resources so that the job can run properly.
Label jobs
To help keep track of jobs and document their purpose, consider using labels and annotations to categorize them. These descriptors help to ensure that no matter who is managing the cluster, they’ll be able to identify each job. Labels are also useful for identifying jobs that are no longer necessary and can be deleted.
Generate alerts on CronJob failures
By default, Kubernetes won’t explicitly alert you about CronJob failures. However, you can set up an alerting mechanism by enabling kube-state-metrics in your cluster, then configuring an alert whenever the metrics record a CronJob problem.
Secure secrets and sensitive configurations
As with any other type of Kubernetes resource, CronJobs have the potential to expose sensitive data to unauthorized parties if they handle secrets improperly. Be sure to follow secrets management best practices, such as avoiding the “hard-coding” of secrets in plain text, when working with CronJobs.
Optimizing Kubernetes CronJob performance
In addition to managing CronJobs effectively, it’s also important to optimize CronJob performance by minimizing the resources CronJobs consume, as well as the time they take to run. One key step in this direction is ensuring that you only run CronJobs when necessary. Just because you can run a job every minute or hour doesn’t mean you should. To avoid unnecessary resource usage, only run jobs when you actually need them to run.
It also helps to choose a minimalist container image when running a job. In general, the container should provide only the utilities necessary to support the CronJob. Anything extra leads to wasted resources. Likewise, when specifying a CronJob’s commands, avoid calling utilities that you don’t need. Sweet and simple leads to better CronJob performance.
Finally, it’s best practice to avoid scheduling multiple jobs in the same time window. Spacing them out will reduce the load that CronJobs place on your cluster. That said, you should also avoid running jobs at times when your cluster is likely to be under heavy load for other reasons. For example, if your cluster hosts an application that receives much more traffic during the day than at night (in whatever the cluster’s default timezone is), you’d want to schedule CronJobs during nighttime if possible.
How groundcover helps with Kubernetes CronJobs
As a comprehensive, real-time Kubernetes monitoring and observability solution, groundcover delivers the visibility admins need to monitor CronJobs, track CronJob performance, and troubleshoot issues when they arise.
.png)
Plus, because groundcover uses eBPF as the foundation for data collection, it places much less load on your clusters than traditional Kubernetes monitoring tools – which you have more resources to devote to your CronJobs and other workloads, and less overhead wasted on monitoring.
Making life simpler with CronJobs
Setting up CronJobs in Kubernetes is certainly not a requirement. But if you want to avoid toil and tedium, configuring CronJobs is well worth the effort. Just be sure that you’re ready to monitor your CronJobs effectively, too, and extend your Kubernetes troubleshooting strategy to CronJobs – because a failed CronJob is worse than having no CronJob at all.


