Video Thumbnail for Lesson
4.6: Job

Job

In Kubernetes, a Job creates one or more Pods and ensures that a specified number of them complete successfully.

Jobs are used for short-lived, one-time tasks such as batch processing and other short-lived operations.

Official docs: https://kubernetes.io/docs/concepts/workloads/controllers/job/

Hands-On: Working with Jobs

We will create and examine a Job to understand it's behavior.

1. Create a Namespace for the Examples

First, we'll create a namespace for these examples and set it as the default.

# task 01-create-namespace
# - Create a namespace for these examples and set as default
kubectl apply -f Namespace.yaml
kubens 04--job

2. Apply the Standalone Pod Configuration

Unlike the nginx container we have been using so far which executes as a long-running process and is not expected to terminate, in the case of a Job the container is expected to terminate.

To demonstrate this, we can use a pod running the busybox image (a small linux distro with a variety of utilities included) and run the command date. This will log the date to stdout and then exit.

apiVersion: v1
# Pod.echo-date-minimal.yaml
kind: Pod
metadata:
  name: echo-date-minimal
spec:
  containers:
    - name: echo
      image: busybox:1.36.1
      command: ["date"]
  restartPolicy: Never

Note that we specify restartPolicy: Never to ensure kubernetes does not attempt to restart the pod after it exits.

# task 02-apply-minimal-pod
# - Apply the standalone Pod configuration.
kubectl apply -f Pod.echo-date-minimal.yaml
❯ kubectl get pods
NAME                READY   STATUS      RESTARTS   AGE
echo-date-minimal   0/1     Completed   0          6s
❯ kubectl logs echo-date-minimal
Tue Jul  2 13:35:36 UTC 2024

This worked fine, but if the container had failed, Kubernetes would not have retried it.

3. Apply the Job Configuration

By using a Job resource, we can specify how many completions are desired, how many pods can run in parallel, and how many times Kubernetes should attempt to retry upon encountering failures.

apiVersion: batch/v1
kind: Job
metadata:
  name: echo-date-better
  namespace: 04--job
spec:
  parallelism: 2
  completions: 2
  activeDeadlineSeconds: 100
  backoffLimit: 1
  template:
    metadata:
      labels:
        app: echo-date
    spec:
      containers:
        - name: echo
          image: busybox:1.36.1
          command: ["date"]
      restartPolicy: Never

As you can see, the spec.template.spec field matches that of our standalone pod, but for the job we have additional configuration options:

  • parallelism: Specifies the maximum number of pods that can run in parallel. Here, it's set to 2.
  • completions: Specifies the number of successful completions needed for the job to be considered complete. Here, it's set to 2.
  • activeDeadlineSeconds: Specifies the duration in seconds after which the job will be terminated if not completed. Here, it's set to 100 seconds.
  • backoffLimit: Specifies the number of retries before marking the job as failed. Here, it's set to 1.
# task 04-apply-better-job
# - Apply the better Job configuration.
kubectl apply -f Job.echo-date-better.yaml

5. Delete the Namespace to Clean Up

Finally, clean up by deleting the namespace, which will also delete all resources within it.

# task 05-delete-namespace
# - Delete the namespace to clean up.
kubectl delete -f Namespace.yaml