E-NO
Kubernetes 7 min de lecture

Mise à niveau et migration des CronJobs Kubernetes : guide pratique d'implémentation

calendar_today Publié : 2026-08-23
update Dernière mise à jour : 2026-08-23
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Mise à niveau et migration des CronJobs Kubernetes : guide pratique d'implémentation ».

Intro

Mettre à niveau des CronJobs Kubernetes ou les migrer entre clusters est rarement un simple kubectl apply. Les opérations de niveau production exigent une séquence qui commence par observer l'état actuel, documente le plus petit changement réversible, et se termine par des commandes de vérification concrètes où le résultat attendu est connu à l'avance. Cet article est un guide pratique de cette séquence exacte.

Vous y trouverez un flux de travail complet couvrant l'inventaire des versions, les changements de manifeste depuis l'API dépréciée batch/v1beta1 vers l'API stable batch/v1, la configuration sûre, la validation, les modes de défaillance avec restauration, et une liste de contrôle opérationnelle. Chaque section inclut des commandes réelles, des extraits YAML d'exemple, des sorties attendues et des critères de décision, afin que vous puissiez adapter les étapes à votre propre environnement.

Le public visé est les développeurs, ingénieurs DevOps, SRE et équipes techniques de startups qui exécutent des tâches planifiées dans Kubernetes. L'accent est mis sur les CronJobs spécifiquement, mais les préoccupations environnantes (version du cluster, registre de conteneurs, pipelines CI/CD) sont incluses lorsqu'elles impactent directement la sécurité de la mise à niveau.

Avant d'appliquer quoi que ce soit à un cluster partagé, créez un namespace jetable pour vos tests à blanc. Cela limite le rayon d'impact et vous permet de tester le chemin de migration complet sans toucher aux charges de travail de production.

kubectl create namespace cronjob-migration-test
kubectl config set-context --current --namespace=cronjob-migration-test

Vous avez maintenant un terrain de jeu sûr pour suivre chaque exemple ci-dessous.

Inventaire des versions et de l'environnement

La première étape de toute mise à niveau ou migration de CronJob est de savoir exactement ce que vous exécutez. L'API CronJob de Kubernetes a évolué au fil du temps : batch/v1beta1 était la version originale de l'API, dépréciée depuis Kubernetes 1.21, et supprimée dans Kubernetes 1.25. L'API stable batch/v1 est disponible depuis Kubernetes 1.21. Votre chemin de migration dépend fortement de la version de cluster que vous exécutez et des objets CronJob que vous avez.

Visez une migration propre vers batch/v1. Voici le tableau des phases :

Version du clusterStatut de batch/v1beta1Statut de batch/v1Action de migration requise
< 1.21DisponibleNon disponibleMettre à niveau le cluster d'abord, puis migrer les CronJobs
1.21 - 1.24DépréciéeDisponibleMigrer les CronJobs vers batch/v1 avant la mise à niveau du cluster vers 1.25
>= 1.25SuppriméeDisponibleTous les CronJobs doivent être en batch/v1

Si vous êtes sur Kubernetes 1.24 ou antérieur, vous pouvez toujours lire les CronJobs batch/v1beta1 avec le serveur d'API. À partir de 1.25, les requêtes à l'ancien point de terminaison échouent avec une erreur 404. Si votre outillage GitOps ou votre pipeline CI/CD référence encore l'ancienne API, ces manifestes échoueront à s'appliquer après la mise à niveau du cluster.

Vérifier la version du cluster et la disponibilité de l'API

D'abord, capturez la version du cluster. Cela détermine si l'ancienne API est encore servie.

kubectl version --short
# Exemple de sortie sur 1.24 :
# Client Version: v1.24.10
# Server Version: v1.24.10

Pour voir quelles versions d'API sont disponibles pour les CronJobs dans votre cluster, utilisez kubectl api-versions.

kubectl api-versions | grep batch
# Exemple de sortie sur 1.24 :
# batch/v1
# batch/v1beta1
# Sur 1.25+, seule batch/v1 apparaît.

Ne présumez pas de la disponibilité uniquement à partir de la version du cluster : une API peut être désactivée via des feature gates ou des drapeaux du serveur d'API. La commande api-versions est la vérité terrain.

Lister tous les CronJobs existants et leurs versions d'API

Maintenant, énumérez chaque CronJob dans tous les namespaces, y compris la version d'API stockée dans chaque objet. Utilisez kubectl get cronjobs avec une sortie large.

kubectl get cronjobs --all-namespaces -o wide
# Exemple de sortie :
# NAMESPACE   NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE   CONTAINERS   IMAGES
# default     db-backup    0 2 * * *    False     0        3m              12d   backup       postgres:15

La sortie -o wide ne montre pas la version d'API. Pour la capturer, utilisez une requête JSON.

kubectl get cronjobs --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{" apiVersion="}{.apiVersion}{"\n"}{end}'
# Exemple de sortie :
# default/db-backup apiVersion=batch/v1beta1
# default/reports apiVersion=batch/v1

Écrivez cette sortie dans un fichier. Cela devient votre inventaire de migration :

kubectl get cronjobs --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{" apiVersion="}{.apiVersion}{"\n"}{end}' > cronjob-inventory.txt
cat cronjob-inventory.txt

Évaluer la santé spécifique des CronJobs

Avant de modifier quoi que ce soit, vérifiez que les CronJobs existants fonctionnent réellement. Décrivez-en un pour voir ses événements récents.

kubectl describe cronjob db-backup -n default
# Cherchez la section Events :
# Events:
#   Type    Reason             Age   From                Message
#   ----    ------             ----  ----                -------
#   Normal  SuccessfulCreate   3m    cronjob-controller  Created job db-backup-28463140
#   Normal  SawCompletedJob    2m    cronjob-controller  Saw completed job: db-backup-28463140, status: Complete

S'il n'y a pas d'événements, ou si les événements montrent des échecs, corrigez le problème sous-jacent avant de tenter une migration d'API. Migrer un CronJob cassé ne fait que changer sa version d'API, pas son comportement.

Capturer l'état actuel pour la restauration

Ayez toujours un moyen de revenir en arrière. Stockez les manifestes actuels dans un répertoire versionné :

mkdir -p cronjob-backup/pre-migration
kubectl get cronjob db-backup -n default -o yaml > cronjob-backup/pre-migration/db-backup.yaml

Si votre CronJob a été créé via Helm ou un autre outil, ne vous fiez pas uniquement à l'objet vivant ; conservez également les valeurs de chart ou les manifestes d'origine. Pour une restauration manuelle, appliquer le YAML sauvegardé est le chemin le plus rapide.

Chemin de configuration sûr

Une fois que vous avez l'inventaire et une sauvegarde, l'étape suivante est de définir la configuration cible. L'objectif principal est de migrer le manifeste CronJob de batch/v1beta1 vers batch/v1. Le CronJob batch/v1 est structurellement identique à la bêta, donc le changement est généralement limité au champ apiVersion. Cependant, certains clusters ont des règles de validation ou de défaut supplémentaires, donc un dry-run est recommandé.

Exemple : migration d'un manifeste CronJob

Voici un CronJob batch/v1beta1 typique :

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: reports
  namespace: production
spec:
  schedule: "0 1 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: report-generator
            image: registry.example.com/reports:1.4.2
            command: ["/usr/local/bin/generate-report"]
            env:
            - name: REPORT_BUCKET
              value: "s3://reports-archive"
            resources:
              requests:
                cpu: 100m
                memory: 128Mi
              limits:
                cpu: 500m
                memory: 512Mi

Pour migrer, changez apiVersion en batch/v1.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: reports
  namespace: production
spec:
  schedule: "0 1 * * *"
  # ... tout le reste demeure identique

Utiliser kubectl apply avec --dry-run=client ou --dry-run=server

Avant d'appliquer au cluster vivant, validez le manifeste. --dry-run=client vérifie la syntaxe YAML et le schéma de base. --dry-run=server envoie la requête au serveur d'API sans la persister, ce qui est la validation la plus précise possible.

kubectl apply -f reports-cronjob.yaml --dry-run=server
# Sortie attendue (si valide) :
# cronjob.batch/reports created (server dry run)
# Si la version d'API est supprimée, vous obtenez :
# error: unable to recognize "reports-cronjob.yaml": no matches for kind "CronJob" in version "batch/v1beta1"

Si le dry-run serveur réussit, vous pouvez appliquer pour de vrai. S'il échoue, inspectez le message d'erreur et ajustez le manifeste en conséquence. Ne sautez jamais cette étape ; elle détecte instantanément les incompatibilités de version, les champs manquants et les valeurs invalides.

Définir explicitement concurrencyPolicy et les limites d'historique

Une mise à niveau ou migration de CronJob est un bon moment pour revoir la spec. Deux champs causent souvent des surprises en production :

  • concurrencyPolicy: Forbid empêche les exécutions qui se chevauchent. La valeur par défaut est Allow, ce qui peut conduire à des jobs dupliqués si une exécution déborde.
  • successfulJobsHistoryLimit et failedJobsHistoryLimit contrôlent combien d'objets Job terminés sont conservés. Les valeurs par défaut sont 3 et 1, ce qui est généralement bien. Les mettre trop bas supprime un historique d'audit utile ; trop haut encombre le cluster.

Exemple de spec de CronJob renforcée :

spec:
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 5
  failedJobsHistoryLimit: 3
  startingDeadlineSeconds: 300
  jobTemplate:
    spec:
      backoffLimit: 4
      activeDeadlineSeconds: 3600

startingDeadlineSeconds: 300 signifie que si le contrôleur CronJob rate le démarrage planifié de plus de 5 minutes (par exemple, le contrôleur était en panne), il n'exécutera pas cette itération, évitant une rafale de jobs de rattrapage. backoffLimit et activeDeadlineSeconds bornent les propres tentatives du job et sa durée totale.

Vérifier avec un test local

Pour être encore plus prudent, appliquez le CronJob migré dans un namespace séparé d'abord et déclenchez manuellement un job pour le voir fonctionner de bout en bout.

kubectl create namespace cronjob-migration-test
kubectl apply -f reports-cronjob.yaml -n cronjob-migration-test
# Ensuite créez un job de test à partir du CronJob en utilisant kubectl create job --from
kubectl create job manual-reports-test --from=cronjob/reports -n cronjob-migration-test
# Surveillez l'exécution du job
kubectl get jobs -n cronjob-migration-test
# NAME                  COMPLETIONS   DURATION   AGE
# manual-reports-test   1/1           42s        42s

Si le job de test réussit, votre configuration CronJob est valide sous la nouvelle version d'API. S'il échoue, inspectez les journaux et événements pour corriger le problème avant de migrer le CronJob de production.

Vérification et diagnostics

Après avoir appliqué le CronJob migré, vous devez vérifier qu'il est correctement configuré et qu'il s'exécutera comme prévu. La vérification ne consiste pas seulement à vérifier que la ressource existe ; c'est confirmer que le calendrier est interprété correctement, que le contrôleur peut créer des jobs, et que ces jobs se terminent avec succès.

Vérifier l'objet CronJob

D'abord, confirmez que le CronJob utilise maintenant batch/v1.

kubectl get cronjob reports -n production -o jsonpath='{.apiVersion}{"\n"}'
# Attendu : batch/v1

Ensuite, examinez le calendrier calculé. Une erreur courante est de définir une chaîne de calendrier que Kubernetes interprète différemment de l'intention. Le contrôleur CronJob utilise le format cron standard à cinq champs (minute heure jour-du-mois mois jour-de-la-semaine). Utilisez kubectl describe pour voir le calendrier et l'heure de dernière planification.

kubectl describe cronjob reports -n production
# Extrait de sortie :
# Schedule:   0 1 * * *
# Concurrency Policy: Forbid
# Suspend:     False
# Last Schedule Time:  2025-03-12T01:00:00Z

Si Suspend est True, le CronJob ne s'exécutera jamais. Aussi, vérifiez Last Schedule Time pour voir si le contrôleur a planifié activement des jobs. Si l'heure de dernière planification est ancienne et qu'aucun job n'existe, examinez les journaux du contrôleur.

Surveiller la création et la fin des jobs

Déclenchez manuellement un job à partir du CronJob pour simuler l'exécution normale. Cela valide le modèle de job sans attendre la prochaine heure planifiée.

kubectl create job reports-manual-test --from=cronjob/reports -n production
kubectl get jobs -n production
# NAME                  COMPLETIONS   DURATION   AGE
# reports-manual-test   1/1           35s        35s

Si le job ne se termine pas, inspectez les journaux du pod et les événements.

kubectl logs jobs/reports-manual-test -n production
# Si le pod est dans une boucle de crash, obtenez les journaux précédents :
kubectl logs jobs/reports-manual-test -n production --previous

Vérifier la santé du contrôleur CronJob

Le contrôleur CronJob fait partie du kube-controller-manager. S'il n'est pas en cours d'exécution ou n'est pas sain, aucun CronJob ne sera planifié. Vérifiez son statut en regardant les pods du gestionnaire de contrôleurs dans le namespace kube-system.

kubectl get pods -n kube-system | grep controller-manager
# Sortie attendue (varie selon le cluster) :
# kube-controller-manager-control-plane  1/1     Running   0          42d

Si le gestionnaire de contrôleurs est dans une boucle de crash, vérifiez ses journaux pour les erreurs liées à la synchronisation CronJob.

kubectl logs -n kube-system kube-controller-manager-control-plane | grep -i cronjob

Valider les fuseaux horaires et la sémantique de planification

Les CronJobs Kubernetes ne supportent pas CRON_TZ. Le calendrier est toujours évalué dans le fuseau horaire du contrôleur, qui est généralement UTC. Si vous avez besoin qu'un job s'exécute à une heure locale spécifique, convertissez vous-même l'heure en UTC. Par exemple, pour s'exécuter à 1h00 heure normale de l'Est (UTC-5), le calendrier devrait être 0 6 * en UTC. Soyez explicite dans votre documentation pour éviter toute confusion.

Modes de défaillance et récupération

Même avec une planification minutieuse, les mises à niveau et migrations peuvent échouer. Cette section couvre les modes de défaillance les plus courants pour la migration de CronJob et fournit des étapes de récupération concrètes.

Défaillance : version d'API supprimée avant la migration

Si vous essayez d'appliquer un CronJob batch/v1beta1 sur un cluster Kubernetes 1.25+, le serveur d'API le rejette.

kubectl apply -f old-cronjob.yaml
# Sortie d'erreur :
# error: unable to recognize "old-cronjob.yaml": no matches for kind "CronJob" in version "batch/v1beta1"

Récupération : Modifiez le manifeste pour utiliser apiVersion: batch/v1 et appliquez à nouveau. Si vous avez de nombreux manifestes, utilisez un rechercher-remplacer dans votre dépôt ou un outil comme kubectl convert (s'il est encore disponible) pour convertir en masse. N'essayez pas d'utiliser l'ancienne API en rétrogradant le cluster ; ce n'est pas un chemin supporté.

Défaillance : le modèle de job référence une ConfigMap ou un Secret manquant

L'application du CronJob réussit, mais lorsqu'un job est créé, le pod échoue avec CreateContainerConfigError ou InvalidImageName.

kubectl describe pod reports-manual-test-abcde -n production
# Events:
#   Warning  Failed     10s (x2 over 30s)  kubelet  Error: configmap "report-config" not found

Récupération : Recréez la ConfigMap ou le Secret manquant dans le namespace cible. Assurez-vous que le namespace du CronJob correspond à l'endroit où vivent les objets de configuration. Si vous avez migré un CronJob vers un nouveau cluster, vous devez migrer également ses dépendances (ConfigMaps, Secrets, ServiceAccounts, PersistentVolumeClaims, etc.).

Défaillance : permissions ServiceAccount incorrectes

Après une migration inter-cluster, le ServiceAccount référencé dans le CronJob peut ne pas exister ou manquer de permissions RBAC. Le pod démarre mais le job échoue avec des erreurs d'autorisation.

kubectl logs jobs/reports-manual-test -n production
# Exemple d'erreur :
# Error from server (Forbidden): configmaps is forbidden: User "system:serviceaccount:production:reports-sa" cannot list resource "configmaps" in API group "" in the namespace "production"

Récupération : Créez le ServiceAccount et les liaisons Role ou ClusterRole nécessaires dans le nouveau cluster. Utilisez kubectl auth can-i --list --as=system:serviceaccount:production:reports-sa -n production pour auditer les permissions.

Défaillance : l'évaluation du calendrier conduit à des exécutions inattendues

Après la migration, le CronJob s'exécute à des heures inattendues. Les causes courantes incluent la confusion des fuseaux horaires ou une chaîne de calendrier qui était précédemment définie et se comporte maintenant différemment en raison des mises à niveau du contrôleur.

Récupération : Revoyez la chaîne de calendrier dans le manifeste et calculez les prochaines exécutions à l'aide d'un outil comme crontab.guru ou un analyseur cron local. Si le calendrier est incorrect, corrigez le manifeste et appliquez à nouveau. Si le calendrier est correct mais que les exécutions sont toujours décalées, vérifiez le fuseau horaire du contrôleur et ajustez le calendrier en conséquence.

Défaillance : chevauchements ou problèmes de concurrence

Si concurrencyPolicy est réglé sur Allow (par défaut) et que les jobs prennent plus de temps que l'intervalle de planification, plusieurs jobs peuvent s'exécuter simultanément, provoquant une contention des ressources ou une corruption des données.

Récupération : Réglez concurrencyPolicy: Forbid pour empêcher les exécutions qui se chevauchent. Si vous devez autoriser un certain chevauchement mais pas illimité, utilisez Replace pour tuer le job existant avant d'en démarrer un nouveau. Appliquez le changement et surveillez la prochaine exécution planifiée.

Procédure de restauration

Si une migration cause des problèmes imprévus (par exemple, un bogue dans la nouvelle image, ou un job se comporte différemment sous la nouvelle API), vous devez restaurer. Parce que les specs de CronJob batch/v1 et batch/v1beta1 sont identiques dans la plupart des champs, restaurer la version d'API est trivial : réappliquez le manifeste de sauvegarde enregistré (qui a l'ancienne apiVersion) si le cluster le supporte encore. Pour les clusters qui ne servent plus l'ancienne API, vous ne pouvez pas revenir à batch/v1beta1 ; vous devez plutôt corriger le problème tout en restant sur batch/v1.

Étapes de restauration :

  1. Suspendez le CronJob immédiatement pour arrêter la création de nouveaux jobs.
   kubectl patch cronjob reports -n production -p '{"spec":{"suspend":true}}'
  1. Revenez à un manifeste précédent de votre répertoire de sauvegarde.
   kubectl apply -f cronjob-backup/pre-migration/db-backup.yaml
  1. Vérifiez la restauration en contrôlant la version d'API et le calendrier.
   kubectl get cronjob db-backup -n production -o jsonpath='{.apiVersion}{"\n"}'
  1. Réactivez si la restauration est efficace et que vous voulez reprendre le fonctionnement normal.
   kubectl patch cronjob db-backup -n production -p '{"spec":{"suspend":false}}'

Ayez toujours un plan de restauration écrit avant de commencer la migration. En plein incident, vous n'aurez pas le temps de vous souvenir des commandes exactes.

Liste de contrôle opérationnelle

Utilisez la liste de contrôle suivante pour exécuter une mise à niveau/migration de CronJob en toute sécurité. Chaque élément inclut la commande et le résultat attendu.

ÉtapeActionCommande / CritèreSortie / Signal attendu
1Enregistrer la version du clusterkubectl version --shortServer Version >= 1.21 pour batch/v1
2Confirmer la disponibilité de l'APIkubectl api-versions | grep batchbatch/v1 et batch/v1beta1 sur 1.21-1.24 ; seulement batch/v1 sur 1.25+
3Inventorier tous les CronJobskubectl get cronjobs --all-namespaces -o wideListe de tous les CronJobs avec versions d'API
4Sauvegarder les manifestes CronJob existantskubectl get cronjob <name> -n <ns> -o yaml > backup.yamlFichier YAML sauvegardé pour restauration
5Mettre à jour apiVersion en batch/v1 dans le manifesteModifier YAMLapiVersion: batch/v1
6Appliquer en dry-run sur le cluster ciblekubectl apply -f cronjob.yaml --dry-run=servercronjob.batch/<name> created (server dry run)
7Appliquer en productionkubectl apply -f cronjob.yamlcronjob.batch/<name> configured
8Vérifier la version d'APIkubectl get cronjob <name> -o jsonpath='{.apiVersion}'batch/v1
9Déclencher un job de test manuelkubectl create job <name>-test --from=cronjob/<name>Job créé et se termine avec succès
10Vérifier l'exécution planifiéeAttendre la prochaine planification ; kubectl get jobs -n <ns> montre un nouveau jobLe job s'exécute à l'heure prévue
11Surveiller les échecskubectl get jobs -n <ns> --watchAucun job échoué au-delà de backoffLimit
12Documenter le chemin de restaurationEnregistrer les commandes de restauration dans le runbookPrêt à exécuter si nécessaire

Après avoir terminé la liste de contrôle, faites une revue post-migration : comparez la nouvelle version d'API, le calendrier, la politique de concurrence et les limites de ressources avec les valeurs pré-migration pour vous assurer que rien n'a été modifié involontairement.

Conclusion

Les mises à niveau et migrations de CronJobs Kubernetes sont un processus contrôlé en plusieurs étapes, pas une seule commande. La clé du succès est d'observer avant de changer, de sauvegarder avant d'appliquer, de faire un dry-run avant de valider, et de vérifier après coup. L'API stable batch/v1 est disponible depuis Kubernetes 1.21, et la migration vers celle-ci est simple si vous suivez les étapes décrites : inventorier vos CronJobs, mettre à jour l'apiVersion, valider avec des dry-runs serveur, tester avec un job manuel, et avoir un plan de restauration.

Comme prochaine étape, choisissez un CronJob à faible risque dans un namespace non-production et passez par le processus complet de bout en bout. Enregistrez l'état actuel, mettez à jour le manifeste, appliquez, déclenchez un job de test, et vérifiez le résultat. Ensuite, documentez les commandes exactes que vous avez utilisées dans un runbook pour votre équipe. Ce n'est qu'après avoir confiance dans le processus que vous devriez migrer les CronJobs de production.

Un flux de travail de mise à niveau fiable rend les échecs visibles, protège les valeurs sensibles comme les secrets et les identifiants, limite les changements à la ressource prévue, et définit la vérification de récupération avant qu'un incident ne force la décision. En suivant ce guide, vous pouvez migrer vos CronJobs Kubernetes en toute sécurité et avec confiance.

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