>
E-NO
Kubernetes 7 min de lecture

Architecture des CronJobs Kubernetes expliquée avec des exemples pratiques

calendar_today Publié : 2026-08-26
update Dernière mise à jour : 2026-08-26
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Architecture des CronJobs Kubernetes expliquée avec des exemples pratiques ».

Introduction

Les CronJobs Kubernetes vous permettent d'exécuter des Jobs selon un calendrier précis, tout comme l'utilitaire cron classique d'Unix. Ils prennent en charge des tâches récurrentes telles que les sauvegardes nocturnes de bases de données, la génération de rapports, la rotation des journaux, le renouvellement de certificats et la synchronisation périodique de données. Mais derrière cette simple chaîne de planification se cache un petit système distribué : le contrôleur de CronJob surveille le temps, crée des Jobs, et ces Jobs créent à leur tour des Pods. Si vous méconnaissez cette chaîne, vous verrez des exécutions manquées, des exécutions dupliquées ou des échecs silencieux.

Cet article explique l'architecture des CronJobs en termes pratiques pour les développeurs, ingénieurs DevOps et équipes techniques de startups. Vous apprendrez les composants clés, comment les données circulent de la planification au Pod, comment le contrôleur prend des décisions et comment exploiter les CronJobs en toute sécurité. Chaque section inclut des commandes kubectl concrètes, les sorties attendues, les signaux de défaillance et les étapes de récupération. À la fin, vous serez en mesure de concevoir, vérifier et dépanner des CronJobs en toute confiance.

Nous mettons l'accent sur la sécurité opérationnelle : observez avant de modifier, limitez le rayon d'impact, évitez d'intégrer des secrets, vérifiez les résultats et documentez les chemins de récupération. L'article suppose un cluster Kubernetes fonctionnel (version 1.21 ou ultérieure pour l'API stable des CronJobs batch/v1) et un kubectl configuré avec les permissions appropriées.

Inventaire de la version et de l'environnement

Avant de toucher à un CronJob, vous devez avoir une vision claire de votre environnement. Cela évite les incompatibilités de versions et les surprises liées aux permissions. L'API CronJob est stable depuis Kubernetes 1.21 (batch/v1). Les versions antérieures utilisaient batch/v1beta1, qui a été supprimée. Utilisez kubectl api-versions pour confirmer :

kubectl api-versions | grep batch

La sortie attendue inclut batch/v1. Si vous ne voyez que batch/v1beta1, mettez à niveau votre cluster ou utilisez un manifeste compatible.

Ensuite, vérifiez que le contrôleur de CronJob est en cours d'exécution. Il fait partie du kube-controller-manager, généralement un Pod statique dans l'espace de noms kube-system :

kubectl get pods -n kube-system | grep controller-manager

Recherchez un Pod nommé quelque chose comme kube-controller-manager-<node-name> avec le statut Running et tous les conteneurs prêts. S'il plante, tout le système de planification est en panne. Récupérez les journaux :

kubectl logs -n kube-system kube-controller-manager-<node-name>

Les signaux de défaillance courants incluent des erreurs RBAC (« interdit »), des problèmes d'élection de leader ou des indicateurs mal configurés.

Vérifiez également vos permissions utilisateur. Vous avez besoin de create, get, list et watch sur les cronjobs et jobs dans votre espace de noms :

kubectl auth can-i create cronjobs --namespace default
kubectl auth can-i list jobs --namespace default

Les deux doivent renvoyer yes. Sinon, demandez à votre administrateur de cluster d'attacher un rôle avec ces permissions.

Enfin, répertoriez les CronJobs existants pour éviter les collisions de noms ou les chevauchements indésirables :

kubectl get cronjobs --all-namespaces

Prenez note des planifications, des jobs actifs et de l'heure de la dernière planification. Pour un CronJob spécifique, utilisez :

kubectl get cronjob <name> -o yaml

Cela montre la spécification complète, le statut et éventuellement la dernière configuration appliquée. Capturez cela comme référence avant d'apporter toute modification.

Question rapide 1 sur 2

Pourquoi les Jobs définis dans un CronJob devraient-ils être idempotents ?

La référence indique : « Kubernetes essaie d'éviter ces situations, mais ne les empêche pas complètement. Par conséquent, les Jobs que vous définissez doivent être idempotents. »

Chemin de configuration sûr

Un manifeste de CronJob définit la planification, le modèle de Job et les politiques d'exécution. Un exemple minimal exécute un conteneur busybox chaque minute qui affiche un horodatage et se termine :

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello-cron
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: hello
            image: busybox:1.36
            command: ["/bin/sh", "-c", "date; echo Hello from CronJob"]

Écrivez ceci dans hello-cron.yaml et appliquez :

kubectl apply -f hello-cron.yaml

Sortie attendue :

cronjob.batch/hello-cron created

Vérifiez le statut du CronJob :

kubectl get cronjob hello-cron

Colonnes de sortie : NAME, SCHEDULE, SUSPEND, ACTIVE, LAST SCHEDULE, AGE. Initialement, ACTIVE vaut 0 et LAST SCHEDULE est <none>. Attendez jusqu'à une minute, puis exécutez à nouveau :

NAME        SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello-cron  */1 * * * *   False     0        15s             2m

Maintenant, un horodatage LAST SCHEDULE apparaît. Le CronJob crée un Job avec un nom comme hello-cron-<unix-timestamp> ou un suffixe plus lisible selon la version. Listez les Jobs :

kubectl get jobs

Vous devriez voir un Job par exécution planifiée. Chaque Job crée un Pod :

kubectl get pods

Recherchez les noms de Pod commençant par hello-cron-.... Une fois le Job terminé, le Pod reste à l'état Completed (si successfulJobsHistoryLimit le permet). Récupérez les journaux :

kubectl logs <pod-name>

La sortie attendue inclut la date et « Hello from CronJob ».

Une décision de conception clé est la restartPolicy. Pour les Pods de Job, elle doit être OnFailure ou Never (pas Always). OnFailure redémarre le conteneur sur le même Pod ; Never démarre un nouveau Pod. Pour les tâches idempotentes, Never peut éviter les redémarrages partiels. Pour les calculs de longue durée qui pourraient être interrompus, OnFailure est souvent plus efficace.

Utilisez concurrencyPolicy pour contrôler les exécutions qui se chevauchent. La valeur par défaut Allow permet à plusieurs Jobs du même CronJob de s'exécuter simultanément. Forbid saute une exécution planifiée si le Job précédent est encore actif. Replace annule le Job actif et en démarre un nouveau. Choisissez en fonction de votre charge de travail : les sauvegardes veulent généralement Forbid ; les videurs de file d'attente peuvent tolérer Allow.

startingDeadlineSeconds est un autre champ critique. Si le contrôleur est en panne lorsqu'une planification se déclenche, par défaut, il créera quand même le Job à son retour, tant que la date limite n'est pas dépassée. Définissez startingDeadlineSeconds: 200 pour ignorer les exécutions en retard de plus de 200 secondes. Cela évite un afflux de Jobs de rattrapage après une panne.

Enfin, limitez l'historique conservé pour éviter l'encombrement :

spec:
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1

Cela ne conserve que les 3 derniers Jobs réussis et 1 Job échoué pour inspection. Ajustez selon vos besoins d'audit.

Vérification et diagnostic

Une fois qu'un CronJob est en cours d'exécution, vérifiez qu'il fait réellement ce que vous attendez. Commencez par le statut du CronJob lui-même :

kubectl describe cronjob hello-cron

Regardez la section Events pour des messages comme « Saw completed job » ou « Cannot determine if job needs to be started ». Le statut affiche également Last Schedule Time et les Jobs Active. Si Active est non nul pendant longtemps, un Job est bloqué.

Examinez le dernier Job :

kubectl get jobs --sort-by=.metadata.creationTimestamp
kubectl describe job <job-name>

La description du Job montre les statuts des Pods, les nombres de complétions et les événements. Si un Job échoue, examinez ses Pods :

kubectl get pods --selector=job-name=<job-name>
kubectl describe pod <pod-name>

Champs clés : State (Running, Terminated, Waiting), Reason (Completed, Error, CrashLoopBackOff) et Events (ordonnancement, extraction, démarrage). Pour un conteneur qui a planté, récupérez les journaux :

kubectl logs <pod-name> --previous

L'indicateur --previous récupère les journaux de l'instance précédente du conteneur, ce qui est essentiel pour diagnostiquer les boucles de crash.

Modèles de défaillance courants :

  • ImagePullBackOff : L'image du conteneur n'existe pas ou les informations d'identification du registre sont manquantes. Vérifiez le champ image et assurez-vous que les imagePullSecrets sont corrects.
  • CrashLoopBackOff : Le conteneur se termine avec un code non nul. Inspectez les journaux pour les erreurs d'application.
  • DeadlineExceeded : Le Job dépasse activeDeadlineSeconds. Augmentez la date limite ou optimisez la tâche.
  • Échecs de Pod inattendus : Examinez les limites de ressources et la capacité du nœud. Utilisez kubectl describe node pour voir les conditions de pression.

Vérifiez également la planification elle-même. Kubernetes utilise la syntaxe cron standard : minute heure jour-du-mois mois jour-de-la-semaine. Erreurs courantes :

  • Utiliser * pour le jour du mois et le jour de la semaine lorsque vous voulez un jour spécifique.
  • Mal comprendre les fuseaux horaires : par défaut, le contrôleur utilise UTC, sauf si spec.timeZone est défini (Kubernetes 1.27+).
  • Chevauchement des planifications ou absence de startingDeadlineSeconds causant des exécutions manquées.

Pour simuler une exécution sans attendre, vous pouvez créer manuellement un Job à partir du modèle de Job du CronJob :

kubectl create job --from=cronjob/hello-cron manual-test-1

Cela crée un Job nommé manual-test-1 en utilisant le même modèle de Pod. Observez son résultat avant la prochaine exécution planifiée.

Question rapide 2 sur 2

Que se passe-t-il si `startingDeadlineSeconds` est défini sur une valeur inférieure à 10 secondes ?

La référence indique : « Si `startingDeadlineSeconds` est défini sur une valeur inférieure à 10 secondes, le CronJob peut ne pas être planifié. Cela est dû au fait que le contrôleur CronJob vérifie les choses toutes les 10 secondes. »

Modes de défaillance et récupération

Les CronJobs échouent de manière prévisible. Comprendre ces modes vous aide à récupérer rapidement.

Planifications manquées

Si le contrôleur est en panne ou si le serveur API est injoignable, les exécutions planifiées peuvent être manquées. Le contrôleur utilise startingDeadlineSeconds (par défaut aucune date limite) pour décider de créer un Job en retard. Sans date limite, un CronJob peut créer de nombreux Jobs de rattrapage, submergeant le cluster. Définissez startingDeadlineSeconds sur une valeur légèrement supérieure à votre temps d'arrêt prévu. Par exemple, si vous tolérez 5 minutes de planifications manquées, définissez startingDeadlineSeconds: 300.

Pour détecter les planifications manquées, comparez LAST SCHEDULE avec l'heure actuelle. Si l'écart dépasse votre tolérance, examinez la santé du contrôleur et les journaux du serveur API.

Exécutions qui se chevauchent

Si un Job prend plus de temps que l'intervalle entre les planifications, plusieurs Jobs peuvent s'exécuter simultanément. Cela peut provoquer des verrous de base de données, des effets secondaires dupliqués ou un épuisement des ressources. Définissez concurrencyPolicy: Forbid ou Replace selon le cas. Pour un Job de sauvegarde qui prend 3 minutes mais s'exécute toutes les 5 minutes, Forbid empêche le chevauchement si le précédent est encore en cours.

Jobs bloqués à l'état Active

Un Job peut ne jamais se terminer parce qu'un Pod est bloqué en Pending (pas de ressources) ou Running (blocage de l'application). Vérifiez le Pod avec kubectl describe pod et recherchez les événements. Si le Pod est en attente en raison d'un manque de CPU/mémoire, réduisez les demandes ou faites évoluer les nœuds. S'il est en cours d'exécution mais ne progresse pas, vérifiez les journaux de l'application et envisagez de définir activeDeadlineSeconds pour forcer la terminaison.

Exemple : définissez activeDeadlineSeconds: 600 pour tuer tout Job qui s'exécute plus de 10 minutes. Le Job sera marqué comme échoué, et vous pourrez inspecter l'état final du Pod.

Plantages de Pod et nouvelles tentatives

La restartPolicy interagit avec les nouvelles tentatives. Avec OnFailure, le conteneur redémarre jusqu'à backoffLimit fois (par défaut 6) avant que le Job ne soit marqué comme échoué. Avec Never, chaque nouvelle tentative crée un nouveau Pod, jusqu'à backoffLimit Pods. Ajustez backoffLimit pour éviter des tentatives infinies. Pour un appel API instable, backoffLimit: 3 est raisonnable.

Après l'échec d'un Job, le CronJob créera un nouveau Job lors de la prochaine planification, pas immédiatement. Si vous avez besoin d'une nouvelle exécution immédiate, créez manuellement un Job à partir du CronJob comme indiqué précédemment.

CronJobs suspendus

Si vous définissez spec.suspend: true, le contrôleur de CronJob cesse de créer des Jobs. Les Jobs actifs continuent de s'exécuter. C'est utile pour les fenêtres de maintenance. Pour reprendre, définissez suspend: false :

kubectl patch cronjob hello-cron -p '{"spec":{"suspend":false}}'

Vérifiez avec kubectl get cronjob hello-cron que SUSPEND est False.

Liste de contrôle de récupération

  1. Vérifiez la santé du contrôleur : kubectl get pods -n kube-system | grep controller-manager
  2. Vérifiez le statut du CronJob : kubectl get cronjob <name> -o wide
  3. Listez les Jobs : kubectl get jobs --selector=job-name=<name-pattern>
  4. Décrivez le Job et le Pod problématiques
  5. Inspectez les journaux des conteneurs actuels et précédents
  6. Ajustez les champs du manifeste : startingDeadlineSeconds, concurrencyPolicy, backoffLimit, activeDeadlineSeconds, suspend
  7. Appliquez les modifications et observez la prochaine exécution planifiée

Liste de contrôle des opérations

Utilisez cette liste de contrôle pour une exploitation et un dépannage sûrs des CronJobs. Remplacez les espaces réservés par vos valeurs spécifiques.

Pré-déploiement

  • [ ] Confirmez que la version du cluster prend en charge les CronJobs batch/v1 (Kubernetes >=1.21).
  • [ ] Vérifiez que kube-controller-manager est en cours d'exécution et en bonne santé.
  • [ ] Assurez-vous que les permissions RBAC permettent de créer des CronJobs, des Jobs et des Pods.
  • [ ] Passez en revue la syntaxe de planification et le fuseau horaire (UTC par défaut).
  • [ ] Définissez explicitement concurrencyPolicy ; ne vous fiez pas à la valeur par défaut.
  • [ ] Définissez startingDeadlineSeconds pour éviter les tempêtes d'exécutions manquées.
  • [ ] Définissez successfulJobsHistoryLimit et failedJobsHistoryLimit sur des valeurs raisonnables.
  • [ ] Choisissez restartPolicy (OnFailure ou Never) et backoffLimit.
  • [ ] Pour les longs Jobs, définissez activeDeadlineSeconds pour éviter les emballements.
  • [ ] Évitez de stocker des secrets en texte brut ; utilisez les Secrets Kubernetes et référencez-les comme variables d'environnement ou volumes montés.

Exemple d'utilisation de Secret :

spec:
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: db-backup
            image: postgres:16
            env:
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password

Vérification post-déploiement

  • [ ] kubectl get cronjob <name> affiche la bonne planification et SUSPEND=False.
  • [ ] Après le premier intervalle planifié, LAST SCHEDULE est renseigné.
  • [ ] kubectl get jobs montre un Job associé au CronJob, et il atteint finalement le statut Complete.
  • [ ] kubectl get pods montre le Pod du Job à l'état Completed.
  • [ ] kubectl logs <pod-name> affiche la sortie attendue et aucune erreur.
  • [ ] Si vous utilisez un Service ou une ingress, vérifiez la connectivité avec kubectl port-forward ou curl avant de dépendre du trafic externe.

Surveillance continue

  • [ ] Vérifiez quotidiennement le statut des CronJobs : kubectl get cronjobs --all-namespaces.
  • [ ] Surveillez les Jobs actifs qui ne se terminent jamais (indique des Jobs bloqués).
  • [ ] Passez en revue les limites de l'historique des Jobs pour éviter les fuites de ressources.
  • [ ] Configurez des alertes sur les échecs de Jobs à l'aide de Prometheus ou d'observateurs d'événements.
  • [ ] Testez périodiquement la récupération en simulant une exécution échouée (par exemple, image volontairement mauvaise) et en parcourant le diagnostic.

Conclusion

Les CronJobs Kubernetes offrent un moyen puissant de planifier des charges de travail récurrentes, mais leur fiabilité dépend de la compréhension des mécanismes du contrôleur et de l'application de pratiques de configuration sûres. En inventoriant votre environnement, en rédigeant des manifestes explicites, en vérifiant les exécutions avec des commandes et en vous préparant aux modes de défaillance courants, vous pouvez éviter les pièges des planifications manquées, des Jobs qui se chevauchent et des échecs silencieux.

Cet article vous a fourni un cadre pratique : observez l'état, apportez des modifications ciblées, vérifiez les résultats et documentez les chemins de récupération. Les exemples et les listes de contrôle sont destinés à être adaptés à vos charges de travail et politiques de cluster spécifiques.

Comme prochaine étape, prenez un CronJob à faible risque dans votre environnement, appliquez la section Vérification et diagnostic, et pratiquez un scénario de défaillance en le configurant volontairement mal dans un espace de noms de test. Enregistrez vos conclusions et ajustez votre manuel opérationnel en conséquence. N'oubliez pas qu'un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite le rayon d'impact et définit la récupération avant qu'un incident ne force la décision.

Recherches connexes

Score de qualité de l’article

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