## 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: Forbid ou Replace pour prévenir les chevauchements.

- startingDeadlineSeconds: 60 pour éviter les exécutions manquées après de courtes pannes.

- backoffLimit: 1-2 pour plafonner les nouvelles tentatives des Jobs en échec.

- successfulJobsHistoryLimit et failedJobsHistoryLimit pour 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.