【发布时间】:2018-04-24 19:05:00
【问题描述】:
最近在学习Kubernetes,对“kubectl apply”和“kubectl replace”的区别不是很清楚。有没有只能使用其中一种的情况?
【问题讨论】:
-
这能回答你的问题吗? kubectl apply vs kubectl create?
标签: kubectl
最近在学习Kubernetes,对“kubectl apply”和“kubectl replace”的区别不是很清楚。有没有只能使用其中一种的情况?
【问题讨论】:
标签: kubectl
破坏性更新
在某些情况下,您可能需要更新无法更新的资源字段 初始化后更新,或者您可能只想进行递归 立即更改,例如修复由 部署。要更改此类字段,请使用
replace --force,它会删除 并重新创建资源。
【讨论】:
--force 选项而不是kubectl replace 本身,正如kubectl replace --help: --force=false: Delete and re-create the specified resource 所见。该文档不包含有关区分“kubectl replace”和“kubectl apply”的信息。
更新答案
我的原作颇有争议,我什至现在事后看来,有一半是错误的。因此,这是一个更新的答案,希望对您有所帮助:
patch、replace、delete、create 甚至 edit 这样的命令都是必不可少的:它们告诉 kubectl 究竟该做什么apply 命令是 OTOH “声明性”,因为它告诉 kubernetes,这是一个所需的状态(提供给应用命令的文件中的 yaml),现在弄清楚如何到达那里:创建、修补、替换对象,等等……你明白了。所以这两个命令有很大的不同。
EG 和apply 你可以只给它你想要的改变:它会找出对象的哪些属性需要改变,而不要管其他的;如果这些属性是“不可变的”(例如,pod 的 nodeName),它会报错,然后如果您使用--force 重复该命令,它就足够聪明地知道执行与replace --force 等效的操作。
一般来说,你应该支持apply(必要时使用--force),并且只在声明式方法没有给出预期结果时使用命令式命令(虽然我很想看到这样的例子——我'我猜这只会在你需要几个步骤时才会发生,因为如果使用 apply 会产生负面后果的相互依赖关系)。
【讨论】:
kubectl apply 一个没有指定副本数的新部署 - 它似乎默认为 0 或 1。
apply 和replace 的区别类似于apply 和create 的区别。
create / replace 使用imperative 方法,而apply 使用declarative 方法。
如果您使用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 ... 将用指定的值替换/覆盖整个对象。 这应该是首选,因为您要避免选择性启发式更新的复杂性。然而,像入口/负载均衡器这样的资源是不可变的,因此不能真正被替换。
导致不明显操作的启发式更新示例:https://github.com/kubernetes/kubernetes/issues/67135
【讨论】:
我已经详细解释了应用、替换和补丁之间的区别:Kubernetes Apply vs. Replace vs. Patch。它包含一个解释,即当前对该问题的排名最高的答案是错误的。
简而言之,kubectl apply 使用提供的规范创建一个资源,如果它不存在并更新,即修补,如果它存在。提供给apply 的规范只需要包含规范的必需部分,创建资源时 API 将使用其余部分的默认值,更新资源时将使用其当前值。
kubectl replace 将现有资源完全替换为提供的规范定义的资源。 replace 想要一个完整 规范作为输入,包括由 API 提供的只读属性,例如 .metadata.resourceVersion、.spec.nodeName 用于 pod、.spec.clusterIP 用于服务,.secrets 用于服务帐户. kubectl 有一些内部技巧可以帮助您做到这一点,但通常replace 的用例是获取资源规范,更改属性,然后使用更改后的完整规范来替换现有资源。
kubectl replace 命令有一个--force 选项,它实际上不使用替换,即PUT,API 端点。它使用提供的规范强制删除 (DELETE) 然后重新创建 (POST) 资源。
【讨论】: