Kubernetes Jobs
Un Job è un oggetto che crea uno o più pod, i quali eseguono una sola volta poi terminano.
Semplice Job
Esempio: un job che calcola il valore di Pi Greco a 2000 cifre decimali.
Scriviamo il Manifest:
vim ~/scripts/jobpi.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
Li parametro backoffLimit
è il numero massimo di riprove prima di dichiarare fallimento definitivo, con valore di default 6.
Sottoponiamo il manifest a Kubernetes:
kubectl apply -f ~/scripts/jobpi.yml
Controlliamo l'esistenza:
kubectl get job
e del pod sottostante:
kubectl get pod
I Job si possono descrivere:
kubectl describe job pi
Quando un Job termina lo si vede dalla colonna COMPLETIONS. Quando il suo pod termina va nello stato Completed
.
Per listare tutti i pod non Completed (ancora attivi) che appartengono ad un Job si può usare l'espressione:
pods=$(kubectl get pods --selector=batch.kubernetes.io/job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods
Per vedere l'output dei pod di un Job si può usare:
kubectl logs jobs/pi
3.141592653589793238462643383279502884197169.....
Rimuoviamo il Job tramite Manifest:
kubectl delete -f ~/scripts/jobpi.yml
La rimozione di un job rimuove i suoi pod.
CronJob
Un CronJob compie attività a intervalli regolari schedulati nel futuro.
E' l'equivalente dell'ambiente cron nel mondo Unix/Linux.
Esempio. Un cronJob che scrive l'ora corrente e un messaggio ogni minuto.
vim ~/scripts/cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
A intervalli di un minuto viene creato un nuovo pod che esegue il comando specificato.
La schedulazione è data dal campo .spec.schedule
, che ha lo stesso formato del cron di Unix.
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday)
# │ │ │ │ │ OR sun, mon, tue, wed, thu, fri, sat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
Sono disponibili delle macro:
Macro | Equivalente a |
---|---|
@yearly | 0 0 1 1 * |
@monthly | 0 0 1 * * |
@weekly | 0 0 * * 0 |
@daily | 0 0 * * * |
@hourly | 0 * * * * |
Il campo .spec.jobTemplate
ha lo stesso schema di un Job. Si possono anche usare in esso metadati come labels e annotations.
Sottomettiamo il Manifest:
kubectl apply -f ~/scripts/cronjob.yml
Controlliamo l'esistenza del CronJob:
kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello * * * * * False 0 14s 30s
Dopo qualche minuto controlliamo i Job e i Pod:
kubectl get cronjobs
kubectl get jobs
kubectl get pods
Notare che il nome è costruito a partire dal nome del CronJob.
I nostri pod del Cronjob scrivono ciascuno al suo standard output, quindi nei logs. L'output di un pod è visibile con, p.es.:
kubectl logs hello-28474168-pdh77
Tue Feb 20 17:38:04 UTC 2024
Hello from the Kubernetes cluster
Calibrazione dei Job
Storia dei Job
Anche dopo molti minuti il rapporto mantiene una storia di poche entries. La storia mantenuta è controllata dai parametri:
.spec.successfulJobsHistoryLimit
- lunghezza della storia dei jobs/pods che hanno avuto successo (default 3).spec.failedJobsHistoryLimit
- lunghezza della storia dei jobs/pods che sono falliti (default 1)
Partenza Ritardata dei Job
Il campo opzionale .spec.startingDeadlineSeconds
definisce una tolleranza in secondi per la partenza di un job (default: infinito), se per qualsiasi ragione il job non riesce a partire al momento schedulato.
Non settare mai il parametro inferiore a 10 secondi, o il job può non venire mai eseguito.
Se passa il tempo di tolleranza il job è considerato fallito.
Concorrenza
E' quando il job precedente è ancora in esecuzione e viene schedulato un nuovo job uguale.
Questo è controllato dal parametro .spec.concurrencyPolicy
che può avere i seguenti valori:
Allow
- (default) concessoForbid
- proibito. Il nuovo job schedulato fallisce.Replace
- il nuovo job schedulato parte. Il vecchio job non ancora completato, fallisce.
Sospensione
Si può sospendere l'esecuzione di un Job o CronJob settando il parametro .spec.suspend
al valore true
(default: false
).
I job già partiti non sono toccati.
Si possono cambiare i cronjob già attivi, oltre che modificare e sottomettere il Manifest. Per esempio:
kubectl patch cronjob hello -p '{"spec":{"suspend":true}}'
La stringa di patch può essere in Json o Yaml.
ATTENZIONE: Quando un CronJob è sospeso e passano i momenti di schedulazione dei suoi Job, questi vengono accodati. Quando si toglie la sospensione i Job accodati vengono eseguiti simultaneamente. Il comportamento dipende dai settaggi .spec.startingDeadlineSeconds
e .spec.concurrencyPolicy
.
Terminare l'Esercizio
kubectl delete -f ~/scripts/cronjob.yml