Introduction
Les CronJobs Kubernetes exécutent des conteneurs à un horaire défini. Un Kubernetes CronJobs local lab vous permet d'expérimenter en toute sécurité, de reproduire des incidents et de gagner en confiance avant d'intervenir sur des environnements partagés. Dans ce guide, vous allez monter un cluster jetable, créer un namespace dédié, puis exécuter deux exemples concrets : un "echo" minutely et une petite tâche Python. Vous validerez la planification, le comportement de concurrence, les logs, les limites d'historique et les routines de nettoyage afin d'accélérer votre Kubernetes CronJobs testing et votre Kubernetes CronJobs development.
Vue d'ensemble du workflow
Pour garder vos essais propres et rapides, suivez ce flux :
- Créez un cluster local isolé.
- Créez un namespace et un ServiceAccount pour les CronJobs.
- Déployez un mini CronJob pilote à cadence rapide.
- Observez la création des Jobs et des Pods, les logs et l'historique.
- Exercez les contrôles : suspend, run-once, concurrencyPolicy, backoff.
- Ajoutez un deuxième exemple réaliste (Python) avec variables d'environnement et ressources.
- Dépannez les échecs via les events, Jobs et Pods.
- Ajoutez des garde-fous : limites de ressources, non-root, scripts de cleanup.
- Automatisez les vérifications courantes en one-liners ou scripts Bash.
- Réinitialisez ou supprimez rapidement le lab à la fin.
Plan pilote local
Objectif pilote : un CronJob par minute qui imprime l'horodatage et un message, garde un historique court, et interdit les chevauchements.
Critères de succès :
- En moins de 2 minutes, voir au moins un Job réussi.
- Pouvoir lire les logs du Pod du dernier Job.
- Aucun recouvrement d'exécutions.
- Savoir le suspendre puis le reprendre.
- Déclencher une exécution ponctuelle à la demande.
Ce périmètre réduit est rapide à mesurer et simple à inspecter en local avant tout déploiement plus large.
Créer un cluster local
Utilisez kind pour un cluster léger et jetable.
Créer le cluster :
kind create cluster --name cronlab
Pointer kubectl dessus :
kubectl cluster-info --context kind-cronlab
Vérifier les nœuds :
kubectl get nodes
Alternative : minikube start (si vous préférez minikube).
Namespace et ServiceAccount
Isolez votre lab dans un namespace et exécutez les Pods en non-root autant que possible.
Créez un namespace et un ServiceAccount (enregistrez sous ns-sa.yaml) :
---
apiVersion: v1
kind: Namespace
metadata:
name: cronlab
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cronjob-sa
namespace: cronlab
Appliquez :
kubectl apply -f ns-sa.yaml
Exemple 1 : job echo minutely
Un petit CronJob qui tourne chaque minute, interdit les chevauchements et garde un historique court. Enregistrez sous cron-echo.yaml :
apiVersion: batch/v1
kind: CronJob
metadata:
name: echo-minutely
namespace: cronlab
spec:
schedule: '* * * * *'
concurrencyPolicy: Forbid
startingDeadlineSeconds: 30
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 1
template:
metadata:
labels:
app: echo-minutely
spec:
serviceAccountName: cronjob-sa
restartPolicy: OnFailure
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: echo
image: busybox:1.36
imagePullPolicy: IfNotPresent
command: ['sh','-c','date; echo Hello from CronJob; sleep 5']
resources:
requests:
cpu: 10m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi
Appliquer et observer :
kubectl apply -f cron-echo.yaml
kubectl get cronjob -n cronlab
kubectl get jobs -n cronlab --watch
Obtenir les logs du Pod le plus récent :
kubectl get pods -n cronlab -l app=echo-minutely
kubectl logs -n cronlab <pod-name>
Suspendre et reprendre via un patch (plus robuste entre shells). Enregistrez suspend-true.yaml :
spec:
suspend: true
Puis :
kubectl patch cronjob echo-minutely -n cronlab --type merge --patch-file suspend-true.yaml
Repassez spec.suspend à false pour reprendre.
Exécuter une fois à la demande sans attendre l'horaire :
kubectl create job echo-now-1 --from=cronjob/echo-minutely -n cronlab
Utilisez un nouveau nom à chaque fois (echo-now-2, echo-now-3, ...).
Exemple 2 : Python ETL mock
Cet exemple simule une petite tâche de données toutes les 5 minutes, utilise des variables d'environnement, un stockage éphémère et des ressources modestes. Enregistrez sous cron-python.yaml :
apiVersion: batch/v1
kind: CronJob
metadata:
name: python-etl-mock
namespace: cronlab
spec:
schedule: '*/5 * * * *'
concurrencyPolicy: Replace
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 2
jobTemplate:
spec:
backoffLimit: 2
template:
metadata:
labels:
app: python-etl-mock
spec:
serviceAccountName: cronjob-sa
restartPolicy: OnFailure
containers:
- name: worker
image: python:3.11-slim
command: ['python','-c','import os, time, random, sys; print("starting job"); time.sleep(2); n=random.randint(0,9); print("processed", n, "records from", os.getenv("SOURCE_URL")); sys.exit(0)']
env:
- name: SOURCE_URL
value: 'file:///data/input.csv'
resources:
requests:
cpu: 20m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
volumeMounts:
- name: scratch
mountPath: /data
volumes:
- name: scratch
emptyDir: {}
Appliquer et vérifier :
kubectl apply -f cron-python.yaml
kubectl get cronjob -n cronlab
kubectl get jobs -n cronlab -l app=python-etl-mock
kubectl logs -n cronlab -l app=python-etl-mock -c worker --tail=50 --all-containers=false
Observabilité et dépannage
Vérifications courantes :
- Lister les CronJobs :
kubectl get cronjob -n cronlab
- Décrire un CronJob :
kubectl describe cronjob echo-minutely -n cronlab
- Surveiller les Jobs :
kubectl get jobs -n cronlab --watch
- Afficher les Pods d'un Job :
kubectl get pods -n cronlab -l job-name=<job-name>
- Logs d'un Pod :
kubectl logs -n cronlab <pod-name>
- Événements en cas d'échec :
kubectl describe job/<job-name> -n cronlab
Lancer un CronJob immédiatement sans attendre :
kubectl create job echo-now-1 --from=cronjob/echo-minutely -n cronlab
Répétez avec un nouveau nom (echo-now-2, echo-now-3, ...).
Simuler un échec pour tester le backoff en modifiant la commande vers un retour non nul (par exemple exit 1), puis observer les réessais et les events.
Sécurité et contrôle des ressources
Adoptez ces garde-fous dans votre lab et en production :
- concurrencyPolicy:
ForbidouReplacepour éviter les chevauchements. - startingDeadlineSeconds : éviter de rater des runs après une courte panne.
- backoffLimit : plafonner les réessais des Jobs en échec.
- successfulJobsHistoryLimit et failedJobsHistoryLimit : maîtriser la taille des listes.
- Demandes/limites de ressources : éviter les "noisy neighbors" en local.
- securityContext :
runAsNonRoot,seccompProfile: RuntimeDefault. - Portée par namespace : garder les artefacts du lab contenus.
Nettoyage rapide :
kubectl delete ns cronlab
kind delete cluster --name cronlab
Automatiser et itérer en local
Regroupez les étapes du lab dans un script Bash ou un Makefile pour que vos collègues puissent tout monter, tester et démonter en quelques commandes. Placez les manifestes sous contrôle de version (Git), ajoutez un smoke test qui crée un Job à partir de chaque CronJob, suit les logs et vérifie un code de sortie zéro. Cette séparation entre setup, exécution et revue facilite l'ajout de nouveaux Kubernetes CronJobs examples sans réécriture.
Conclusion
Vous disposez désormais d'un Kubernetes CronJobs setup reproductible : un cluster isolé, un namespace dédié, un CronJob pilote rapide et un exemple Python plus réaliste. Vous savez observer les horaires, limiter l'historique, prévenir les chevauchements, déclencher à la demande et nettoyer proprement. Prochaines étapes : ajouter des alertes en cas d'échec de Job, paramétrer l'environnement via ConfigMaps et Secrets, et codifier vos vérifications pour valider chaque changement localement, rapidement et en toute sécurité.