我最近在学习Kubernetes,我不太清楚"kubectl apply"one_answers"kubectl replace"之间的区别。是否存在我们只能使用其中一个的情况?
我已经写了一篇关于应用、替换和补丁之间差异的全面解释:Kubernetes应用与替换与补丁。其中包括一个解释,即目前排名第一的答案是错误的。
简而言之,如果资源不存在,kubectl apply
将使用提供的规范来创建资源,如果存在,则进行更新,即修补。提供给apply
的规范只需要包含规范的必需部分,当创建资源时,API将对其余部分使用默认值,而当更新资源时,它将使用其当前值。
kubectl replace
用所提供的规范定义的资源完全替换现有资源。replace
需要完整的规范作为输入,包括API提供的只读属性,如.metadata.resourceVersion
、用于pods的.spec.nodeName
、用于服务的.spec.clusterIP
和用于服务帐户的.secrets
。kubectl
有一些内部技巧可以帮助您做到这一点,但通常replace
的用例是获取资源规范,更改属性,然后使用更改后的完整规范来替换现有资源。
kubectl replace
命令有一个--force
选项,该选项实际上不使用replace,即PUT
,API端点。它使用所提供的规范强制删除(DELETE
)然后重新创建(POST
)资源
更新的答案
我最初的观点相当有争议,事后看来,我甚至会说,有一半是错误的。因此,这里有一个更新的答案,我希望它会更有帮助:
- 像kubectl
patch
、replace
、delete
、create
甚至edit
这样的命令都是命令式的:它们告诉kubectl该做什么 - kubectl
apply
命令是OTOH";陈述性的";因为它告诉kubernetes,这里有一个所需的状态(提供给apply命令的文件中的yaml),现在要弄清楚如何到达那里:创建、修补、替换对象等等。。。你明白了
所以这两个命令有很大的不同。
EG使用apply
,您可以对其进行您想要的更改:它将确定对象的哪些属性需要更改,而不考虑其他属性;如果这些性质是";不可变的";(例如,pod的nodeName),它会抱怨,如果你用--force
重复这个命令,它就足够聪明了,知道要做相当于replace --force
的事情。
一般来说,您应该支持apply
(必要时使用--force
),并且只有在声明性方法没有给出预期结果时才使用命令行命令(尽管我很想看到这样的例子——我猜只有当您需要几个步骤时才会发生这种情况,因为如果使用apply,相互依赖性会产生负面后果)。
apply
和replace
之间的差异类似于apply
和create
之间的差异。
create
/replace
使用命令式方法,而apply
使用声明式方法。
如果使用create
创建资源,则使用replace
更新资源。如果使用apply
创建资源,那么使用apply
更新资源。
请注意,replace
和apply
都需要一个完整的规范,并且都在删除旧资源之前先创建新资源(除非指定了--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
,它会删除并重新创建资源。