157

Every time a deployment gets updated, a new replica set is added to a long list. Should the old rs be cleaned?

yuval
  • 1,680
  • 2
  • 12
  • 8
  • I wonder if - assuming all replica sets come from deployments - whether it's save to just blanket delete all the ones in the default namespace... – Rambatino Jul 15 '18 at 10:10
  • 4
    The old replicasets are kept by k8s on purpose to allow rolling back to a previous version of the Deployments. – wobmene May 05 '21 at 11:24
  • **Don't do this if you want to be able to rollback to previous versions of deployments**. Certainly don't do this on Prod. You're probably fine doing it in Dev environments. – sampathsris Apr 14 '23 at 05:22

8 Answers8

264

Removing old replicasets is part of the Deployment object, but it is optional. You can set .spec.revisionHistoryLimit to tell the Deployment how many old replicasets to keep around.

Here is a YAML example:

apiVersion: apps/v1
kind: Deployment
# ...
spec:
  # ...
  revisionHistoryLimit: 0 # Default to 10 if not specified
  # ...
Gian Marco
  • 22,140
  • 8
  • 55
  • 44
rwehner
  • 4,058
  • 1
  • 18
  • 13
  • 16
    Quote from K8s docs: «.spec.revisionHistoryLimit is an optional field that specifies the number of old ReplicaSets to retain to allow rollback. These old ReplicaSets consume resources in etcd and crowd the output of kubectl get rs. The configuration of each Deployment revision is stored in its ReplicaSets; therefore, once an old ReplicaSet is deleted, you lose the ability to rollback to that revision of Deployment. By default, 10 old ReplicaSets will be kept, however its ideal value depends on the frequency and stability of new Deployments.» – wobmene May 05 '21 at 11:22
  • 1
    It's worth highlighting this line from the docs @wobmene pasted here: By default, 10 old ReplicaSets will be kept, however its ideal value depends on the frequency and stability of new Deployments. – pizoelectric Aug 13 '21 at 21:36
43

Here's a way to do it without AWK, using only kubectl and the built-in jsonpath functionality:

kubectl delete replicaset $(kubectl get replicaset -o jsonpath='{ .items[?(@.spec.replicas==0)].metadata.name }')

This should be more stable because it processes the replica count directly instead of trying to parse the output of kubectl which might change.

Mike Matera
  • 431
  • 4
  • 3
27

A revision on Kévin's post above as I can't comment yet :D

AWK lets us ignore the spacing!

kubectl delete $(kubectl get all | grep replicaset.apps | awk '{if ($2 + $3 + $4 == 0) print $1}')
Joe Eaves
  • 387
  • 3
  • 3
26

If you want to clean it manually you can just paste that in your console

kubectl delete $(kubectl get all | grep replicaset.apps | grep "0         0         0" | cut -d' ' -f 1)

This only works because of the way kubectl get all displays resources. It's a cheap solution but it's not that big an issue either.

Edit

Look at Joe Eaves's solution, it's similar but less dependent on the syntax (ignores white spaces at least)

fearphage
  • 16,808
  • 1
  • 27
  • 33
4

on k8s v1.19.6 i had to modify Joe Eaves' command as below to make it work:

kubectl -n <namespace> delete rs $(kubectl -n <namespace> get rs | awk '{if ($2 + $3 + $4 == 0) print $1}' | grep -v 'NAME')
mkumar118
  • 442
  • 5
  • 12
3

One-Liner using awk and xargs deleting all ReplicaSets from all Namespaces:

kubectl get replicaset --all-namespaces -o=jsonpath='{range .items[?(@.spec.replicas==0)]}{.metadata.name}{"\t"}{.metadata.namespace}{"\n"}{end}' | awk '{print $1 " --namespace=" $2}' | xargs -n 2 -d '\n' bash -c 'kubectl delete replicaset $0 $1'
2

I do this way:

kubectl get replicasets.apps -n namespace | awk '{if ($2 + $3 + $4 == 0) print $1}' | xargs kubectl delete replicasets.apps -n namespace 

first get all replicaset, then parse it with conditional and then, delete it.

hiddenrebel
  • 79
  • 1
  • 4
1

A short way:

kubectl delete rs $(kubectl get rs | grep "0         0         0" | cut -d' ' -f 1)
hejeroaz
  • 173
  • 2
  • 3