kubectl apply和kubectl replace之间有什么区别



我最近在学习Kubernetes,我不太清楚"kubectl apply"one_answers"kubectl replace"之间的区别。是否存在我们只能使用其中一个的情况?

我已经写了一篇关于应用、替换和补丁之间差异的全面解释:Kubernetes应用与替换与补丁。其中包括一个解释,即目前排名第一的答案是错误的。

简而言之,如果资源不存在,kubectl apply将使用提供的规范来创建资源,如果存在,则进行更新,即修补。提供给apply的规范只需要包含规范的必需部分,当创建资源时,API将对其余部分使用默认值,而当更新资源时,它将使用其当前值。

kubectl replace用所提供的规范定义的资源完全替换现有资源。replace需要完整的规范作为输入,包括API提供的只读属性,如.metadata.resourceVersion、用于pods的.spec.nodeName、用于服务的.spec.clusterIP和用于服务帐户的.secretskubectl有一些内部技巧可以帮助您做到这一点,但通常replace的用例是获取资源规范,更改属性,然后使用更改后的完整规范来替换现有资源。

kubectl replace命令有一个--force选项,该选项实际上不使用replace,即PUT,API端点。它使用所提供的规范强制删除(DELETE)然后重新创建(POST)资源

更新的答案

我最初的观点相当有争议,事后看来,我甚至会说,有一半是错误的。因此,这里有一个更新的答案,我希望它会更有帮助:

  • 像kubectlpatchreplacedeletecreate甚至edit这样的命令都是命令式的:它们告诉kubectl该做什么
  • kubectlapply命令是OTOH";陈述性的";因为它告诉kubernetes,这里有一个所需的状态(提供给apply命令的文件中的yaml),现在要弄清楚如何到达那里:创建、修补、替换对象等等。。。你明白了

所以这两个命令有很大的不同。

EG使用apply,您可以对其进行您想要的更改:它将确定对象的哪些属性需要更改,而不考虑其他属性;如果这些性质是";不可变的";(例如,pod的nodeName),它会抱怨,如果你用--force重复这个命令,它就足够聪明了,知道要做相当于replace --force的事情。

一般来说,您应该支持apply(必要时使用--force),并且只有在声明性方法没有给出预期结果时才使用命令行命令(尽管我很想看到这样的例子——我猜只有当您需要几个步骤时才会发生这种情况,因为如果使用apply,相互依赖性会产生负面后果)。

applyreplace之间的差异类似于applycreate之间的差异。

create/replace使用命令式方法,而apply使用声明式方法。

如果使用create创建资源,则使用replace更新资源。如果使用apply创建资源,那么使用apply更新资源。

请注意,replaceapply都需要一个完整的规范,并且都在删除旧资源之前先创建新资源(除非指定了--force)。

当使用kubectl时,您可以添加选项-v=8,您会发现类似以下的日志

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

kubectl apply ..将使用各种启发式方法来选择性地更新资源中指定的值。

kubectl replace ...将用指定的值替换/覆盖整个对象这应该是首选,因为您避免了选择性启发式更新的复杂性。然而,一些资源,如ingress/负载均衡器,并不能真正被替换,因为它们是不可变的。

导致不明显操作的启发式更新示例:https://github.com/kubernetes/kubernetes/issues/67135

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

中断性更新

在某些情况下,您可能需要更新无法初始化后更新,或者您可能只想进行递归立即更改,例如修复由部署。要更改这些字段,请使用replace --force,它会删除并重新创建资源。

最新更新