Jobs y CronJobs
Todo lo que has desplegado hasta ahora comparte una premisa: el proceso debe correr para siempre, y si termina, algo va mal. Pero hay tareas cuya definición de éxito es justo la contraria: terminar. Generar un informe, copiar una base de datos, procesar un lote. Para ellas existen los Jobs, y para las que además se repiten en horario, los CronJobs.
Trabaja desde la pestaña dev-machine.
Paso 1: Un Job que termina bien
Crea el archivo job.yaml:
cat << 'EOF' > job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: backups
spec:
completions: 1
backoffLimit: 3
template:
spec:
restartPolicy: Never
containers:
- name: backups
image: ghcr.io/iximiuz/labs/nginx:alpine
command: ["sh", "-c", "echo copiando la db; sleep 5; echo copia completada"]
EOF
El YAML, explicado con preguntas y respuestas
¿Por qué apiVersion: batch/v1?
Los Jobs y CronJobs viven en el grupo batch de la API, el dedicado a las cargas de trabajo finitas. Tercera variante que conoces, tras v1 (Pods) y apps/v1 (Deployments).
¿Qué cuenta completions?
Cuántas terminaciones exitosas necesita el Job para darse por completado. Con completions: 1, basta un Pod que acabe bien. Valores mayores sirven para procesar lotes en varias tandas (y combinados con parallelism, en paralelo).
¿Qué limita backoffLimit?
El número de reintentos ante fallos antes de marcar el Job como fallido. Sin él, un comando roto reintentaría (con esperas crecientes) hasta el límite por defecto de 6.
¿Por qué restartPolicy: Never si en los Pods nunca la habíamos tocado?
Los Pods de larga duración usan el valor por defecto Always: si el proceso termina, el kubelet lo reinicia. Eso es incompatible con un Job, donde terminar es el objetivo. Los Jobs solo admiten Never (cada reintento es un Pod nuevo) u OnFailure (reintenta en el mismo Pod). Es obligatorio elegir una.
¿Y el command que sobrescribe al de la imagen?
Igual que viste en los challenges: sustituye el proceso por defecto de la imagen. Aquí convierte un servidor web en un script de cinco segundos, suficiente para simular un trabajo por lotes.
Aplícalo y observa su ciclo de vida completo:
kubectl apply -f job.yaml
kubectl get jobs,pods
kubectl logs -l job-name=backups
Fíjate en un detalle importante: cuando el Pod termina, pasa a estado Completed pero no desaparece. El Job conserva sus Pods para que puedas leer sus logs.
Paso 2: Un CronJob que se repite
Un CronJob es una fábrica de Jobs con horario. Crea cronjob.yaml:
cat << 'EOF' > cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: reports
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: reports
image: ghcr.io/iximiuz/labs/nginx:alpine
command: ["sh", "-c", "date; echo informe de ventas generado"]
EOF
El YAML, explicado con preguntas y respuestas
¿Qué formato usa schedule?
El formato cron clásico de cinco campos: minuto, hora, día del mes, mes y día de la semana. * * * * * significa cada minuto, ideal para no esperar en un laboratorio; en el mundo real verás cosas como 0 3 * * * (a las 3:00 cada día).
¿Qué es jobTemplate?
Un Job completo embebido, igual que la template de un Deployment embebía un Pod. La cadena resultante tiene tres eslabones: el CronJob crea Jobs, y cada Job crea Pods.
¿Qué pasa si una ejecución sigue corriendo cuando toca la siguiente?
Lo decide el campo concurrencyPolicy, que aquí no declaramos: su valor por defecto Allow permite ejecuciones simultáneas. Las alternativas son Forbid (salta la nueva) y Replace (mata la vieja). Merece la pena conocerlo antes de que un Job lento te lo enseñe por las malas.
Aplícalo:
kubectl apply -f cronjob.yaml
Ahora toca esperar al minuto siguiente. Vigila cómo se crean los Jobs:
kubectl get jobs --watch
Cuando aparezca el primero (con nombre reports-<timestamp>: cada Job hereda el nombre de su CronJob), sal con Ctrl+C y lee su log:
kubectl logs -l job-name=<nombre-del-job>
💡 Por defecto, un CronJob conserva los 3 últimos Jobs exitosos y el último fallido (successfulJobsHistoryLimit y failedJobsHistoryLimit). Sin esos límites, un CronJob de cada minuto acumularía miles de objetos en pocos días.
Resumen
- Un Job persigue terminaciones exitosas (
completions) con un presupuesto de reintentos (backoffLimit). restartPolicydeja de ser un detalle: en Jobs es obligatorio elegirNeveruOnFailure.- Un CronJob es una plantilla de Jobs con horario cron, y
concurrencyPolicygobierna los solapes. - Los Pods
Completedno son basura: son los logs de tus trabajos.
Antes de continuar, limpia el CronJob para que no siga fabricando Jobs durante el resto del curso: kubectl delete cronjob reports.
- Previous lesson
- Init containers y sidecars
- Next lesson
- Horizontal Pod Autoscaler