69

I am learning Kubernetes recently, and I am not very clear about the difference between "kubectl apply" and "kubectl replace". Is there any situation that we can only use one of them?

JimmyCYJ
  • 771
  • 1
  • 5
  • 12
  • 2
    This may help https://stackoverflow.com/questions/47369351/kubectl-apply-vs-kubectl-create – Jose Armesto Dec 20 '17 at 16:52
  • good read on subject: https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/ – Ivan Aracki Jun 11 '19 at 11:57
  • Does this answer your question? [kubectl apply vs kubectl create?](https://stackoverflow.com/questions/47369351/kubectl-apply-vs-kubectl-create) – Inanc Gumus Apr 21 '20 at 12:50

6 Answers6

27

I have written up a thorough explanation of the differences between apply, replace, and patch: Kubernetes Apply vs. Replace vs. Patch. It includes an explanation that the current top-ranked answer to this question is wrong.

Briefly, kubectl apply uses the provided spec to create a resource if it does not exist and update, i.e., patch, it if it does. The spec provided to apply need only contain the required parts of a spec, when creating a resource the API will use defaults for the rest and when updating a resource it will use its current values.

The kubectl replace completely replaces the existing resource with the one defined by the provided spec. replace wants a complete spec as input, including read-only properties supplied by the API like .metadata.resourceVersion, .spec.nodeName for pods, .spec.clusterIP for services, and .secrets for service accounts. kubectl has some internal tricks to help you get that right, but typically the use case for replace is getting a resource spec, changing a property, and then using that changed, complete spec to replace the existing resource.

The kubectl replace command has a --force option which actually does not use the replace, i.e., PUT, API endpoint. It forcibly deletes (DELETE) and then recreates, (POST) the resource using the provided spec.

David Dooling
  • 674
  • 7
  • 6
16

Updated Answer

My original was rather controversial and I would even say now, in hindsight, half incorrect. So here is an updated answer which I hope will be more helpful:

  • commands like kubectl patch, replace, delete, create, even edit are all imperative: they tell kubectl exactly what to do
  • the kubectl apply command is OTOH "declarative" in that it tells kubernetes, here is a desired state (the yaml from the file provided to the apply command), now figure out how to get there: create, patch, replace the object, etc whatever it takes... you get the idea.

So the 2 commands are hugely different.

EG with apply you can give it just the changes you want: it will figure out what properties of the object need to be changed, and leave the other ones alone; if those properties are "immutable" (eg, the nodeName of a pod), it will complain, and if you then repeat the command with --force, it is smart enough to know to do the equivalent of a replace --force.

In general, you should favor apply (with --force when necessary), and only use the imperative commands when the declarative approach does not give the expected result (although I would love to see examples of this -- I'm guessing this would happen only when you would need several steps because of interdependencies that will have negative consequences if done with apply).

Oliver
  • 27,510
  • 9
  • 72
  • 103
  • 1
    This does not seem to happen in practice. If I `kubectl apply` a new deployment with no replica count specified - it seems to default to `0` or `1`. – Chris Stryczynski Aug 16 '19 at 11:49
  • @Code you are right and there was quite a spread of votes (only 2/3 were up votes) so I updated my answer a few weeks ago, hopefully that makes it more useful – Oliver Jan 25 '21 at 17:08
  • 1
    It would be best to delete the original answer section since it's incorrect. – RichVel Jan 27 '21 at 15:51
  • 1
    @richvel removed original – Oliver Jan 27 '21 at 22:14
  • 2
    if you update an answer and remove its original content, we lose track of the history and don't know whether a comment applies to the original or to the updated one – Andre Soares Sep 01 '21 at 10:21
  • @AndreSoares: I agree but too late to fix. But luckily it's easy: only comments from Jan 25, 2021 and after relate to the current version of my answer. So only one comment is obsolete (the one by @ChrisStryczynski). – Oliver Jul 25 '22 at 16:20
5

The difference between apply and replace is similar to the difference between apply and create.

create / replace uses the imperative approach, while apply uses the declarative approach.

If you used create to create the resource, then use replace to update it. If you used apply to create the resource, then use apply to update it.

Note that both replace and apply require a complete spec, and both create the new resources first before deleting the old ones (unless --force is specified).

Code
  • 6,041
  • 4
  • 35
  • 75
  • 1
    For a more thorough explanation and comparison, see [this section](https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/) in the Kubernetes docs. – Rob van Maris Dec 02 '19 at 15:23
  • "Note that both replace and apply require a complete spec, and both create the new resources first before deleting the old ones (unless --force is specified)." This is the biggest take away here. Thank you – Shinebayar G Jan 10 '22 at 17:41
5

you can add option -v=8 when use kubectl, and you will find the log like this

apply --force
patch 422
delete 200
get 200
get 200
get 404
post 201

replace --force
get 200
delete 200
get 404
post 201
shuaihanhungry
  • 468
  • 6
  • 7
4

kubectl apply .. will use various heuristics to selectively update the values specified within the resource.

kubectl replace ... will replace / overwrite the entire object with the values specified. This should be preferred as you're avoiding the complexity of the selective heuristic update. However some resources like ingresses/load balancers can't really be replaced as they're immutable.

Example of the heuristic update leading to non obvious operation: https://github.com/kubernetes/kubernetes/issues/67135

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
3

From: https://github.com/kubernetes/website/blob/master/content/en/docs/concepts/cluster-administration/manage-deployment.md

Disruptive updates

In some cases, you may need to update resource fields that cannot be updated once initialized, or you may just want to make a recursive change immediately, such as to fix broken pods created by a Deployment. To change such fields, use replace --force, which deletes and re-creates the resource.

Eyal Levin
  • 16,271
  • 6
  • 66
  • 56
  • 6
    I think this is more about the `--force` option than about `kubectl replace` itself, as can be seen with `kubectl replace --help`: `--force=false: Delete and re-create the specified resource`. The docs do not contain infomation about what distinguishes "kubectl replace" from "kubectl apply". – Florian von Stosch Oct 29 '18 at 14:42