Kubernetes 101: Jobs and CronJobs

Cron is a long-standing feature of Unix-like operating systems, which provides a mechanism to schedule scripts or commands execution at specific intervals.

Kubernetes 101: Jobs and CronJobs
Source: https://learnbatta.com/

Introduction

Cron is a long-standing feature of Unix-like operating systems, which provides a mechanism to schedule scripts or commands execution at specific intervals. It uses a simple text-based configuration file to set up timed jobs and is used in many server environments for tasks like log rotation and system maintenance.

Kubernetes, as a modern and extensible platform, includes similar functionality but adapted for distributed systems scenarios. CronJobs are one of the resource types in Kubernetes, which manage time-based jobs and run them on a regular schedule.

Cron Syntax

The cron syntax forms the basis of how we define schedules in CronJobs in Kubernetes. It's important to understand how the syntax works in order to be able to create the schedules you need. A basic cron expression consists of five fields separated by white space that represent:

  1. Minute in the hour (0 - 59)
  2. Hour in the day (0 - 23)
  3. Day of the month (1 - 31)
  4. Month in the year (1 - 12)
  5. Day of the week (0 - 7) where both 0 and 7 represent Sunday

Each of these fields can have a specific value, a range, a set of values, or an asterisk which represents all possible values. Let's break these down:

  1. Specific Value: If you wanted your job to execute at the 30th minute of every hour, your cron expression would be 30 * * * *.
  2. Range: If you wanted your job to execute on the first minute of every hour from 8 AM to 5 PM, your cron expression would be 0 8-17 * * *.
  3. Set of Values: If you wanted your job to execute at the first minute of the hour at 8 AM, 12 PM, and 5 PM, your cron expression would be 0 8,12,17 * * *.
  4. All Values (asterisk): If you wanted your job to execute every minute, your cron expression would be * * * * *.

In addition, there are also special characters that can be used:

  1. The Comma (,): Allows you to specify a list of values or ranges. For example, 1,2,5 * * * * would mean "at minutes 1, 2, and 5".
  2. The Hyphen (-): Allows you to specify a range of values. For example, 1-5 * * * * would mean "every minute between minute 1 and 5".
  3. The Asterisk (*): Represents all possible values for a field. For example, * * * * * would mean "every minute of every hour of every day of the month of every month".
  4. The Slash (/): Allows you to specify values that are stepped by a certain amount. For example, */15 * * * * means "every 15 minutes".

It's worth noting that these syntax rules can be combined in a single field to create complex expressions. For instance, 1-5,*/15,30-45 * * * * would mean "every minute between minute 1 and 5, every 15 minutes, and every minute between minute 30 and 45".

The Role of CronJobs in Kubernetes

Source: https://cronitor.io/

CronJobs in Kubernetes create Jobs (a Kubernetes resource type used for run-to-completion tasks like batch processing) on a time-based schedule. The schedule is defined in the Cron format, enabling a high degree of flexibility in specifying when the job should be run.

CronJobs can be used for running regular maintenance tasks, backups, sending notifications, data processing, and more. Essentially, any task that you need to run regularly can be packaged into a Docker container and run as a CronJob on Kubernetes.

When to Use CronJobs

  • Regularly Scheduled Tasks: CronJobs are best suited for jobs that need to run on a regular, predictable schedule. This can range from system maintenance tasks like cleanup and backup to data processing tasks that need to run during low traffic times.
    Example: Suppose you have an e-commerce website and want to generate a report of all the transactions at the end of the day when the traffic is low. You can use a CronJob to schedule this reporting job to run late at night every day.
  • Polling: If you need to periodically check an external service for updates, CronJobs can be a good fit.
    Example: In a microservices architecture, if a service needs to verify the status of a remote API endpoint periodically, a CronJob can be set to hit that endpoint at fixed intervals.
  • Notifications and Reminders: If you need to send notifications or reminders at certain times of the day or week, you can use CronJobs to schedule these tasks.
    Example: If you have a service that sends weekly newsletters to your users, a CronJob can be set up to run this service every week at a specified time.

When Not to Use CronJobs

  1. Short, Frequent Jobs: Kubernetes has some overhead in scheduling and running jobs, so if you have a job that needs to run very frequently (like every few seconds), a CronJob might not be the best choice. A continuously running service that manages its internal timing could be more suitable in this case.
  2. Non-periodic, Trigger-based Jobs: If your jobs need to run based on certain events or triggers (e.g., a new file appearing in a directory, or a message arriving on a queue), CronJobs may not be the best fit. Instead, event-driven architectures or workflows should be used.
  3. Long Running or Continuous Jobs: CronJobs are intended for jobs that run to completion. For long-running or continuous tasks that don't have a clear end, such as a web server, CronJobs are not suitable. In these cases, using other Kubernetes resources like Deployments or StatefulSets would be more appropriate.
  4. Jobs with Complex Dependencies: If you have jobs with complex dependencies, where one job must complete before another begins, and these relationships can't easily be expressed with the Cron syntax, you might need a more sophisticated workflow management system. Tools like Apache Airflow or Argo are designed for these types of workflows.

Remember, the use of CronJobs (or any other technology) always depends on the specific requirements of your application and your infrastructure. It's important to understand these details before deciding on the appropriate tools and technologies to use.

Example of CronJobs Manifest

Let's use this basic CronJob manifest as an example:

Here's the breakdown of each part of this CronJob manifest:

  • apiVersion: This defines the Kubernetes API version which is used to create this object. The batch/v1beta1 is currently the API version used for defining CronJobs.
  • kind: This is the kind of Kubernetes resource we want to create. In this case, it's a CronJob.
  • metadata: This section is used to name our CronJob and could also include other metadata such as labels and annotations.
  • spec: This section is used to define the behavior of our CronJob.
       schedule: This is where we use the cron syntax to define when the job should be run. In this case, "*/1 * * * *" means the job will run every minute.
       jobTemplate: A CronJob creates Job resources, and this is the template for those Jobs. The spec under jobTemplate defines how the job runs.
  • spec.template: This is a pod template, it describes the desired state for the pod created by this job.
       spec.containers: This is an array of containers that will run in the pod. In this case, we only have one container.
       name: This is the name that is given to the container.
       image: This is the Docker image that is used to create this container. In this case, it's busybox, a minimal Unix-like operating system.
       args: These are arguments that are passed to the container at runtime. Here we pass a shell command to print the date and a message.
  • restartPolicy: This is the restart policy for all containers within the pod. The possible values are Always, OnFailure, and Never. Here, if the container fails for any reason, Kubernetes will try to restart it.

This CronJob will run a job every minute. Each job will start a pod with a single container running the busybox image, and will print the date and a message to the console.

Remember that the specific contents of the spec will depend on the specific needs of your job. The above is a relatively simple example, and real-world jobs might include more complex container specifications, multiple containers, or additional elements such as volumes.

Introduction to Jobs

Jobs in Kubernetes are a type of controller used to manage a desired task until it completes successfully. Unlike Pods or Deployments, which are designed to run continuously, Jobs are designed to run to completion. This means that Jobs are ideal for tasks that need to run once or a set number of times, but not indefinitely.

Use Cases for Kubernetes Jobs

Kubernetes Jobs are particularly useful for running tasks that are expected to exit once they have completed their work. Here are some examples:

  • Batch Processing: Jobs are great for batch processing tasks. For example, if you need to process a large dataset, you might create a Job that processes a portion of the data. You could then create multiple Jobs to process the entire dataset in parallel.
  • Scheduled Tasks: Although for tasks that need to be run on a regular schedule, a CronJob (which creates Jobs based on a schedule) is usually a better fit, a Job can be used in conjunction with external scheduling mechanisms.
  • System Maintenance: You might need to run system maintenance tasks like database migrations, cleaning up old logs or data, or taking backups. Jobs can be an excellent fit for these tasks, as they will run to completion and then stop.

CronJobs and Jobs

A Job in Kubernetes is a controller that is designed to carry out a task until it completes successfully. When a specified number of tasks have completed successfully, the Job is complete. Essentially, a Job creates one or more Pods and ensures that a specified number of them successfully terminate. As Pods complete, the Job tracks the successful completions.

A CronJob is essentially a Job with a schedule. The CronJob controller in Kubernetes creates Jobs on a repeating schedule, like once every hour or once a day, etc. It's named after the Unix utility 'cron' that accomplishes the same task. So, a CronJob manages Jobs on a time-based schedule. It creates Job objects, and it is these Job objects that spawn the Pods to carry out the actual tasks.

To summarize, a Job runs to completion (i.e., until the task is done), while a CronJob is a time-based Job scheduler, creating Jobs according to a schedule. Both of them are meant to carry out tasks, but a CronJob does this on a schedule, while a Job does it until a task is completed. The relationship is such that the CronJob creates Job resources, and it's these Job resources that actually carry out the tasks in Pods.

Job Manifests

A Kubernetes Job is defined using a manifest, which is a YAML document that describes the desired state for the Kubernetes object. Here is a basic example of a Job manifest:

Let's break this down:

  • apiVersion: This defines the Kubernetes API version which is used to create this object. The batch/v1 is currently the API version used for defining Jobs.
  • kind: This is the kind of Kubernetes resource we want to create. In this case, it's a Job.
  • metadata: This section is used to name our Job and could also include other metadata such as labels and annotations.
  • spec: This is the specification of our Job.
       spec.template: This is the template that will be used to create the pods that the job manages. It is of PodTemplateSpec type and its structure is the same as a pod’s specification.
           spec.containers: This is an array of containers that will run in the pod. In this case, we only have one container.
               name: This is the name that is given to the container.
               image: This is the Docker image that is used to create this container. In this case, it's busybox, a minimal Unix-like operating system.
               command: This is the command that will be run when the container starts. Here we just echo a simple string.
           restartPolicy: This is the restart policy for all containers within the pod. For Jobs, the allowed values are OnFailure and Never. Here, if the container fails for any reason, Kubernetes will not try to restart it.

About 8grams

We are a small DevOps Consulting Firm that has a mission to empower businesses with modern DevOps practices and technologies, enabling them to achieve digital transformation, improve efficiency, and drive growth.

Ready to transform your IT Operations and Software Development processes? Let's join forces and create innovative solutions that drive your business forward.

Subscribe to our newsletter for cutting-edge DevOps practices, tips, and insights delivered straight to your inbox!