E-NO
Kubernetes 4 min de lecture

Erreurs de configuration des Jobs Kubernetes : exemples pratiques et correctifs

calendar_today Publié : 2026-08-23
update Dernière mise à jour : 2026-08-23
analytics Efficacité SEO : 97%
Illustration du guide technique pour « Erreurs de configuration des Jobs Kubernetes : exemples pratiques et correctifs ».

Introduction

Les Jobs Kubernetes sont les piliers du traitement par lots, des tâches ponctuelles et des opérations de maintenance. Ils garantissent qu'un nombre spécifié de pods se terminent avec succès, en gérant les relances et le cycle de vie des pods. Mais un Job n'est fiable que si sa configuration est correcte. Un restartPolicy manquant, un backoffLimit illimité ou une limite de ressources absente peuvent transformer une simple tâche en échec silencieux ou en monstre gourmand en ressources.

Dans ce guide, nous passerons en revue les erreurs de configuration les plus courantes des Jobs Kubernetes, comment valider vos manifestes de Job avant de les appliquer, et comment récupérer en toute sécurité lorsque les choses tournent mal. Chaque section comprend des extraits YAML concrets, des commandes kubectl et des sorties attendues pour que vous puissiez appliquer ces pratiques immédiatement.

Inventaire de la version et de l’environnement

Avant de créer ou de déboguer des Jobs, vous devez connaître votre environnement Kubernetes. Cela évite les surprises liées aux API obsolètes, aux contraintes de ressources ou aux problèmes de permissions.

1. Vérifier la version de Kubernetes

Utilisez kubectl version pour voir les versions du client et du serveur. Les Jobs sont stables dans batch/v1 depuis Kubernetes 1.21, mais des fonctionnalités comme podFailurePolicy et managedBy nécessitent des versions plus récentes.

kubectl version --short
Client Version: v1.27.3
Server Version: v1.27.3

Si votre serveur est antérieur à 1.21, vous devez utiliser batch/v1beta1 pour les Jobs, mais cette API est supprimée en 1.25. Prévoyez une mise à niveau.

2. Vérifier les dépréciations d’API

Depuis Kubernetes 1.25, l’API batch/v1beta1 de CronJob est supprimée. Utilisez toujours batch/v1 pour les Jobs et les CronJobs. Vous pouvez vérifier les avertissements lors de l’application des ressources en utilisant kubectl apply --dry-run=client ou en interrogeant le serveur d’API avec kubectl api-resources.

3. Vérifier les quotas de ressources

Si votre espace de noms a un ResourceQuota, il peut limiter le nombre de Jobs, de pods, ou de CPU/mémoire. Vérifiez avec :

kubectl describe resourcequota -n dev
Name:            compute-quota
Namespace:       dev
Resource         Used   Hard
--------         ----   ----
requests.cpu     500m   2
requests.memory  1Gi    4Gi
limits.cpu       1      4
limits.memory    2Gi    8Gi
pods             3      10
jobs.batch       1      5

Si vous dépassez ces limites, les pods de votre Job ne seront pas planifiés.

4. Évaluer la capacité des nœuds

Assurez-vous que les nœuds de votre cluster disposent de suffisamment de CPU et de mémoire allouables pour les pods du Job plus les frais généraux. Utilisez :

kubectl describe nodes | grep -A 5 "Allocated resources"
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests      Limits
  --------           --------      ------
  cpu                1200m (60%)   0 (0%)
  memory             900Mi (45%)   0 (0%)

5. Confirmer les permissions RBAC

Vous avez besoin au minimum des verbes create, get, list, watch et delete sur les Jobs et les pods, et get sur les logs. Pour un accès minimal, créez un rôle :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: job-manager
rules:
- apiGroups: ["batch"]
  resources: ["jobs"]
  verbs: ["create", "get", "list", "watch", "delete", "update"]
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

Liez ce rôle à votre utilisateur ou compte de service.

Question rapide 1 sur 2

Quelles valeurs de restartPolicy sont appropriées pour un Job Kubernetes ?

Comme indiqué dans la référence, un Job n'est approprié que pour les Pods dont restartPolicy vaut OnFailure ou Never. La valeur par défaut est Always, ce qui ne convient pas aux Jobs.

Chemin de configuration sécurisé

Une approche sûre pour déployer des Jobs consiste à commencer par un manifeste minimal, à valider avec un dry-run, à appliquer dans un espace de noms de développement, puis à ajouter des limites de ressources, des délais et des relances. Cela évite un rayon d’impact accidentel.

Étape 1 : Créer un manifeste de Job de base

Créez un fichier job.yaml avec un Job simple qui affiche un message et se termine.

apiVersion: batch/v1
kind: Job
metadata:
  name: hello-job
spec:
  template:
    spec:
      containers:
      - name: hello
        image: busybox:1.36
        command: ["sh", "-c", "echo Hello Kubernetes! && sleep 5"]
      restartPolicy: Never
  backoffLimit: 4

Remarquez que restartPolicy est défini sur Never ; c’est obligatoire pour les Jobs (autrement OnFailure). L’étiquette de l’image est épinglée à 1.36, pas latest.

Étape 2 : Validation par dry-run

Utilisez kubectl apply --dry-run=client pour valider la syntaxe et la justesse des champs de l’API sans réellement créer le Job.

kubectl apply --dry-run=client -f job.yaml
job.batch/hello-job created (dry run)

Pour une validation plus poussée qui atteint le serveur d’API sans persister, utilisez --dry-run=server (Kubernetes 1.18+). Cela vérifie les webhooks d’admission et les quotas.

kubectl apply --dry-run=server -f job.yaml
job.batch/hello-job created (server dry run)

Étape 3 : Appliquer dans un espace de noms de développement

Créez un espace de noms dédié aux tests, par exemple dev, et appliquez le manifeste.

kubectl create namespace dev
kubectl apply -f job.yaml -n dev
job.batch/hello-job created

Étape 4 : Définir les demandes et limites de ressources

N’exécutez jamais un Job sans demandes et limites de ressources. Cela empêche un pod de consommer toutes les ressources d’un nœud et assure une planification prévisible.

Ajoutez ce qui suit à la spécification du conteneur :

resources:
  requests:
    cpu: "100m"
    memory: "50Mi"
  limits:
    cpu: "200m"
    memory: "100Mi"

Extrait complet du Job :

apiVersion: batch/v1
kind: Job
metadata:
  name: hello-job
spec:
  template:
    spec:
      containers:
      - name: hello
        image: busybox:1.36
        command: ["sh", "-c", "echo Hello Kubernetes! && sleep 5"]
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "200m"
            memory: "100Mi"
      restartPolicy: Never
  backoffLimit: 4

Étape 5 : Configurer les délais et les relances

Contrôlez la durée d’exécution d’un Job et le nombre de relances de pods échoués.

  • backoffLimit : nombre de relances avant de marquer le Job comme échoué. La valeur par défaut est 6.
  • activeDeadlineSeconds : durée maximale pendant laquelle le Job peut s’exécuter, y compris toutes les relances de pods. Une fois dépassée, le Job est terminé et marqué comme échoué.
  • completions : nombre de fins de pods réussies requis pour que le Job soit considéré comme terminé.
  • parallelism : nombre de pods pouvant s’exécuter simultanément.

Exemple :

spec:
  backoffLimit: 2
  activeDeadlineSeconds: 100
  completions: 5
  parallelism: 2

Avec cette configuration, le Job crée 5 pods au total, en exécutant 2 à la fois. Chaque pod a jusqu’à 2 relances, et tout le Job doit se terminer en 100 secondes. Si activeDeadlineSeconds est dépassé, tous les pods sont tués et le Job échoue avec la raison DeadlineExceeded.

Manifeste de Job sécurisé complet

En combinant toutes les étapes :

apiVersion: batch/v1
kind: Job
metadata:
  name: hello-job
  namespace: dev
spec:
  backoffLimit: 2
  activeDeadlineSeconds: 100
  completions: 5
  parallelism: 2
  template:
    spec:
      containers:
      - name: hello
        image: busybox:1.36
        command: ["sh", "-c", "echo Hello Kubernetes! && sleep 5"]
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "200m"
            memory: "100Mi"
      restartPolicy: Never

Vérification et diagnostics

Après avoir appliqué le Job, vérifiez son état, inspectez les journaux et surveillez les événements pour garantir une réussite.

Vérifier l’état du Job

Utilisez kubectl get jobs pour voir l’état d’achèvement.

kubectl get jobs -n dev
NAME        COMPLETIONS   DURATION   AGE
hello-job   5/5           45s        2m

Si COMPLETIONS affiche 0/5, le Job est toujours en cours ou bloqué.

Décrire le Job

kubectl describe job fournit des détails sur les états des pods, les événements et les conditions.

kubectl describe job hello-job -n dev
Name:           hello-job
Namespace:      dev
Selector:       controller-uid=1234abcd-...
Labels:         controller-uid=1234abcd-...,job-name=hello-job
Annotations:    <none>
Parallelism:    2
Completions:    5
Start Time:     Mon, 12 Aug 2024 10:00:00 +0000
Pods Statuses:  2 Active / 3 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=1234abcd-...,job-name=hello-job
  Containers:
   hello:
    Image:      busybox:1.36
    Port:       <none>
    Command:    ["sh", "-c", "echo Hello Kubernetes! && sleep 5"]
    Limits:
      cpu:      200m
      memory:   100Mi
    Requests:
      cpu:      100m
      memory:   50Mi
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  2m    job-controller  Created pod: hello-job-abcde
  Normal  SuccessfulCreate  2m    job-controller  Created pod: hello-job-fghij
  Normal  SuccessfulCreate  1m    job-controller  Created pod: hello-job-klmno
  Normal  SuccessfulCreate  1m    job-controller  Created pod: hello-job-pqrst
  Normal  SuccessfulCreate  1m    job-controller  Created pod: hello-job-uvwxy

Recherchez les événements FailedCreate si les pods ne peuvent pas être créés (par exemple, quota dépassé).

Afficher les journaux des pods

D’abord, listez les pods associés au Job en utilisant le sélecteur d’étiquette job-name.

kubectl get pods -l job-name=hello-job -n dev
NAME              READY   STATUS      RESTARTS   AGE
hello-job-abcde   0/1     Completed   0          2m
hello-job-fghij   0/1     Completed   0          2m
hello-job-klmno   0/1     Completed   0          1m
hello-job-pqrst   0/1     Completed   0          1m
hello-job-uvwxy   0/1     Completed   0          1m

Puis affichez les journaux d’un pod :

kubectl logs hello-job-abcde -n dev
Hello Kubernetes!

Pour les pods échoués, les journaux révèlent souvent l’erreur.

Surveiller les événements

Les événements fournissent une chronologie de ce qui est arrivé au Job et à ses pods.

kubectl get events --field-selector involvedObject.name=hello-job-abcde -n dev
LAST SEEN   TYPE     REASON      OBJECT                MESSAGE
2m          Normal   Scheduled   pod/hello-job-abcde   Successfully assigned dev/hello-job-abcde to node-1
2m          Normal   Pulled      pod/hello-job-abcde   Container image "busybox:1.36" already present on machine
2m          Normal   Created     pod/hello-job-abcde   Created container hello
2m          Normal   Started     pod/hello-job-abcde   Started container hello

Si un pod échoue, cherchez des événements Warning tels que BackOff, Failed ou Unhealthy.

Question rapide 2 sur 2

Que fait le contrôleur de Job lorsqu'il voit un nouveau Job ?

Le contrôleur de Job n'exécute aucun Pod ni conteneur lui-même. Au lieu de cela, il demande au serveur d'API de créer ou supprimer des Pods. D'autres composants agissent sur ces nouvelles informations pour planifier et exécuter les Pods.

Modes d’échec et récupération

Les Jobs peuvent échouer pour de nombreuses raisons. Voici les modes d’échec courants, les symptômes et les étapes de récupération.

Mode d’échecSymptômesRécupération
ImagePullBackOffPod bloqué en Pending ou ImagePullBackOff, événements montrent Failed to pull imageVérifiez le nom/l’étiquette de l’image, les identifiants du registre, l’accès réseau. Utilisez kubectl describe pod pour les détails.
CrashLoopBackOffLe pod redémarre de manière répétée, code de sortie non nulInspectez les journaux (kubectl logs <pod>), corrigez la commande ou les variables d’environnement.
DeadlineExceededL’état du Job affiche Failed avec la raison DeadlineExceededAugmentez activeDeadlineSeconds ou optimisez la charge de travail.
ResourceQuotaExceededLe Job ne peut pas créer de pods, les événements affichent exceeded quotaAjustez les demandes de ressources ou augmentez le quota de l’espace de noms.
EvictedPods expulsés à cause de la pression sur le nœudAugmentez les ressources du nœud ou réduisez les demandes de ressources des pods.
BackoffLimitExceededLe Job a échoué après backoffLimit relancesEnquêtez sur la cause racine, augmentez backoffLimit si c’est transitoire.

Exemples de récupération détaillés

ImagePullBackOff

Supposons que votre Job utilise image: myapp:latest mais que le registre exige une authentification. Le pod affichera ImagePullBackOff.

Vérifiez le pod :

kubectl describe pod myjob-xxxxx -n dev
Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Normal   Scheduled  5m    default-scheduler  Successfully assigned dev/myjob-xxxxx to node-1
  Warning  Failed     5m    kubelet            Failed to pull image "myapp:latest": rpc error: code = Unknown desc = Error response from daemon: pull access denied for myapp, repository does not exist or may require 'docker login'
  Warning  Failed     5m    kubelet            Error: ErrImagePull
  Normal   BackOff    4m    kubelet            Back-off pulling image "myapp:latest"
  Warning  Failed     4m    kubelet            Error: ImagePullBackOff

Récupération :

  1. Vérifiez le nom et l’étiquette de l’image, par exemple myregistry.com/myapp:1.2.3.
  2. Si elle est privée, créez un Secret avec les identifiants du registre et ajoutez imagePullSecrets à la spécification du pod.
  3. Réappliquez le manifeste corrigé.

CrashLoopBackOff

Un pod qui se termine avec un code non nul de façon répétée entrera en CrashLoopBackOff.

kubectl get pods -n dev
NAME          READY   STATUS             RESTARTS   AGE
myjob-xxxxx   0/1     CrashLoopBackOff   5          3m

Inspectez les journaux :

kubectl logs myjob-xxxxx -n dev --previous
Error: cannot open config file

Récupération :

  1. Corrigez la commande ou l’environnement pour fournir la configuration manquante.
  2. Mettez à jour le manifeste du Job et réappliquez.
  3. Si le Job est toujours en cours, supprimez le pod pour en déclencher un nouveau (sous réserve de backoffLimit).

DeadlineExceeded

Si votre Job dépasse activeDeadlineSeconds, tous les pods sont terminés et le Job échoue.

kubectl get job myjob -n dev
NAME    COMPLETIONS   DURATION   AGE
myjob   0/1           100s       2m

kubectl describe job myjob -n dev
...
Conditions:
  Type     Status  Reason            Message
  ----     ------  ------            -------
  Failed   True    DeadlineExceeded  Job was active longer than specified deadline

Récupération :

  1. Si la charge de travail nécessite légitimement plus de temps, augmentez activeDeadlineSeconds.
  2. Si elle s’est bloquée, enquêtez sur la cause racine via les journaux.
  3. Supprimez le Job échoué et créez-en un nouveau avec les paramètres corrigés.

Étapes de retour en arrière et de récupération

Lorsqu’un Job échoue à cause d’une mauvaise configuration, suivez ces étapes :

  1. Modifiez le manifeste du Job pour corriger le problème. Si vous avez le fichier d’origine, modifiez-le ; sinon, utilisez kubectl get job <name> -o yaml > job.yaml pour le récupérer.
  2. Réappliquez le manifeste avec kubectl apply. Notez que certains champs du Job sont immuables (par exemple, template, backoffLimit, completions, parallelism après la création dans les anciennes versions). Si vous devez modifier des champs immuables, vous devez supprimer et recréer le Job.
  3. Si des champs immuables changent, supprimez l’ancien Job et créez-en un nouveau :
kubectl delete job hello-job -n dev
kubectl apply -f corrected-job.yaml -n dev
  1. Nettoyez les Jobs terminés pour éviter l’encombrement et les fuites de ressources. Utilisez kubectl delete job --all -n dev pour tous les Jobs de l’espace de noms, ou définissez ttlSecondsAfterFinished sur le Job pour le supprimer automatiquement après une période (Kubernetes 1.21+).
spec:
  ttlSecondsAfterFinished: 3600  # supprimer 1 heure après la fin

Liste de contrôle opérationnelle

Avant de promouvoir un Job en production, assurez-vous que ces éléments sont en place. Cette liste couvre les points de mauvaise configuration les plus critiques.

  • L’étiquette de l’image du conteneur est épinglée (par exemple, busybox:1.36, pas latest).
  • restartPolicy est défini sur Never ou OnFailure (jamais Always).
  • Les demandes et limites de ressources sont définies pour chaque conteneur.
  • backoffLimit et activeDeadlineSeconds sont définis en fonction du temps d’exécution prévu et de la tolérance aux relances.
  • Le manifeste est validé avec kubectl apply --dry-run=server dans un espace de noms de développement.
  • Les journaux sont accessibles via votre pile de journalisation et surveillés pour les erreurs.
  • Le plan de retour en arrière est documenté et testé (par exemple, vous pouvez redéployer depuis le contrôle de version).
  • Le Job est idempotent ou sûr à réexécuter (pas d’effets secondaires en cas de double exécution).
  • completions et parallelism correspondent à la charge de travail (pas accidentellement laissés aux valeurs par défaut qui sur- ou sous-approvisionnent).
  • Les quotas de l’espace de noms et la capacité des nœuds sont suffisants pour le parallélisme de pointe.
  • Les permissions RBAC sont minimales mais suffisantes pour l’automatisation.
  • Le Job a des étiquettes appropriées pour l’identification et la surveillance (par exemple, app: billing-export).

Utilisez cette liste comme porte d’entrée dans votre pipeline CI/CD ou comme document de revue pour les déploiements manuels.

Conclusion

Les Jobs Kubernetes sont puissants, mais les erreurs de configuration sont courantes et peuvent entraîner des échecs silencieux, des relances infinies ou l’épuisement des ressources. En suivant un chemin de configuration sécurisé, en validant avec des dry-runs, en définissant des limites de ressources et des délais, et en surveillant les événements, vous pouvez exécuter des Jobs de manière fiable en production.

N’oubliez pas de commencer par un pilote étroit, de valider localement et d’établir des habitudes de surveillance et de retour en arrière. Révisez régulièrement vos configurations de Jobs pour éviter toute dérive. Avec ces pratiques, vos charges de travail par lots s’exécuteront sans heurts, et en cas d’échec, vous saurez exactement comment diagnostiquer et récupérer.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 97%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO