Introduction
Les CronJobs Kubernetes exécutent des conteneurs selon une planification. Un laboratoire local permet de s'exercer en toute sécurité, de reproduire des problèmes et de gagner en confiance avant de toucher aux environnements partagés. Dans ce guide, vous mettrez en place un cluster kind jetable, créerez un espace de noms dédié avec un compte de service non-root, et lancerez deux exemples de CronJob : une tâche minutée affichant un message et une simulation ETL en Python. Vous validerez les planifications, le comportement de concurrence, les journaux, les limites d'historique et les routines de nettoyage pour que votre équipe puisse tester ses changements rapidement et de façon reproductible.
Aperçu du flux de travail
Suivez ce flux pour garder vos expériences propres et rapides :
- Créer un cluster local isolé.
- Créer un espace de noms et un compte de service pour les CronJobs.
- Appliquer un CronJob pilote minuscule avec une planification rapide.
- Observer la création des Jobs et Pods, les journaux et les limites d'historique.
- Exercer les contrôles : suspension, exécution unique, remplacement de concurrence, backoff.
- Ajouter un second exemple réaliste (Python) avec variables d'environnement et ressources.
- Dépanner les échecs en inspectant les événements, Jobs et Pods.
- Ajouter des garde-fous : limites de ressources, exécution non-root, scripts de nettoyage.
- Automatiser les vérifications courantes en one-liners ou scripts.
- Réinitialiser ou supprimer le laboratoire rapidement une fois terminé.
Plan pilote local
Objectif du pilote : un CronJob minuté qui affiche l'horodatage et un message, conserve un court historique de Jobs et interdit les exécutions chevauchantes.
Critères de succès :
- En moins de 2 minutes, vous voyez au moins un Job réussi.
- Vous pouvez lire les journaux du Pod du Job le plus récent.
- Aucune exécution chevauchante ne se produit.
- Vous pouvez le suspendre, puis le reprendre.
- Vous pouvez déclencher une exécution ponctuelle à la demande.
Cette portée étroite est rapide à mesurer et facile à inspecter localement avant tout déploiement.
Configurer un cluster local
Utilisez kind pour un cluster léger et jetable.
Créez le cluster :
kind create cluster --name cronlab
Pointez kubectl vers ce cluster :
kubectl cluster-info --context kind-cronlab
Vérifiez les nœuds :
kubectl get nodes
La sortie attendue affiche un nœud control-plane avec le statut Ready. Alternative : minikube start si vous préférez minikube.
Espace de noms et ServiceAccount
Cloisonnez votre laboratoire dans un espace de noms et exécutez les pods en non-root quand c'est possible.
Créez un espace de noms et un compte de service (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 : Tâche minutée d'écho
Un minuscule CronJob qui s'exécute chaque minute, interdit les chevauchements et conserve un court historique. Enregistrez sous cron-echo.yaml :
apiVersion: batch/v1
kind: CronJob
metadata:
name: echo-minutely
namespace: cronlab
spec:
schedule: '* * * * *'
concurrencyPolicy: Forbid
startingDeadlineSeconds: 60
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
Appliquez et observez :
kubectl apply -f cron-echo.yaml
kubectl get cronjob -n cronlab
kubectl get jobs -n cronlab --watch
Obtenez les journaux du Pod du Job le plus récent :
kubectl get pods -n cronlab -l app=echo-minutely
kubectl logs -n cronlab <nom-du-pod>
Sortie typique des journaux :
Tue Jan 14 10:30:00 UTC 2025
Hello from CronJob
Suspendez et reprenez à l'aide d'un fichier de patch (plus sûr entre shells). Enregistrez suspend-true.yaml :
spec:
suspend: true
Puis :
kubectl patch cronjob echo-minutely -n cronlab --type merge --patch-file suspend-true.yaml
Mettez spec.suspend: false pour reprendre.
Exécutez une fois à la demande sans attendre la planification :
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 : Simulation ETL Python
Cet exemple simule une petite tâche de données toutes les 5 minutes, utilise des variables d'environnement, un stockage temporaire 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(f"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: {}
Appliquez et vérifiez :
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 job-name -c worker --tail=50
Extrait de journal attendu :
starting job
processed 7 records from file:///data/input.csv
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=<nom-du-job>
- Journaux d'un Pod :
kubectl logs -n cronlab <nom-du-pod>
- Événements en cas d'échec :
kubectl describe job/<nom-du-job> -n cronlab
Exécutez 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 à chaque fois (echo-now-2, echo-now-3, ...).
Simulez un échec pour tester le backoff en changeant la commande par exit 1, puis observez les tentatives et les événements. La description d'un Job échoué affiche BackoffLimitExceeded après les tentatives configurées.
Garde-fous de sécurité et de ressources
Utilisez ces garde-fous dans votre laboratoire et dans les vraies charges de travail :
concurrencyPolicy: ForbidouReplacepour prévenir les chevauchements.startingDeadlineSeconds: 60pour éviter les exécutions manquées après de courtes pannes.backoffLimit: 1-2pour plafonner les nouvelles tentatives des Jobs en échec.successfulJobsHistoryLimitetfailedJobsHistoryLimitpour contrôler la taille des listes.- Requêtes/limites de ressources : empêchent les voisins bruyants localement.
- Contexte de sécurité :
runAsNonRoot,seccompProfile=RuntimeDefault. - Cloisonnement par espace de noms : gardez les artefacts du laboratoire contenus.
Nettoyage rapide :
kubectl delete ns cronlab
kind delete cluster --name cronlab
Automatiser et itérer localement
Regroupez vos étapes de laboratoire dans un script simple pour que les nouveaux collègues puissent démarrer, tester et nettoyer en quelques commandes. Exemple lab.sh :
#!/usr/bin/env bash
set -euo pipefail
kind create cluster --name cronlab
kubectl apply -f ns-sa.yaml
kubectl apply -f cron-echo.yaml
kubectl apply -f cron-python.yaml
# test de fumée : déclencher une exécution de chaque et suivre les journaux
kubectl create job echo-smoke --from=cronjob/echo-minutely -n cronlab
kubectl create job python-smoke --from=cronjob/python-etl-mock -n cronlab
kubectl wait --for=condition=complete job/echo-smoke -n cronlab --timeout=60s
kubectl wait --for=condition=complete job/python-smoke -n cronlab --timeout=60s
kubectl logs -n cronlab -l job-name=echo-smoke
kubectl logs -n cronlab -l job-name=python-smoke -c worker
Conservez les manifestes en contrôle de version, ajoutez un test de fumée qui crée un Job depuis chaque CronJob, suit les journaux et assure un code de sortie nul. Cette séparation entre configuration, exécution et revue vous aide à ajouter de nouveaux exemples sans retravailler l'existant.
Conclusion
Vous disposez maintenant d'un laboratoire CronJobs local reproductible : un cluster kind isolé, un espace de noms cloisonné, un CronJob pilote rapide et un exemple Python plus réaliste. Vous pouvez observer les planifications, limiter l'historique, prévenir les chevauchements, exécuter à la demande et nettoyer en toute sécurité. Prochaines étapes : ajouter des alertes pour les Jobs échoués, paramétrer les environnements via ConfigMaps et Secrets, et codifier vos vérifications pour que chaque changement soit rapide à valider localement.