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.
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.