Start your free 14-day ContainIQ trial

Using Kubectl Delete | Tutorial and Best Practices

June 27, 2022

Kubectl delete is one of the many tools to help you manage your Kubernetes clusters. In this tutorial, you’ll learn how this tool can be used, and what some best practices for using it are.

Joseph Eshiett
DevOps Engineer

The Kubernetes command-line tool, kubectl, provides a way to communicate with the Kubernetes cluster via the control plane to manage resources by creating, editing, and extracting details about specific resources. The tool comes with a number of commands that can be used to perform different tasks.

One of the commands associated with this tool is the <terminal inline>kubectl delete<terminal inline> command. This command allows you to terminate running resources gracefully.  Some of the use cases for the <terminal inline>kubectl delete<terminal inline> command include the termination of running pods, deployments, services, StatefulSets, and many other resources.

In this guide, you'll learn how to appropriately use <terminal inline>kubectl delete<terminal inline> to stop resources, and about the various parameters that this command offers. You’ll learn some best practices to guide you in the safe and correct use of this command.

What is kubectl delete?

kubectl delete offers you a way to gracefully shut down and terminate Kubernetes resources by their filenames or specific resource names. The graceful termination of resources using the <terminal inline>kubectl delete<terminal inline> command is to be done with utmost discretion, because once the command has been run, there's no way to undo the deletion of the resource.

Kubernetes doesn't provide users with the ability to simply pause and resume resources. There are several ways to get around this limitation, one of which is to simply stop (delete) the desired resource to pause, and reapply the resource definition to the cluster to resume.

The <terminal inline>kubectl delete<terminal inline> command is especially handy during clean up after the deployment of an application. During development, the creation and deployment of resources is a top concern, but the management of these resources sometimes falls to the wayside after deployment.

Some of these resource-management responsibilities involve deleting unused pods. These pods, while running and unused in the Kubernetes cluster, take up some of the node's resources, thereby limiting other, more important, running pods.

In some cases, a Kubernetes node needs to be shut down, and the Kubernetes deployments and services will need to be terminated. Another resource-management concern could be the deletion of StatefulSets that manage pods that rely on durable storage configurations, such as persistent volumes.

K8s Metrics, Logging, and Tracing
Monitor the health of your cluster and troubleshoot issues faster with pre-built dashboards that just work.
Start Free Trial Book a Demo

Using kubectl delete

Before you begin with this tutorial, you need to have an understanding of the following Kubernetes concepts:

To get started with using <terminal inline>kubectl delete<terminal inline>, you need to have a single-node Kubernetes cluster running with at least 4 GB of RAM available. You can create one locally with lightweight Kubernetes distributions, such as minikube, K3s, or MicroK8s, or you can provision one with a cloud provider such as Google Kubernetes Engine (GKE), Azure Kubernetes Service, or Amazon Elastic Kubernetes Service (EKS).

kubectl delete Basic Use Case

With your cluster set up, you can now begin with a basic use case of the <terminal inline>kubectl delete<terminal inline> command.

Deploy a sample NGINX deployment by creating a file named <terminal inline>deployment.yaml<terminal inline>, then adding the following code snippet:


apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 3
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.14.2
       ports:
       - containerPort: 80

You then run the configurations on your Kubernetes cluster with the <terminal inline>kubectl apply<terminal inline> command:


kubectl apply -f ./deployment.yaml

The command above will create an NGINX deployment with a ReplicaSet and three NGINX pods deployed and running in the <terminal inline>default<terminal inline> namespace in your Kubernetes cluster. To verify this, you can simply perform the <terminal inline>kubectl get pod<terminal inline> command, and you'll get the following response:

NAME READY STATUS RESTARTS AGE
nginx-deployment-9456bbbf9-grdtc 1/1 Running 0 4m24s
nginx-deployment-9456bbbf9-dd5g2 1/1 Running 0 4m24s
nginx-deployment-9456bbbf9-4nzn2 1/1 Running 0 4m24s

Now that you've successfully deployed NGINX to your Kubernetes cluster, the next step is to clean up after the deployment.

If you perform the command <terminal inline>kubectl delete pods --all<terminal inline> to delete all the NGINX pods in the default namespace, another set of pods will spring back up to replace the ones that were deleted. In order to prevent this from happening, you need to delete the deployment configuration using either the filename, <terminal inline>deployment.yaml<terminal inline>, or the deployment name, <terminal inline>nginx-deployment<terminal inline>, as configured in the <terminal inline>metadata<terminal inline> section in the YAML code snippet above.

The NGINX Deployment can be deleted in two ways:


# Delete Deployment using filename
kubectl delete -f ./deployment.yaml

# Delete Deployment using metadata name:
kubectl delete deployment nginx-deployment

Once the deployment resource has been deleted, you shouldn't be able to see any pods, deployments, or ReplicaSets in the <terminal inline>default<terminal inline> namespace. You'll see only a single Kubernetes service active when you perform the <terminal inline>kubectl get services<terminal inline> command:


kubectl get services

This will display the available services in the <terminal inline>default<terminal inline> namespace:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 45h

Please note that depending on the type of Kubernetes distribution you are running, the output shown above may differ slightly.

kubectl delete Advanced Use Case

In the previous section, you created a simple NGINX deployment, then deleted it properly. In this section, you’ll look at a more advanced use case for the <terminal inline>kubectl delete<terminal inline> command, and see the steps involved in applying the command.

In this example, you’ll deploy the popular WordPress CMS. To do this, you’ll create the WordPress service, the <terminal inline>wp-pv-claim<terminal inline> PersistentVolumeClaim, and deploy the Wordpress app using the latest Docker Hub image.

Using your favorite text editor, create a file named <terminal inline>wordpress.yaml<terminal inline> and paste in the following YAML code:


apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:5.9.3-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-db
        - name: WORDPRESS_DB_PASSWORD
          value: password
        ports:
        - containerPort: 8080
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim

Apply the above configuration to your cluster by running the <terminal inline>kubectl apply<terminal inline> command:


kubectl describe deployment test-webapp

You’ll see output similar to the following:


$ kubectl apply -f ./wordpress.yml   
service/wordpress created
persistentvolumeclaim/wp-pv-claim created
deployment.apps/wordpress created

Verify that the changes were executed correctly using the <terminal inline>kubectl get all<terminal inline> command:


kubectl get all

You should get output similar to this:


NAME                             READY   STATUS    RESTARTS   AGE
pod/svclb-wordpress-4r66v        1/1     Running   0          25s
pod/wordpress-66ff8d4cb4-k746r   1/1     Running   0          25s

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kubernetes   ClusterIP      10.43.0.1       <none>        443/TCP          9d
service/wordpress    LoadBalancer   10.43.130.141   172.19.0.2    8080:32552/TCP   25s

NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/svclb-wordpress   1         1         1       1            1           <none>          25s

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/wordpress   1/1     1            1           25s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/wordpress-66ff8d4cb4   1         1         1       25s

After verifying that the WordPress deployment was successful, you can proceed to cleanup.

As before, trying to delete the pods is futile, since the deployment specification will recreate them as many times as necessary. Fortunately, you only have to use one command to remove the newly created deployment, service, and PVC:


$ kubectl delete -f ./wordpress.yaml
service "wordpress" deleted
persistentvolumeclaim "wp-pv-claim" deleted
deployment.apps "wordpress" deleted

If you want, you can confirm the above output using the commands:


kubectl get services
kubectl get persistentvolumeclaims

The output should be similar to the following:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 9d

No resources found in default namespace.

Another way to check that there are no remaining traces of WordPress is to use the <terminal inline>kubectl get all<terminal inline> command again:

$ kubectl get all

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 9d

As you can see, the <terminal inline>kubectl delete<terminal inline> command is suitable for both simple and more advanced use cases.

However, note that this was possible because a single YAML file was used to configure all the moving parts. This may or may not be a good idea, as you could mistakenly delete even data stored on a persistent volume. This leads us to the next section, best practices.

Best Practices

A single misused <terminal inline>kubectl delete<terminal inline> command can destroy a whole application and render it useless. There are no safety measures, such as prompts to ask if you truly want to delete the resource or not, attached to the command. Before you perform an operation with the <terminal inline>kubectl delete<terminal inline> command, you need to know exactly what you want to delete and how you want it deleted.

You can use the <terminal inline>kubectl delete --help<terminal inline> command to view a list of flags and options that can be applied.

Know When and How to Use kubectl delete

Understanding when to delete Kubernetes resources requires that you know your application’s tolerance for the unavailability of one or more of the resources. If one of the resources is taken down, your application should still be able to function.

Similarly, knowing how to delete resources is essential to keeping your services and applications running. For instance, deleting resources with the <terminal inline>--force<terminal inline> flag set to <terminal inline>true<terminal inline> should be avoided, as this may result in resource inconsistency, leading to application runtime failure or data loss. Unless you're very certain that doing this won't create problems for your application, this should be used only as a last resort.

Don’t Use kubectl delete Unless Absolutely Needed

It is strongly advised that you use the <terminal inline>kubectl delete<terminal inline> command sparingly, unless during important operations such as clean-up operations for resource optimization once all deployments are done with.

It's also advisable to hold off on deleting PersistentVolumeClaims until all necessary data is retrieved or copied, using the <terminal inline>kubectl cp<terminal inline> command from the <terminal inline>mountPath<terminal inline> on to your host machine.

Final Thoughts

In this article, you learned about the <terminal inline>kubectl delete<terminal inline> command: what it is, the different use cases for it, and the recommended ways to use it.

The <terminal inline>kubectl delete<terminal inline> command can be a great help when it comes to managing resources, but it's important to note that while it can prevent bottlenecks in your application, <terminal inline>kubectl delete<terminal inline> can also break your application entirely if used carelessly.

Kubernetes deployments are best paired with a monitoring solution like ContainIQ, which allows you to keep an eye on your resources, analyze the logs, and trace potential problems in your application, keeping you informed about your cluster's health and enabling you to better manage your resources.

Start your free 14-day ContainIQ trial
Start Free TrialBook a Demo
No card required
Joseph Eshiett
DevOps Engineer

Joseph is a DevOps practitioner who is fascinated by cloud technologies, software development, and deployment processes. Currently, he works as a DevOps Engineer for Sabino LLC. He is also a technical writer who enjoys documenting the processes and learning new things.

READ MORE