---
title: "Jobs et CronJobs"
description: "Exécuter des tâches ponctuelles et planifiées sur Kontainers : migrations de schéma, maintenance, sauvegardes applicatives — pour un coût quasi nul."
source_url:
  html: https://docs.blackswift.cloud/deployer/jobs-et-cronjobs/
  md: https://docs.blackswift.cloud/deployer/jobs-et-cronjobs.md
---

# Jobs et CronJobs

> Exécuter des tâches ponctuelles et planifiées sur Kontainers : migrations de schéma, maintenance, sauvegardes applicatives — pour un coût quasi nul.

Tout ne mérite pas un Deployment qui tourne en permanence. Pour une tâche qui
s'exécute puis se termine — migration de base, import, purge, dump — Kubernetes
propose le **Job** (exécution unique) et le **CronJob** (planifiée). Et comme
[seuls les pods Running sont facturés](https://docs.blackswift.cloud/reference/facturation.md), à l'heure
entamée, une tâche quotidienne ne coûte qu'une heure par jour — environ 25 fois
moins qu'un pod permanent.

## Job : une exécution unique

Cas d'usage type : une migration de schéma avant une mise en production.

```yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: migrate-v2
spec:
  backoffLimit: 3                  # nb de tentatives en cas d'échec
  ttlSecondsAfterFinished: 3600    # auto-nettoyage 1 h après la fin (important !)
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: registry.exemple.com/acme/mon-app:2.0.0
          command: ["./migrate.sh"]
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef: {name: ma-base-app, key: uri}
          resources:
            requests: {cpu: 100m, memory: 256Mi}
```

```bash
kubectl apply -f migrate.yaml -n <namespace>
kubectl wait --for=condition=complete job/migrate-v2 -n <namespace> --timeout=300s
kubectl logs job/migrate-v2 -n <namespace>
```

:::caution[Toujours mettre `ttlSecondsAfterFinished`]
Un Job terminé laisse son pod `Completed` — qui ne coûte rien, mais **compte dans
le quota de 20 pods** du namespace. Sans TTL, les jobs s'accumulent jusqu'à
bloquer vos déploiements ([symptôme](https://docs.blackswift.cloud/depanner/aucun-pod-ne-se-cree.md)). Le TTL
supprime le Job et son pod automatiquement.
:::

## CronJob : l'exécution planifiée

Cas d'usage type : un dump de base quotidien
([exemple complet](https://docs.blackswift.cloud/operer/sauvegardes-et-restauration.md#compléter-avec-des-sauvegardes-applicatives)),
une purge de fichiers, un rapport hebdomadaire.

```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: purge-quotidienne
spec:
  schedule: "30 4 * * *"           # tous les jours à 4h30 (heure UTC)
  concurrencyPolicy: Forbid        # jamais deux exécutions en parallèle
  successfulJobsHistoryLimit: 3    # ne garder que les 3 derniers pods réussis
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      backoffLimit: 2
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: purge
              image: registry.exemple.com/acme/mon-app:2.0.0
              command: ["./purge-old-files.sh"]
              resources:
                requests: {cpu: 100m, memory: 128Mi}
```

```bash
kubectl get cronjobs -n <namespace>

# Déclencher manuellement sans attendre l'horaire (pour tester)
kubectl create job purge-test --from=cronjob/purge-quotidienne -n <namespace>
```

Les `HistoryLimit` jouent le même rôle que le TTL des Jobs : ils bornent le
nombre de pods terminés conservés — gardez-les bas.

:::note
Le champ `schedule` est en **UTC** : `30 4 * * *` = 5h30 ou 6h30 heure de Paris
selon la saison. À ne pas confondre avec le format à 6 champs (secondes en tête)
des [ScheduledBackups CNPG](https://docs.blackswift.cloud/deployer/postgresql-manage.md#sauvegardes-self-service).
:::

## Ce qui s'applique aussi aux Jobs

Un pod de Job est un pod comme un autre sur Kontainers :

- [Requests injectées](https://docs.blackswift.cloud/reference/mutations-et-politiques.md) si absentes —
  déclarez-les ;
- Limite mémoire = request : un job de build ou d'import gourmand doit demander
  sa vraie consommation, sinon [OOMKilled](https://docs.blackswift.cloud/depanner/pod-en-erreur.md#oomkilled) ;
- Quotas : **20 Jobs et 10 CronJobs** par namespace
  ([référence](https://docs.blackswift.cloud/reference/quotas-et-limites.md)), et les pods actifs comptent dans
  les 20 pods ;
- Le coût : la facturation est [à l'heure entamée](https://docs.blackswift.cloud/reference/facturation.md) —
  un CronJob quotidien de quelques minutes à 1 bundle ≈ 1 h facturée par jour,
  soit **≈ 0,12 € par mois**. Comparez au même script dans un Deployment qui
  dort : 2,88 €/mois. Et des exécutions rapprochées dans la même heure ne
  s'additionnent pas tant qu'elles ne se chevauchent pas (la base horaire est le
  maximum observé).
