【问题标题】:What is the difference between kubectl apply and kubectl replacekubectl apply 和 kubectl replace 有什么区别
【发布时间】:2018-04-24 19:05:00
【问题描述】:

最近在学习Kubernetes,对“kubectl apply”和“kubectl replace”的区别不是很清楚。有没有只能使用其中一种的情况?

【问题讨论】:

标签: kubectl


【解决方案1】:

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

破坏性更新

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

【讨论】:

  • 我认为这更多的是关于--force 选项而不是kubectl replace 本身,正如kubectl replace --help: --force=false: Delete and re-create the specified resource 所见。该文档不包含有关区分“kubectl replace”和“kubectl apply”的信息。
【解决方案2】:

更新答案

我的原作颇有争议,我什至现在事后看来,有一半是错误的。因此,这是一个更新的答案,希望对您有所帮助:

  • 像 kubectl patchreplacedeletecreate 甚至 edit 这样的命令都是必不可少的:它们告诉 kubectl 究竟该做什么
  • kubectl apply 命令是 OTOH “声明性”,因为它告诉 kubernetes,这是一个所需的状态(提供给应用命令的文件中的 yaml),现在弄清楚如何到达那里:创建、修补、替换对象,等等……你明白了。

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

EG 和apply 你可以只给它你想要的改变:它会找出对象的哪些属性需要改变,而不要管其他的;如果这些属性是“不可变的”(例如,pod 的 nodeName),它会报错,然后如果您使用--force 重复该命令,它就足够聪明地知道执行与replace --force 等效的操作。

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

【讨论】:

  • 这在实践中似乎不会发生。如果我 kubectl apply 一个没有指定副本数的新部署 - 它似乎默认为 01
  • @Code 你是对的,并且有相当多的选票(只有 2/3 赞成票)所以我在几周前更新了我的答案,希望它更有用
  • 原答案部分最好删除,因为它不正确。
  • @richvel 删除了原版
  • 如果您更新答案并删除其原始内容,我们会丢失历史记录,并且不知道评论适用于原始内容还是更新后的内容
【解决方案3】:

applyreplace 的区别类似于applycreate 的区别。

create / replace 使用imperative 方法,而apply 使用declarative 方法。

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

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

【讨论】:

  • 如需更全面的解释和比较,请参阅 Kubernetes 文档中的 this section
  • "请注意,replace 和 apply 都需要完整的规范,并且都先创建新资源,然后再删除旧资源(除非指定 --force)。"这是这里最大的收获。谢谢?
【解决方案4】:

在使用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

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

      我已经详细解释了应用、替换和补丁之间的区别: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) 资源。

      【讨论】:

        猜你喜欢
        • 2021-06-22
        • 2019-03-01
        • 2019-12-04
        • 1970-01-01
        • 2018-05-02
        • 2018-06-14
        • 2023-02-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多