Kubectl Apply vs. Create: Understanding the Difference

When we’re dealing with configurations within Kubernetes clusters, two commands are used for editing Kubernetes resources. These commands are kubectl apply and kubectl create.

On the surface, it might seem that both of these commands are doing the same thing. So why do we have two different commands for doing the same thing? Well, these commands are different. They both handle config manipulation in distinct ways. Within this blog, let’s try and understand how the two differ from each other.

What is kubectl?

Before diving into the two commands in question, let’s first understand kubectl. Kubectl is a CLI tool for interacting with a Kubernetes cluster. It provides a way to do CRUD(Create, Read, Update, and Delete) operations for Kubernetes resources. It allows you to interact with the Kubernetes API server to deploy, manage, and monitor containerized applications and other resources in the cluster.

You can imagine kubectl as a "remote control" for your Kubernetes cluster. Using kubectl, you can issue commands to manipulate Kubernetes resources like pods, services, and deployments. You can also use it to check the status of your resources, view logs, and troubleshoot issues.

However, using kubectl isn’t the easiest thing to do. You often have to type long commands with multiple flags. Or even combine the commands with a long bash script for what you want to do. To provide a better experience while working with Kubernetes resources, Devtron provides you with a resource browser that does all the kubectl operations interactively. We can search, edit and delete the resources on the UI itself, and abstract away a lot of the complexities.

To learn more about kubectl and all its different functionalities, check out the official kubectl cheat sheet.

kubectl create

The kubectl create command is a way to create a Kubernetes resource, such as a pod or deployment. Let’s understand in detail what the kubectl create command does, and how to use it.

  • kubectl create takes a configuration file as input and creates a new Kubernetes resource based on the specifications defined in the file. This file is usually a YAML or JSON file. We will take a look at an example file when we see how to use kubectl create
  • kubectl create can work even without a configuration file. You can directly create Kubernetes resources by passing in the appropriate flags. However, you are limited with what customizations you can make using this method. To get a complete gist of how you can use the different configuration flags on kubectl create, check out the official kubectl reference sheet.
  • kubectl create will always create a new resource, even if a resource with the same name and specifications already exists in the cluster. In such a case, it will throw an error, and not allow you to create the resource until you provide a different resource name.
  • Typically, we prefer using kubectl create when we want to create a completely new Kubernetes resource. For example; when you want to create a temporary busybox pod for debugging your application.
  • kubectl create supports a wide range of resource types, including pods, services, and deployments.
  • However, kubectl create is limited to only creating new Kubernetes resources. You won’t be able to update existing resources using kubectl create.

Now that we understand what kubectl can do, let’s look at it in action.

First, make sure that you have a Kubernetes cluster up and running. If you don’t have a cluster, go ahead and install kind or minikube to get access to a local Kubernetes cluster.

To make sure that you have access to a Kubernetes cluster, you can run the below command. If you get an output, you have access to a cluster.

kubectl get nodes

If you get an error, there is some problem with connecting with the cluster. You can recreate your kind or minikube cluster to quickly resolve the problem. Alternatively, you can join the Devtron discord server and we can help you debug the problem.

Next, we need a YAML file that we can use. Let’s go ahead and create a YAML file that we can use for testing out the apply command. You can either create a Kubernetes configuration file using kubectl create <object-type> -o yaml, or you can copy the below YAML file. Let’s name it as deployment.yaml

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

Next, let’s go ahead and create this file using the kubectl create command. Simply run the below command.

kubectl create -f deployment.yaml

This will have created a deployment called my-deployment, which is running the nginx image.

If you remember, earlier we mentioned that kubectl create will not create a resource if it has the same name. Let’s put that to the test. We are going to apply the exact same YAML file once again, and this time, we will get an error.

kubectl apply

kubectl apply is a powerful utility that lets you create and update Kubernetes resources. Most of the time, DevOps teams prefer using kubectl apply over kubectl create, due to its flexible nature. Since operations teams work with configuration files, and do not directly create resources, kubectl apply is a great option. Let’s understand what kubectl apply can do, and how it’s different from kubectl create, and let’s also look at it in action.

  • kubectl apply reads the configuration file, typically YAML or JSON as input, which describes the desired state of a Kubernetes resource. For example, pods, services, deployments, and more.
  • If the resource described in the configuration file already exists in the cluster, kubectl apply will compare the state of the running resource, and the manifest provided. If there is a difference between the two, the existing resource will be updated to match the state described in the manifest file.
  • If the resource does not exist in the cluster, kubectl apply will create it based on the configuration file.
  • kubectl apply will try to update the resource in a way that is safe and non-disruptive, meaning that it will avoid deleting the resource and replacing it with a new one if possible.
  • kubectl apply is a good choice when you want to create a new resource or update an existing one, and you want Kubernetes to automatically manage the changes for you.
  • kubectl apply is often used in conjunction with source control systems like Git to manage changes to Kubernetes resources over time.
  • When updating a resource with kubectl apply, the last applied configuration available in the live manifest is saved

Now let’s go ahead and take a look at how we can use kubectl apply.

Just like before, make sure you have a Kubernetes cluster and you are connected to it. We will be using the same manifest file from the above example. If you ran the above commands, make sure you delete the deployment before proceeding with these steps. To delete the deployment you can run

kubectl delete deployment my-deployment

Now, we will use kubectl apply to create the same deployment once again, and then we will try and update the deployment with some changed configurations. To first create the deployment go ahead and run the following:

kubectl apply -f deployment.yaml

You can see that the same deployment my-deployment has been created. However, the process was a little different. Kubernetes first compared the actual state of the cluster, with the state defined in the configuration file. Since the state was not the same, Kubernetes went ahead and updated the cluster so that it would match the desired state.

Now if you remember, we mentioned that kubectl apply can even update the state of your existing Kubernetes resources. Let’s go ahead and try that out. We will update the configuration file, to have 3 replicas instead of two, and then we will apply it again. Go ahead and make the following changes within your manifest file.

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

Now, once again we will apply it using kubectl apply, and we can see that we now have 3 replicas instead of two.

Conclusion

The main difference between kubectl apply and kubectl create is how they handle updates to existing resources.

kubectl apply compares the actual state of the cluster with the desired state. The desired state is defined using YAML files. It is useful for creating or updating Kubernetes resources, and it will try to update an existing resource if one with the same name already exists. This makes kubectl apply a good choice when you want to make changes to existing resources.

On the other hand, kubectl create is used to create a new Kubernetes resource, and it will always create a new resource. However, if a resource with the same name and specifications exists, it will throw an error. This makes kubectl create a good choice when you want to create a new resource from scratch.

In the real world, you might want to use a combination of kubectl create and kubectl apply. You can use kubectl create to generate a sample YAML file which you can edit according to their desired configurations. Then to create the resource, and update it in the future, you can leverage the capabilities of the kubectl apply command.

I hope you understood the key differences. If you have any queries related to Kubernetes and beyond, feel free to ask your queries in our actively growing Discord Community.