Jobs y CronJobs en Kubernetes
Los Jobs y los CronJobs son recursos en Kubernetes diseñados para automatizar tareas de forma puntual o recurrente. A diferencia de los Pods, los Jobs tienen un número de ejecuciones definido y un tiempo de vida limitado, mientras que los CronJobs permiten programar tareas recurrentes basadas en un cronograma.
Estos recursos son ideales para tareas de mantenimiento, como limpieza de logs, backups de datos o cualquier tarea que no requiera ejecución continua.
🎥 Vídeo completo, utilicemos los capítulos de youtube para saltar a la sección que nos interese: https://youtu.be/DJGkIhNxE94
¿Qué es un Job?
Un Job en Kubernetes asegura que un conjunto de tareas se ejecuten una cantidad específica de veces. Una vez que se completan todas las ejecuciones, el Job finaliza.
Ejemplo básico de un Job
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
spec:
completions: 5 # Número de ejecuciones deseadas
backoffLimit: 3 # Número máximo de reintentos en caso de fallo
ttlSecondsAfterFinished: 300 # Borra el Job y sus pods 5 minutos después de terminar
template:
spec:
containers:
- name: test
image: busybox
command: ["/bin/sleep"]
args: ["3"] # Simula una tarea que dura 3 segundos
restartPolicy: Never
Características principales de un Job
- Control de ejecuciones: Podemos definir cuántas veces debe ejecutarse la tarea utilizando el parámetro
completions. - Paralelismo: Con el parámetro
parallelismpodemos indicar cuántos pods del Job pueden ejecutarse a la vez. Por ejemplo,completions: 5yparallelism: 2ejecutará 5 tareas en total, de dos en dos. - Reintentos automáticos: Si una tarea falla, Kubernetes puede reintentarla automáticamente según el valor de
backoffLimit. - Política de reinicio: El parámetro
restartPolicycontrola si los contenedores fallidos deben reiniciarse (NeveroOnFailure). En los Jobs es obligatorio especificarla, ya que el valor por defecto de los pods (Always) no tiene sentido para una tarea que debe terminar. - Limpieza automática: Con
ttlSecondsAfterFinishedel Job (y sus pods) se borra solo cuando pasan esos segundos desde que termina, bien o mal. Por ejemplo,ttlSecondsAfterFinished: 300lo elimina a los 5 minutos.
Estados de un Job
Ojo con una confusión muy habitual: Pending, Running, Succeeded y Failed son las fases de los pods que crea el Job, no del Job en sí. El Job expresa su estado mediante condiciones (status.conditions):
- Complete: Se alcanzó el número de
completionscon éxito. - Failed: Se superó el
backoffLimit(o elactiveDeadlineSeconds) sin completarse.
Mientras no tenga ninguna de las dos, el Job sigue en marcha, y en status vemos cuántos pods están activos (active), han terminado bien (succeeded) o han fallado (failed). Podemos esperar a que termine con kubectl wait --for=condition=complete job/test-job.
¿Qué es un CronJob?
Un CronJob en Kubernetes permite programar tareas recurrentes basadas en un cronograma. Es ideal para tareas que necesitan ejecutarse en intervalos regulares, como limpiezas diarias o backups semanales.
Ejemplo básico de un CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: test-cronjob
spec:
schedule: "*/1 * * * *" # Ejecuta la tarea cada minuto
timeZone: "Europe/Madrid" # Zona horaria del schedule (por defecto, la del kube-controller-manager)
successfulJobsHistoryLimit: 3 # Mantiene un historial de 3 ejecuciones exitosas
failedJobsHistoryLimit: 1 # Mantiene un historial de 1 ejecución fallida
concurrencyPolicy: Forbid # No permite que dos Jobs se ejecuten en paralelo
jobTemplate:
spec:
completions: 1
backoffLimit: 2
template:
spec:
containers:
- name: test
image: busybox
command: ["/bin/sleep"]
args: ["3"]
restartPolicy: Never
Características principales de un CronJob
- Programación flexible: Utiliza la sintaxis de cron para definir cuándo debe ejecutarse la tarea.
- Zona horaria: Con
timeZone(estable desde Kubernetes 1.27) indicamos en qué zona horaria se interpreta elschedule, usando nombres de la base de datos tz comoEurope/MadridoEtc/UTC. Si no lo ponemos, se usa la zona horaria delkube-controller-manager. - Historial de ejecuciones: Podemos controlar cuántos
Jobscompletados o fallidos se deben mantener en el historial consuccessfulJobsHistoryLimityfailedJobsHistoryLimit. - Control de concurrencia: El parámetro
concurrencyPolicydefine si losJobspueden ejecutarse en paralelo (Allow), si se salta la ejecución mientras el anterior siga en marcha (Forbid), o si se cancela el anterior antes de iniciar uno nuevo (Replace).
El matiz de Forbid y startingDeadlineSeconds
En el curso presencial lo probamos con un CronJob que se lanza cada minuto y tarda 90 segundos. Con Forbid, nunca hay dos Jobs activos a la vez: si el anterior sigue trabajando, la ejecución de ese minuto no arranca.
Pero "saltarse" no siempre significa "perderse". Cuando el Job anterior termina, el controlador vuelve a mirar la ejecución pendiente y la tiene en cuenta mientras no haya pasado startingDeadlineSeconds desde la hora en que tocaba. Si no hemos puesto ese campo (no tiene límite por defecto), o si es mayor que lo que dura el Job, la ejecución pendiente puede arrancar con retraso, justo al terminar la anterior. Y entonces parece que los Jobs se encadenan uno detrás de otro, en lugar de saltarse.
Si lo que queremos es que una ejecución que no pudo empezar a su hora se descarte, pongamos un plazo corto:
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 30 # si no pudo arrancar en 30 s, se da por perdida
startingDeadlineSeconds tiene otro efecto útil: si el controlador acumula más de 100 ejecuciones perdidas (por ejemplo, tras una caída larga del control plane), deja de programar el CronJob y lo avisa en sus eventos. Con un plazo, solo cuenta las que caen dentro de él.
Para pausarlo sin borrarlo, kubectl patch cronjob <nombre> -p '{"spec":{"suspend":true}}'.
Explicación del parámetro schedule
La sintaxis de schedule sigue el formato cron:
# ┌───────────── minuto (0 - 59)
# │ ┌───────────── hora (0 - 23)
# │ │ ┌───────────── día del mes (1 - 31)
# │ │ │ ┌───────────── mes (1 - 12)
# │ │ │ │ ┌───────────── día de la semana (0 - 6) (domingo a sábado)
# │ │ │ │ │
# * * * * *
Ejemplos comunes:
@daily: Ejecuta la tarea una vez al día.@hourly: Ejecuta la tarea una vez por hora.@weekly: Ejecuta la tarea una vez por semana.
Comandos útiles para Jobs y CronJobs
También podemos crear estos recursos de forma imperativa, algo muy práctico en los exámenes de certificación:
# Crear un Job
kubectl create job test-job --image=busybox -- /bin/sleep 3
# Crear un CronJob
kubectl create cronjob test-cronjob --image=busybox --schedule="*/1 * * * *" -- /bin/sleep 3
# Lanzar manualmente un Job a partir de un CronJob existente (muy útil para probarlo sin esperar)
kubectl create job test-manual --from=cronjob/test-cronjob
# Consultar el estado y los logs
kubectl get jobs
kubectl get cronjobs
kubectl logs job/test-job
Continuaremos en el siguiente capítulo viendo los servicios y cómo exponer aplicaciones en Kubernetes.
- Lista de vídeos en Youtube: Curso Kubernetes
