There is a subtle difference between kubectl create and kubectl apply commands.
The kubectl create command creates a new resource. So, if the command is run again it will throw an error as resource names should be unique in a namespace.
kubectl get pods
No resources found.
kubectl create -f pod.xml
pod/myapp-pod created
kubectl create -f pod.xml
Error from server (AlreadyExists): error when creating "pod.xml": pods "myapp-pod" already exists
2) The kubectl apply command applies the configuration to a resource. If the resource is not there then it will be created. The kubectl apply command can be run the second time as it simply applies the configuration as shown below. In this case, the configuration hasn't changed. So, the pod hasn't changed.
kubectl delete pod/myapp-pod
pod "myapp-pod" deleted
kubectl apply -f pod.xml
pod/myapp-pod created
kubectl apply -f pod.xml
pod/myapp-pod unchanged
In the kubectl create, we specify a certain action, in this case create and so it is imperative. In the kubectl apply command we specify the target state of the system and don't specify a certain action and so declarative. We let the system decide what action to take. If the resource is not there it will create it, if the resource is there then it will apply the configuration to the existing resource.
From an execution perspective, there is no difference when a resource is created for the first time between kubectl create and kubectl apply as shown above. But, the second time the kubectl create will throw an error.
It took me some time to get around it, but it makes sense now.