Kubernetes Jobs exécutent des charges de travail de courte durée jusqu'à leur terminaison ; les CronJobs planifient ces Jobs selon un calendrier récurrent. Lorsqu'un des deux échoue, vous avez besoin d'une méthode reproductible pour identifier la cause racine rapidement. Ce guide explique le fonctionnement des relances et de backoffLimit, où chercher les Pods en échec, comment lire les logs et les événements, et comment dépanner en toute sécurité dans des clusters proches de la production. Vous disposerez également de manifests et de commandes copiables‑collables que vous pourrez adapter dès aujourd'hui.
Vue d'ensemble du flux de travail
Suivez ce parcours pour diagnostiquer la majorité des problèmes de Job et de CronJob :
- Observer le contrôleur
kubectl get jobkubectl get cronjob -o wide- Repérez les champs d'état :
Succeeded,Failed,Active,Last Schedule,Suspend,ConcurrencyPolicy
- Trouver les Pods
- Pour un Job :
kubectl get pods -l job-name=<nom-du-job> - Pour une exécution de CronJob : listez les Jobs possédés par le CronJob (
kubectl get jobs --selector=job-name=<nom-cronjob>-ou par motif de nom), puis listez leurs Pods.
- Décrire pour obtenir les événements et les raisons
kubectl describe job/<nom>kubectl describe pod/<nom-du-pod>(cherchezReason/MessagecommeImagePullBackOff,OOMKilled,Error,FailedScheduling)- Lire les logs :
kubectl logs <nom-du-pod> --all-containers=true- Si le conteneur a planté, ajoutez
--previous - Pour tous les Pods d'un Job :
kubectl logs -l job-name=<nom> --all-containers=true
- Vérifier les pièges de la spec
- Jobs :
backoffLimit,activeDeadlineSeconds,parallelism,completions,restartPolicy - CronJobs :
schedule,startingDeadlineSeconds,concurrencyPolicy,suspend,successfulJobsHistoryLimit,failedJobsHistoryLimit
- Agir en toute sécurité
- Mettre en pause le CronJob :
kubectl patch cronjob/<nom> -p '{"spec":{"suspend":true}}' - Reproduire en créant un Job ad‑hoc à partir du CronJob :
kubectl create job --from=cronjob/<nom> <job-temporaire> - Appliquer une petite modification, observer événements et logs, puis réactiver.
Jobs vs CronJobs en pratique
Les Jobs orchestrent les Pods jusqu'à ce que le nombre souhaité de succès soit atteint. Les CronJobs créent des Jobs selon un calendrier. Les différences clés pour le dépannage :
- Jobs : concentrez‑vous sur le cycle de vie des Pods, les codes de sortie,
backoffLimitet les problèmes de ressources. - CronJobs : ajoutez l'évaluation du calendrier,
concurrencyPolicy, les exécutions manquées (startingDeadlineSeconds) et le nettoyage de l'historique. Vous déboguez d'abord le Job engendré, puis revenez à la spec du CronJob si le problème vient de la planification.
Dépannage d'un Job qui échoue
- Confirmer l'état
kubectl get job <nom> -o wide
Regardez Succeeded, Failed, Active.
- Vérifier les Pods
kubectl get pods -l job-name=<nom>
S'il n'y en a pas, inspectez FailedScheduling ou les quotas avec kubectl describe job et kubectl get events.
- Inspecter les événements et le statut
kubectl describe pod <nom-du-pod>
Signaux courants :
ImagePullBackOff: image incorrecte ou secret de pull manquant.ErrImagePull: erreur de registre ou d'authentification.OOMKilled: limite mémoire trop basse pour le processus.Error/Completed: regardez leexitCodedans le statut du conteneur.
- Lire les logs
kubectl logs <nom-du-pod> --all-containers=true
Si le conteneur redémarre dans le même Pod (restartPolicy: OnFailure), ajoutez --previous.
- Comprendre les relances et
backoffLimit
backoffLimit: nombre maximal de relances de Pod avant que le Job ne soit marqué Failed. Exemple :backoffLimit: 2autorise deux relances après le premier échec (trois tentatives au total).activeDeadlineSeconds: limite de temps dure pour le Job ; son dépassement fait échouer le Job.
- Patterns de correction
- Erreurs d'image : corrigez le tag ou ajoutez
imagePullSecrets. - Pression ressources : augmentez les limites mémoire/CPU ou optimisez la charge.
- Code de sortie non‑zéro : gérez les erreurs dans l'application, ajoutez des relances ou ajustez les entrées.
- Jobs lents : prolongez
activeDeadlineSecondsou réduisezparallelismpour alléger la pression.
Dépannage d'un CronJob qui échoue
- Lister les CronJobs
kubectl get cronjob -o wide
Vérifiez SCHEDULE, SUSPEND, ACTIVE, LAST SCHEDULE.
Si ACTIVE reste 0 et LAST SCHEDULE ne change pas, le contrôleur peut être bloqué ou des filtres de calendrier s'appliquent. Inspectez :
- Est‑il en train de créer des Jobs ?
suspend: trueempêche toute création d'exécution.startingDeadlineSeconds: les calendriers manqués plus anciens que cette valeur sont ignorés.concurrencyPolicy:Forbidempêche un nouveau lancement si le précédent est encore actif ;Replaceannule l'exécution active.
- Inspecter le dernier Job engendré
kubectl get jobs --sort-by=.metadata.creationTimestamp
Prenez le Job le plus récent appartenant au CronJob et déboguez‑le comme n'importe quel Job (événements, Pods, logs).
- Opérations sûres
- Mettre en pause temporairement :
kubectl patch cronjob/<nom> -p '{"spec":{"suspend":true}}' - Tester les changements en créant un Job one‑off à partir du template :
kubectl create job --from=cronjob/<nom> <job-temporaire> - Réactiver après validation :
kubectl patch cronjob/<nom> -p '{"spec":{"suspend":false}}'
Exemples pratiques
Exemple 1 : Un Job qui échoue deux fois puis réussit
apiVersion: batch/v1
kind: Job
metadata:
name: demo-backoff
spec:
backoffLimit: 2
template:
spec:
restartPolicy: OnFailure
containers:
- name: worker
image: bash:5
command: ["bash", "-lc", "if [ ! -f /tmp/ok ]; then echo first or second fail; touch /tmp/ok; exit 1; else echo success; fi" ]
Ce qu'il faut observer :
- Le premier Pod sort avec le code
1; le contrôleur relance jusqu'àbackoffLimit. - La deuxième tentative échoue aussi ; la troisième affiche
success. kubectl describe job/demo-backoffmontre l'incrémentation deFailedavantSucceeded.
Exemple 2 : CronJob bloqué par concurrencyPolicy=Forbid
apiVersion: batch/v1
kind: CronJob
metadata:
name: report-job
spec:
schedule: "*/5 * * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 2
jobTemplate:
spec:
backoffLimit: 1
template:
spec:
restartPolicy: OnFailure
containers:
- name: reporter
image: bash:5
command: ["bash", "-lc", "echo starting; sleep 400; echo done" ]
Pourquoi il ne planifie pas toutes les 5 min :
- Chaque exécution dure ~6,6 min (400 s). Avec
Forbid, le déclencheur de 5 min qui arrive pendant qu'une exécution est active sera ignoré.LAST SCHEDULEn'avance pas à chaque tick. - Solutions : passer à
concurrencyPolicy: Allow, réduire le temps d'exécution, ou augmenter l'intervalle.
Exemple 3 : ImagePullBackOff dans un Job
apiVersion: batch/v1
kind: Job
metadata:
name: bad-image
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: c
image: example.com/private/app:does-not-exist
Dépannage :
kubectl describe podafficheErrImagePull/ImagePullBackOff.- Corrigez le tag ou configurez
imagePullSecretset l'URL du registre correcte.
Exemple 4 : OOMKilled dans un Job
apiVersion: batch/v1
kind: Job
metadata:
name: mem-tight
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: c
image: python:3.11
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "64Mi"
cpu: "200m"
command: ["python", "-c", "a='x'*200_000_000; print(len(a))
Dépannage :
kubectl describe podmontreOOMKilleddans le dernier état.- Augmentez la limite mémoire (par exemple
256Mi) ou réduisez la consommation mémoire du programme.
Plan pilote local
Commencez petit et mesurable :
- Choisir un Job aux critères de succès clairs
- Exemple : transformer un petit fichier d'entrée et écrire un checksum.
- Définir la réussite comme code de sortie
0et présence d'une ligne de sortie attendue.
- Rendre l'inspection facile
- Ajoutez des logs structurés et un message final de succès.
- Réglez
backoffLimità1etactiveDeadlineSecondsà une borne supérieure sûre.
- Valider dans un cluster local
- Appliquez le Job, surveillez les événements et lisez les logs de bout en bout.
- Enregistrez le temps d'exécution et la consommation de ressources.
- L'embarquer dans un CronJob (optionnel)
- Choisissez d'abord un calendrier conservateur (par exemple toutes les heures).
- Mettez
concurrencyPolicyàForbidjusqu'à preuve d'idempotence.
- Étendre progressivement
- Augmentez la taille des entrées, puis
parallelism. - Ajoutez des alertes sur les échecs de Job et les calendriers manqués.
Cette approche réduit le risque et raccourcit la boucle de rétroaction.
Conclusion
Les Jobs et CronJobs échouent pour des raisons compréhensibles : images incorrectes, pression sur les ressources, codes de sortie non‑zéro ou règles de planification. Le chemin le plus rapide est constant : vérifier l'état du contrôleur, localiser les Pods, lire les événements, inspecter les logs, et valider les champs de spec tels que backoffLimit, activeDeadlineSeconds, schedule et concurrencyPolicy. Utilisez suspend et les Jobs ad‑hoc pour tester en toute sécurité, puis déployez par petites étapes. Gardez les exécutions courtes, les sorties claires et les critères de succès évidents. C'est ainsi que vous dépannerez avec confiance.