kubectl apply vs create: Which One to Use for Creating Resources in Kubernetes Cluster Environment?
Two different approaches for creating resources in Kubernetes cluster. What's the difference?
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.
NOTE: 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.