34

Is it possible to delete POD in kubernetes based on creation time or age?

Example : I would like to delete all PODs which are older than 1 day. These PODs are orphaned , therefore no new PODs will be created.

dansl1982
  • 998
  • 1
  • 7
  • 10

8 Answers8

53

This command will delete all PODs older than one day :

kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{"\n"}}{{end}}' | awk '$2 <= "'$(date -d 'yesterday' -Ins --utc | sed 's/+0000/Z/')'" { print $1 }' | xargs --no-run-if-empty kubectl delete pod

This command will delete all PODs older than 4 hours :

kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{"\n"}}{{end}}' | awk '$2 <= "'$(date -d'now-4 hours' -Ins --utc | sed 's/+0000/Z/')'" { print $1 }' | xargs --no-run-if-empty kubectl delete pod
marcind
  • 52,944
  • 13
  • 125
  • 111
dansl1982
  • 998
  • 1
  • 7
  • 10
  • 3
    Thanks for your answer! A couple of observations: First of all, this needs GNU `date`, so if for example you're running this inside an alpine container it will fail unless you install that version of `date`. My version of kubectl was outputting `+00:00` instead of `+0000`. Also, nanoseconds don't seem to be necessary. – Aldo 'xoen' Giambelluca May 01 '19 at 11:26
  • 2
    The above command requires GNU version of xargs and date, which can be installed on macOS from HomeBrew as gxargs and gdate respectively. `brew install findutils coreutils` – Hang Aug 23 '20 at 22:46
  • 1
    Thanks for this snippet! Super helpful :) – Eric Sep 23 '20 at 20:16
  • 1
    can anybody explain how this comparison is working/valid `$2 <= "'$(date -d 'yesterday' -Ins --utc ` ? – alixander Oct 01 '20 at 10:26
  • 1
    I like this solution a lot but it looks like the `date -d 'yesterday' -Ins --utc` part does not work on macOS sadly, probably because macOS is BSD based but the answer is for standard GNU. Anyone have a solution for macOS? – Michael Butler Jan 15 '21 at 18:01
  • 2
    @MichaelButler See [the answer](https://stackoverflow.com/a/66479725/8431936) below by SQLesion. The main thing is to use `gdate` on macOS which is the GNU version of `date`. – Jack Kawell Nov 18 '21 at 18:33
29

We could do this with awk by doing a regex [0-9]+d directly on the AGE ($5, 5th column) column and then printing the corresponding NAME ($1, first column) column

kubectl delete pod $(kubectl get pod | awk 'match($5,/[0-9]+d/) {print $1}')

Test first to see what's matching:

kubectl get pod | awk 'match($5,/[0-9]+d/) {print $0}'

$0 means all columns

should_be_working
  • 699
  • 1
  • 7
  • 11
  • 1
    For me on kubectl 1.18.15 the right column to use is `$4` not `$5`. The spirit of the answer is correct though and I'm hesitant to edit it in case it's my fault, not the answer's – 2rs2ts Mar 30 '21 at 22:28
  • Any idea on how to do this in powershell? – Oplop98 Dec 17 '21 at 16:54
  • I'm sure this is straightforward to most, but don't forget to use namespaces on both the "delete" and "get" statements if you use them. – jtclaypool Mar 11 '22 at 15:58
3

You can either add a liveness probe to track how long the pod alive and kill it when it's longer a certain period. Or you can schedule a CronJob

Cindy
  • 262
  • 2
  • 5
  • 4
    For liveness probe, you can add `/bin/sh -c "touch /tmp/healthy; sleep [time you want the container to alive]; rm -rf /tmp/healthy; sleep 600"` in the args. I will kill the old container and restart a new one when the time reaches. – Cindy Feb 22 '18 at 22:34
  • hi Cindy , First of all thank you for the answer, you suggestion is working but it looks like kubectl restarts a container and not deleting a POD. – dansl1982 Feb 23 '18 at 08:44
  • 1
    I found it easiset to actually run the script from [dansl1982's answer](https://stackoverflow.com/a/48960060/121660) inside a cron job like [this one](https://stackoverflow.com/a/54908449/121660) – captncraig Apr 30 '19 at 20:44
3

modified to work on mac:

# try the gnu versions: gxargs
brew install findutils coreutils


kubectl get pods -o go-template -n gui2 --template '{{range .items}}{{.metadata.name}} {{.metadata.creationTimestamp}}{{"\n"}}{{end}}' | awk '$2 <= "'$(gdate -d '21 days ago' -Ins --utc | sed 's/+0000/Z/')'" { print $1 }' | gxargs --no-run-if-empty kubectl delete pod
SQLesion
  • 165
  • 2
  • 9
3

Here is an alternative answer that uses kubectl, jq, and xargs.

It works locally for me on Mac, but I also uses it in a Kubernetes cronjob that runs debian-slim, so I think it works on both Mac and Linux.

The time is set in seconds (86400s here for 1 day).

kubectl get pod -o json | jq -r --argjson timestamp 86400 '.items[] | select (.metadata.creationTimestamp | sub("\\..*";"Z") | sub("\\s";"T") | fromdate < now - $timestamp).metadata.name' | xargs -r -L1 kubectl delete pod ;
ericfossas
  • 1,511
  • 8
  • 12
1

Here's a variant of the answer by dansl1982 above that will delete all pods with a particular label in all namespaces.

kubectl get pods -A -l app=my-api -o go-template --template '{{range .items}}{{.metadata.namespace}} {{.metadata.name}} {{.metadata.creationTimestamp}}{{"\n"}}{{end}}' | awk '$3 <= "'$(date -d'now-4 hours' -Ins --utc | sed 's/+0000/Z/')'" { print $1 " " $2 }' | xargs -L 1 --no-run-if-empty kubectl delete pod -n $1 $2
chakatz
  • 312
  • 1
  • 2
  • 10
1

No answer here by itself was complete for what I needed, so I took bits of (and upvoted) several answers, then mashed them together to delete completed pods older than a day, from various namespaces.

Here's what worked for me:

kubectl get pod --all-namespaces --field-selector=status.phase==Succeeded \
 | awk 'match($6,/[0-9]+d/) {print $1, $2}' \
 | xargs -L 1 --verbose --no-run-if-empty kubectl delete pod -n $1 $2
  • kubectl to find for completed pods in all namespaces,
  • awk to filter pods that finished a day or more ago (any age string ending with a d),
  • xargs to run (and output) kubectl delete against each pod, specifying the pod's namespace.
Dale C. Anderson
  • 2,280
  • 1
  • 24
  • 24
0

Here is another answer by showing the custom field when get pods and filter by the .metadata.creationTimestamp

kubectl delete pod -n foo $(kubectl get pods -n foo --field-selector=status.phase=Failed -o=custom-columns=NAME:.metadata.name,AGE:.metadata.creationTimestamp --no-headers=true --sort-by=.metadata.creationTimestamp | awk '$2 <= "'$(gdate -d '10 days ago' -Ins | sed 's/+0000/Z/')'" { print $1 }')

Based on the above command -o=custom-columns=NAME: has been used for the custom columns.

Amzar
  • 80
  • 7