Kubernetes Operations
Jobs and CronJobs
Not every workload should run forever. Jobs run work to completion, and CronJobs run Jobs on a schedule.
What this lesson covers
Deployments are for long-running services. Jobs and CronJobs are for work that runs to completion, either once or on a schedule.
- What a Job is
- What a CronJob is
- How Jobs differ from Deployments
- How to inspect completion status
- How to view logs from completed Pods
- How to run scheduled work safely
Field note:
Use Deployments for services that should keep running. Use Jobs for tasks that should finish.
Deployment vs Job
Deployment: Keep this application running. Job: Run this task until it completes successfully. CronJob: Run this task on a schedule.
Before you start
kubectl config current-context kubectl get nodes kubectl create namespace jobs-lab
Step 1: Create a simple Job
Create a file named:
simple-job-lab.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: simple-job-lab
namespace: jobs-lab
spec:
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: busybox:latest
command: ["sh", "-c", "echo Starting job; sleep 5; echo Job complete"]
kubectl apply -f simple-job-lab.yaml kubectl get jobs -n jobs-lab kubectl get pods -n jobs-lab
Step 2: Watch the Job complete
kubectl get jobs -n jobs-lab -w
Press Ctrl+C after the Job shows completion.
Step 3: View logs from the Job Pod
kubectl get pods -n jobs-lab kubectl logs <job-pod-name> -n jobs-lab
Step 4: Create a Job with completions
Create a file named:
completions-job-lab.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: completions-job-lab
namespace: jobs-lab
spec:
completions: 3
parallelism: 1
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: busybox:latest
command: ["sh", "-c", "echo Running one unit of work; sleep 3; echo Done"]
kubectl apply -f completions-job-lab.yaml kubectl get jobs -n jobs-lab -w
This Job needs three successful completions.
Step 5: Create a parallel Job
Create a file named:
parallel-job-lab.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: parallel-job-lab
namespace: jobs-lab
spec:
completions: 4
parallelism: 2
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: busybox:latest
command: ["sh", "-c", "echo Parallel work on $(hostname); sleep 5; echo Done"]
kubectl apply -f parallel-job-lab.yaml kubectl get pods -n jobs-lab kubectl get jobs -n jobs-lab
Step 6: Create a failing Job
Create a file named:
failing-job-lab.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: failing-job-lab
namespace: jobs-lab
spec:
backoffLimit: 2
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: busybox:latest
command: ["sh", "-c", "echo This job will fail; exit 1"]
kubectl apply -f failing-job-lab.yaml kubectl get jobs -n jobs-lab kubectl get pods -n jobs-lab kubectl describe job failing-job-lab -n jobs-lab
The backoffLimit controls how many retries Kubernetes attempts before considering the Job failed.
Step 7: Create a CronJob
Create a file named:
cronjob-lab.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-lab
namespace: jobs-lab
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: scheduled-worker
image: busybox:latest
command: ["sh", "-c", "date; echo Scheduled job ran"]
kubectl apply -f cronjob-lab.yaml kubectl get cronjobs -n jobs-lab
Step 8: Wait for scheduled Jobs
kubectl get jobs -n jobs-lab -w
Wait until the CronJob creates a Job, then press Ctrl+C.
Step 9: View CronJob-created logs
kubectl get pods -n jobs-lab kubectl logs <cronjob-pod-name> -n jobs-lab
Common Job and CronJob commands
kubectl get jobs -n <namespace> kubectl describe job <job-name> -n <namespace> kubectl get cronjobs -n <namespace> kubectl describe cronjob <cronjob-name> -n <namespace> kubectl get pods -n <namespace> kubectl logs <pod-name> -n <namespace> kubectl get events -n <namespace> --sort-by=.metadata.creationTimestamp
Common mistakes
- Using a Deployment for one-time work.
- Forgetting that CronJob schedules use cron syntax.
- Leaving too much Job history behind.
- Setting retries too high for tasks that fail fast.
- Not making scheduled jobs idempotent.
Step 10: Clean up
kubectl delete namespace jobs-lab
Bottom line:
Jobs run work to completion. CronJobs create Jobs on a schedule. They are the Kubernetes pattern for batch work, maintenance tasks, and recurring jobs.
Check your understanding
- When should you use a Job instead of a Deployment?
- What does a CronJob create?
- What does backoffLimit control?
- What does completions mean?
- What does parallelism control?
- What command lists CronJobs?
- Why should CronJob tasks often be idempotent?
- Where do you view logs from completed Job work?
- What Namespace command cleaned up the lab?
- Name three troubleshooting commands for Jobs.
Answer key
- When the work should run to completion instead of staying online.
- Jobs.
- How many retries are attempted before the Job is considered failed.
- How many successful Pod completions are needed.
- How many Pods can run at the same time.
- kubectl get cronjobs -n <namespace>.
- Because retries or overlapping schedules can run the same work more than once.
- In the Job-created Pod logs.
- kubectl delete namespace jobs-lab.
- Examples: get jobs, describe job, get pods, logs, get events.