infra / kubernetes
Jobs et CronJobs
Explication
Ce que vous allez apprendre
- Comprendre la différence entre une charge permanente (Deployment) et une tâche ponctuelle (Job)
- Configurer les réessais automatiques d'un Job avec
backoffLimit - Limiter le temps maximal d'exécution d'un Job avec
activeDeadlineSeconds - Paralléliser une file de travail avec
completionsetparallelism - Planifier des tâches récurrentes avec un CronJob, et éviter le piège du chevauchement
Dans quel contexte ?
Une équipe doit exporter chaque nuit un rapport de ventes, un traitement qui dure normalement 10 minutes. Un jour, la base de données est anormalement lente et l'export du lundi prend 3 heures, jusqu'à empiéter sur l'heure de déclenchement de l'export du mardi. Sans protection, les deux exports tournent alors simultanément, se marchent potentiellement dessus et corrompent le rapport final. Cette leçon montre comment un CronJob bien configuré, avec concurrencyPolicy, évite précisément ce genre de chevauchement silencieux.
Toutes les charges ne sont pas permanentes
D'abord, tout ce qui a été vu jusqu'ici, Deployment, StatefulSet, sert à faire tourner des applications qui doivent rester actives en permanence.
Un besoin de nature complètement différente
Mais beaucoup de tâches réelles ont une nature différente : une migration de base de données, un traitement d'images en lot, un export de rapport nocturne. Ces tâches doivent s'exécuter, se terminer, puis s'arrêter.
L'objet conçu pour ce cas
C'est exactement ce que le Job est conçu pour gérer, contrairement à un Deployment qui redémarrerait indéfiniment un conteneur qui se termine.
| Champ | Rôle |
|---|---|
backoffLimit | Nombre maximal de réessais en cas d'échec |
activeDeadlineSeconds | Durée maximale avant d'arrêter un Job bloqué |
completions / parallelism | Nombre total de tâches réparties sur plusieurs exécutions simultanées |
concurrencyPolicy (CronJob) | Interdit ou autorise le chevauchement de deux exécutions planifiées |
Réessayer intelligemment en cas d'échec
Un Job ne se contente pas de lancer une tâche une fois : il peut réessayer automatiquement en cas d'échec, jusqu'à un nombre limite de tentatives, le backoffLimit.
Éviter qu'une tâche bloquée tourne indéfiniment
Il peut aussi imposer une limite de temps globale, activeDeadlineSeconds, pour éviter qu'une tâche bloquée tourne indéfiniment sans jamais échouer proprement.
Prérequis
Cette leçon suppose les Pods et leurs conteneurs déjà bien compris : un Job orchestre simplement leur cycle de vie différemment d'un Deployment, en visant une complétion plutôt qu'une disponibilité permanente.
Traiter une file de travail en parallèle
Un Job peut aussi traiter une file de travail en parallèle, en répartissant un nombre total de tâches (completions) sur plusieurs exécutions simultanées (parallelism), utile pour accélérer un traitement par lots.
Planifier des tâches récurrentes
Une fois le Job compris, le CronJob ajoute une couche de planification par-dessus : au lieu de le lancer manuellement, on définit un calendrier avec la syntaxe cron classique.
Ce que fait Kubernetes à chaque échéance
Kubernetes crée alors automatiquement un nouveau Job à chaque échéance, typiquement pour une sauvegarde nocturne ou un nettoyage périodique.
Piège fréquent
Sans concurrencyPolicy définie, deux exécutions d'un même CronJob peuvent se chevaucher si la première dure plus longtemps que prévu — un risque réel pour des tâches comme des sauvegardes ou des exports, qui peuvent se corrompre mutuellement si elles tournent en même temps.
Le piège du chevauchement
Si une exécution planifiée prend plus de temps que prévu, et que la suivante démarre entretemps, deux exécutions peuvent se marcher dessus, comme deux sauvegardes lancées en même temps.
La protection à connaître
La concurrencyPolicy permet d'interdire explicitement ce chevauchement, un détail facile à négliger mais qui peut avoir de vraies conséquences en production.
La leçon suivante s'attaque à un besoin différent : comprendre ce qui se passe réellement dans le cluster grâce aux logs et aux métriques.
Commandes & code
Jobs & CronJobs
Un Job exécute une tâche jusqu'à complétion (pas un service permanent) ; un CronJob planifie des Jobs récurrents.
# job.yaml - migration de base de données exécutée une fois
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
spec:
backoffLimit: 3 # nombre de tentatives en cas d'échec
activeDeadlineSeconds: 300 # timeout global du Job
template:
spec:
restartPolicy: Never # OnFailure ou Never, jamais "Always" pour un Job
containers:
- name: migrate
image: myorg/api:1.4.2
command: ["npm", "run", "migrate"]# job-parallel.yaml - traitement parallèle d'une file de tâches
apiVersion: batch/v1
kind: Job
metadata:
name: batch-resize-images
spec:
completions: 20 # nombre total de Pods qui doivent terminer avec succès
parallelism: 4 # nombre de Pods exécutés EN MÊME TEMPS
backoffLimit: 6
template:
spec:
restartPolicy: OnFailure
containers:
- name: resize-worker
image: myorg/image-worker:2.1.0
command: ["node", "resize-worker.js"]# cronjob.yaml - sauvegarde nocturne planifiée
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-db-backup
spec:
schedule: "0 2 * * *" # 02h00 chaque nuit (syntaxe cron classique, UTC)
concurrencyPolicy: Forbid # empêche le chevauchement si le précédent tourne encore
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 3
startingDeadlineSeconds: 120
jobTemplate:
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: myorg/db-backup-tool:1.0
command: ["/scripts/backup.sh"]
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: passwordkubectl apply -f cronjob.yaml
kubectl get cronjobs
kubectl get jobs --watch
# Déclencher manuellement une exécution immédiate (utile pour tester le CronJob)
kubectl create job manual-backup --from=cronjob/nightly-db-backup
kubectl logs job/db-migrateRésumé
restartPolicyd'un Job estNeverouOnFailure, jamaisAlways.parallelism/completionsgèrent le traitement par lots en parallèle.concurrencyPolicy: Forbidévite deux exécutions simultanées d'un même CronJob.kubectl create job --from=cronjob/...permet de tester une exécution hors planning.
Exercices pratiques
Mission : empêcher deux sauvegardes nocturnes de se marcher dessus
Objectif : Corriger un CronJob de sauvegarde pour empêcher tout chevauchement d'exécutions, et le tester sans attendre l'échéance planifiée.
Contexte
Le CronJob nightly-db-backup exporte chaque nuit un rapport de ventes en 10 minutes normalement. Une nuit, la base de données est anormalement lente et l'export dure 3 heures, jusqu'à empiéter sur l'échéance suivante. Rien dans la configuration actuelle n'empêche alors les deux exports de tourner en même temps et de corrompre le rapport final : concurrencyPolicy n'a jamais été définie sur ce CronJob.