kubectl apply vs create: Which One to Use for Creating Resources in Kubernetes Cluster Environment?

kubectl apply and kubectl create both are two different approaches to create resources in Kubernetes cluster environment.

They both create resources from either a file or from STDIN.

kubectl apply and create: Two approaches for creating resources

Now let's go in some detailing and understand how kubectl apply and create differ from each other while implementing.

kubectl create: Imperative management

kubectl create is what we call imperative management. On this approach you tell the Kubernetes API what you want to create, replace or delete.

In simpler words, create creates a whole new object (previously non-existing or deleted).

kubectl apply: declarative management

kubectl apply is part of the declarative management approach, where changes that you may have applied to a live object (i.e. through scale) will be "maintained" even if you apply other changes to the object.

In simpler words, apply - makes incremental changes to an existing object by defining what we need.

💡
Both kubectl create and apply approaches accepts JSON and YAML file formats.

Understanding the difference between kubectl create and apply with example

I will use the below YAML file to create a Kubernetes pod.

root@kmaster-rj:~/pod-create# cat mypod.yml
apiVersion: v1
kind: Pod
metadata:
   name: create-vs-apply-demo
   labels:
      app: front-end
      rel: dev
spec:
  containers:
  - name: httpd
    image: docker.io/httpd
    imagePullPolicy: IfNotPresent
    ports:
      - containerPort: 80

Let's create the Pod using imperative way, i.e., using kubectl create command:

root@kmaster-rj:~/pod-create# kubectl create -f mypod.yml
pod/create-vs-apply-demo created

List the pod status along with labels:

root@kmaster-rj:~/pod-create# kubectl get pods --show-labels
NAME                   READY   STATUS    RESTARTS   AGE   LABELS
create-vs-apply-demo   1/1     Running   0          8s    app=front-end,rel=dev

Now I will edit the YAML file and add an extra label (demo: applyVscreate) to it.

root@kmaster-rj:~/pod-create# cat mypod.yml
apiVersion: v1
kind: Pod
metadata:
   name: create-vs-apply-demo
   labels:
      app: front-end
      rel: dev
      demo: applyVscreate
spec:
  containers:
  - name: httpd
    image: docker.io/httpd
    imagePullPolicy: IfNotPresent
    ports:
      - containerPort: 80

Now lets again use the imperative approach to apply the changes.

root@kmaster-rj:~/pod-create# kubectl create -f mypod.yml
Error from server (AlreadyExists): error when creating "mypod.yml": pods "create-vs-apply-demo" already exists

It throws an error and says the resource already exists.

Now let's do the same operation using declarative approach, i.e. kubectl apply command.

root@kmaster-rj:~/pod-create# kubectl apply -f mypod.yml
pod/create-vs-apply-demo configured

So, the resource got configured this time. Verify the changes made.

root@kmaster-rj:~/pod-create# kubectl get pods --show-labels
NAME                   READY   STATUS    RESTARTS   AGE     LABELS
create-vs-apply-demo   1/1     Running   0          3m19s   app=front-end,demo=applyVscreate,rel=dev

You can see the new label has been applied to the pod.

I believe now you should have a clear understanding of the two approaches.

Kubectl create or apply? Which one to use?

It depends on use case how you want to use these concepts or methodology. It's not about which is good or which is bad.

If you want to version control the k8s object then it's better to use declarative way (kubectl apply) which helps to determine the accuracy of data in k8s objects.

And if you want to just create some resource for troubleshooting, learning or interactive experimentation purpose go with imperative approach (kubectl create).

Still confused? Do leave a comment and I'll try to answer your doubts.