Terminus
Deleting a Pod with `kubectl`

Deleting a Pod with `kubectl`

The short answer

To delete a pod in Kubernetes you can use the [.inline-code]kubectl delete pod[.inline-code] command as follows:

$ kubectl delete pod <name>

Where:

  • [.inline-code]name[.inline-code] is the name of the pod you want to delete.

For example:

$ kubectl delete pod nginx-76d6c9b8c-m2hwx

By default, this will cause the terminal to hang until the object is fully removed and output a message upon successful deletion.

[#easily-recall-with-ai]Easily retrieve this command using Warp’s AI Command Search[#easily-recall-with-ai]

If you’re using Warp as your terminal, you can easily retrieve this command using the Warp AI Command Search feature:

Pressing the [.inline-code]#[.inline-code] symbol at the start of a line will pull up the AI search and then you can enter [.inline-code]delete pod[.inline-code] to get the command template. You can quickly insert that command into your shell using [.inline-code]CMD+ENTER[.inline-code].

[#customizing-a-pods-shutdown-time]Customizing a Pod's shutdown grace period[#customizing-a-pods-shutdown-time]

By default, Kubernetes will wait 30 seconds for the Pod to complete any post-run hooks and for the main process to close after receiving the signal to terminate.

If you want to give the process more (or less) time, you can use the [.inline-code]--grace-period[.inline-code] flag as follows:

$ kubectl delete pod <name> --grace-period=<seconds>

Where:

  • [.inline-code]name[.inline-code] is the name of the pod you want to delete.
  • [.inline-code]seconds[.inline-code] is the number of seconds grace to give the pod.

Note that, 1 is the lowest number of seconds you can wait. Setting the value to a negative number will cause the flag to be ignored. Finally, setting the flag to 0 will skip the grace period (and hooks) altogether and can only be used together with the [.inline-code]--force[.inline-code] flag like in the following example:

$ kubectl delete pod <name> --grace-period=0 --force

This combination will immediately remove the pod from Kubernetes without waiting for confirmation that the pod is terminated and the containers will be sent a signal to terminate immediately. This option should be used with care, as if there is an error which causes the container to not be deleted, for example, if a core service is not responding, then the containers might continue to run in the background without you seeing them in kubernetes.

[#deleting-a-pod-without-waiting]Deleting a Pod without waiting[#deleting-a-pod-without-waiting]

By default, the [.inline-code]kubectl[.inline-code] command will hang the terminal until the object is fully removed. If the object has a large grace period this might take a while and you may want to do other things in your terminal in the meantime.

To skip the wait period, you can use the [.inline-code]--wait=false[.inline-code] flag as follows:

$ kubectl delete pod web-0 --wait=false

To wait for a specific amount of time, you can use the [.inline-code]--timeout[.inline-code] flag as follows:

$ kubectl delete pod web-0 --timeout=5s

The above command will wait 5 seconds (notice the [.inline-code]s[.inline-code] suffix for seconds) and if the pod does not close within that amount of time, the [.inline-code]kubectl delete[.inline-code] command will be considered as failed and will display a timeout error in your terminal. Note that, this doesn't mean that the deletion wasn’t a success—your pods will continue to terminate in the background—this only means your pods were not entirely deleted in the specified time.

[#deleting-a-pod-by-label] Deleting a Pod by label [#deleting-a-pod-by-label]

There are times when it is easier to delete Pods by label—this can be because the label is constant and the name of the Pod can change, for example, in a Deployment. Deleting by label is easier for automation scripts in cases like these. Another reason could be if you want to delete many different pods sharing the same label whereas each pod would have a unique name.

To delete a pod by label, you can use the [.inline-code]--selector[.inline-code] flag or [.inline-code]-l[.inline-code] flag for short as follows:

$ kubectl delete pod -l app=nginx

You can also specify multiple labels by separating them with a comma as follows:

$ kubectl delete pod -l app=prometheus,component=exporter

The above command will delete any pods with both label key values:

  1. app: prometheus
  2. component: exporter

[#dry-run-before-deleting-pods]Doing a dry-run before deleting Pods [#dry-run-before-deleting-pods]

When using labels or field selectors to delete pods, you might want to verify which pods will be deleted by your command before actually deleting them.

To perform a dry run, you can use the [.inline-code]--dry-run=server[.inline-code] kubectl flag as follows:

$ kubectl delete pod -l app=nginx --dry-run=server
pod "nginx-76d6c9b8c-sj76d" deleted (server dry run)
pod "web-0" deleted (server dry run)

[#deleting-a-pod-by-field-selector]Deleting a Pod by field selector [#deleting-a-pod-by-field-selector]

Pods can be deleted based on certain values using the [.inline-code]--field-selector[.inline-code] parameter. Similarly to deleting Pods by label, the field selector is a way to delete all pods matching a certain query.

For example, to delete all pods that are currently running, you can run:

$ kubectl delete pod --field-selector=status.phase==Running

The current list of available field selectors is as follows:

  • [.inline-code]metadata.name[.inline-code] - the name of the Pod
  • [.inline-code]metadata.namespace[.inline-code] - the namespace of the Pod
  • [.inline-code]spec.nodeName[.inline-code] - the name of the Node the Pod is running on
  • [.inline-code]spec.restartPolicy[.inline-code] - the restart policy of the Pod
  • [.inline-code]spec.schedulerName[.inline-code] - the name of the Scheduler in charge of deploying the Pod
  • [.inline-code]spec.serviceAccountName[.inline-code] - the name of the service account the Pod is using
  • [.inline-code]spec.hostNetwork[.inline-code] - filter based on if the Pod is connected to the host’s network
  • [.inline-code]status.phase[.inline-code] - the lifecycle phase (status) of the Pod
  • [.inline-code]status.podIP[.inline-code] - filter based on the Pod’s IP
  • [.inline-code]status.nominatedNodeName[.inline-code] - filter based on the name of the Node that is the current “nominated” candidate to schedule the Pod.

For each of these fields, you can use the [.inline-code]==[.inline-code] or [.inline-code]!=[.inline-code] comparison operators to filter the Pods that will be deleted.

To chain multiple conditions together you can combine them using a comma like so:

$ kubectl delete pod --field-selector status.phase==Unknown,spec.nodeName=node1

The above command will delete all pods stuck in the “Unknown” state,. which are also running on a node called [.inline-code]node1[.inline-code].

[#deleting-all-pods]Deleting all Pods at once[#deleting-all-pods]

To delete all pods in the default namespace, you can use the [.inline-code]--all[.inline-code] flag as follows:

$ kubectl delete pod --all 

To delete all pods in another namespace, you can add the [.inline-code]-n[.inline-code] flag (short for [.inline-code]--namespace[.inline-code]) followed by the name of the namespace:

$ kubectl delete pod --all -n staging

Note that, it is usually recommended to run a dry run first before deleting all Pods.

[#troubleshooting-pods-deletion]Troubleshooting Pods deletion[#troubleshooting-pods-deletion]

If you delete a pod and it keeps coming back, chances are it is being controlled by some kind of replication set.

The types of replication sets that exist are:

  • Replicaset: used for basic replication and by deployments.
  • Statefulset: used for replication where not all replicas are exactly the same.
  • Daemonset: used for replication across all nodes, making sure each node in your cluster runs a certain pod.

These sets define the desired number of replicas for a given pod, so if you delete a running pod controlled by one of these, they will make sure a new pod gets scheduled in its place to meet the desired replicas defined in them.

To check what is controlling your pod, you can use the [.inline-code]kubectl get pods[.inline-code] command:

$ kubectl get pods -o custom-columns="\
NAME:.metadata.name,\
CONTROLLED BY:.metadata.ownerReferences[*].name,\
TYPE:.metadata.ownerReferences[*].kind"

Which will return all the pods in the current namespace with 3 columns:

  • [.inline-code]NAME[.inline-code]: the name of the pod.
  • [.inline-code]CONTROLLED BY[.inline-code]: the name of the replication set.
  • [.inline-code]TYPE[.inline-code]: the type of the replication set.

In cases like these, you will need to scale down / delete the source resource which will in turn terminate the pod permanently.

As mentioned above, Deployments also use Replicasets so if you see a Replicaset then you might need to scale down the Deployment and not directly the Replicaset. You can view the owner reference of the Replicaset to see if it is standalone or has a further parent element.