Clean up CLI-generated Kubernetes jobs

2/23/2022

I have a bit of a strange situation, maybe. I have a series of Kubernetes cronjobs that need to be run. However, the set of jobs to be managed is part of a larger framework, and that framework is expanding quickly and manually managing all the jobs is impractical. The jobs take a date parameter and do some data processing using that date, and the date changes every day and may need to be adjusted due to backfill situations and so on. The way I've set it up to be manageable is as follows:

There is master cronjob, called "runner", which runs a script. The script loops over all the job configurations that need to get run and runs them all with the correct date parameter. The child jobs that are created by this script will be run using kubectl create job --image=... -- <job run command>. There is no k8s manifest for the child jobs, because it runs using a docker image and entrypoint command manually.

My question is, based on this configuration, is there a way to set a job TTL for the child jobs? I know I can set a job TTL when I have a k8s manifest, but since I don't have a k8s manifest in this case is there another way to do it?

-- Ertai87
jobs
kubernetes

1 Answer

2/23/2022

You can use dry run combined with patch.

kubectl create job myjob -o yaml --dry-run=client --save-config --image busybox -- sleep 120 |
  kubectl patch --dry-run=client -o yaml --type json --patch '[
    {"op": "add", "path": "/spec/ttlSecondsAfterFinished", "value": 100}
  ]' -f - | kubectl apply -f -

Or you can use jq to add the TTL to the spec.

kubectl create job myjob --image busybox --dry-run=client --save-config -o json -- sleep 120 |
  jq ' .spec += { "ttlSecondsAfterFinished": 100 }' | kubectl apply -f -

If you use this strategy, maybe you can even make yourself a base manifest with a TTL. Since you say you only want to change some date parameter.

kubectl apply -f job.yaml -o yaml --dry-run=client |
  kubectl patch --dry-run=client -o yaml --type json --patch '[
    {"op": "add", "path": "/spec/template/spec/containers/0/args", "value": ["'"$(date)"'"] }
  ]' -f - | kubectl apply -f -

If you would do that and read the date from an env variable, you could also get away with set.

kubectl apply -f job.yaml -o yaml --dry-run=client |
  kubectl set env TARGET_DATE="$(date +%Y-%m-%d)" -o yaml --local --dry-run=client -f - | 
  kubectl apply -f - 
-- The Fool
Source: StackOverflow