kubectl apply vs kubectl create?

kubectl apply vs kubectl create?

我对文档的理解是:

我的问题是

  1. 为什么在集群中做同一个任务需要三个操作?
  2. 这些操作的用例是什么?
  3. 它们在底层有何不同?

这是两种不同的方法:

命令式管理

kubectl create就是我们所说的Imperative Management。在这种方法中,您告诉 Kubernetes API 您想要创建、替换或删除什么,而不是您希望 K8s 集群世界是什么样子。

声明式管理

kubectl applyDeclarative Management 方法的一部分,其中您可能已应用于活动对象(即通过 scale)的更改是“维护" 即使您 apply 对对象进行了其他更改。

You can read more about imperative and declarative management in the Kubernetes Object Management documentation.

在外行他们做不同的事情。如果资源存在,kubectl create会报错,kubectl apply不会报错。

当 运行 在 CI 脚本中时,您将无法使用命令式命令,因为如果资源已经存在,create 会引发错误。

您可以做的是应用(声明式模式)命令式命令的输出,使用--dry-run=true-o yaml 选项:

kubectl create whatever --dry-run=true -o yaml | kubectl apply -f -

如果资源已经存在,上面的命令将不会引发错误(并且会在需要时更新资源)。

这在某些无法使用声明模式的情况下非常有用(例如创建 docker-注册表密码时)。

根据我的理解,给出一个更直接的答案:

apply - 对现有对象进行增量更改
create - 创建一个全新的对象(以前不存在/已删除)


从 Kubernetes 网站链接的 DigitalOcean article 中获取:

We use apply instead of create here so that in the future we can incrementally apply changes to the Ingress Controller objects instead of completely overwriting them.

下面来自 official documentation 的解释帮助我理解了 kubectl apply

This command will compare the version of the configuration that you’re pushing with the previous version and apply the changes you’ve made, without overwriting any automated changes to properties you haven’t specified.

另一方面,

kubectl create 将创建(应该是 non-existing)资源。

这些是命令式命令 :

kubectl run = kubectl create deployment

优点:

  • 简单易学易记。
  • 只需一步即可更改集群。

缺点:

  • 不与变更审阅流程集成。
  • 不提供与更改相关的审计跟踪。
  • 不提供除直播内容以外的记录来源。
  • 不提供用于创建新对象的模板。

这些是必要的对象配置:

kubectl create -f your-object-config.yaml

kubectl delete -f your-object-config.yaml

kubectl replace -f your-object-config.yaml

与命令式命令相比的优势:

  • 可以存储在源代码控制系统中,例如 Git。
  • 可以与流程集成,例如在推送之前审查更改和审计跟踪。
  • 提供用于创建新对象的模板。

与命令式命令相比的缺点:

  • 需要对对象架构有基本的了解。
  • 需要编写 YAML 文件的额外步骤。

与声明性对象配置相比的优势:

  • 更简单易懂。
  • Kubernetes 1.5版本后更加成熟

与声明性对象配置相比的缺点:

  • 最适合文件,而不是目录。
  • 对活动对象的更新必须反映在配置文件中,否则它们将在下次替换时丢失。

这些是声明性对象配置

kubectl diff -f configs/

kubectl apply -f configs/

与命令式对象配置相比的优势:

  • 直接对活动对象所做的更改将被保留,即使它们没有合并回配置文件。
  • 更好地支持对目录进行操作并自动检测每个对象的操作类型(创建、修补、删除)。

与命令式对象配置相比的缺点:

  • 当结果出乎意料时更难调试和理解。
  • 使用差异的部分更新会创建复杂的合并和修补操作。

kubectl create 一次可以使用一个对象配置文件。这也称为命令式管理

kubectl create -f 文件名|url

kubectl apply 适用于包含对象配置 yaml 文件的目录及其子目录。这也称为声明式管理。可以从目录中提取多个对象配置文件。 kubectl apply -f 目录/

详情:
https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/ https://kubernetes.io/docs/tasks/manage-kubernetes-objects/imperative-config/

我们喜欢 Kubernetes 是因为一旦我们给了他们我们想要的东西,它就会在我们不参与的情况下找出如何实现它。

"create" 就像把事情掌握在自己手中来扮演上帝一样。当您只想使用 POD 而不关心 abt Deployment/Replication 控制器时,它非常适合本地调试。

"apply" 遵守规则。 "apply" 就像一个大师级工具,可以帮助您创建和修改,而无需您管理 pods。

初学者理解命令式模式和声明式模式之间区别的最佳方法之一。



参考:https://www.digitalocean.com/community/tutorials/imperative-vs-declarative-kubernetes-management-a-digitalocean-comic


编辑

图中提到的例子有错误。请参考评论以便更好地理解。

您也可以参考下面的例子。

命令式:

  • 取一锅。
  • 打开炉子。
  • 在锅中加入水、糖、咖啡粉、牛奶
  • 等咖啡准备好了
  • 用杯子盛咖啡。

声明式:

  • 告诉服务员您需要一杯咖啡。他给你端咖啡。

从K8s角度看:

势在必行:您必须自己管理不同的资源,例如pods、服务、副本集等。

Declarative : K8 会处理所有资源,所有你需要的都必须指定你的实际需求。

┌─────────┬───────────────────────┬────────────────────────┐
│ command │ object does not exist │ object already exists  │
├─────────┼───────────────────────┼────────────────────────┤
│ create  │ create new object     │          ERROR         │ 
│         │                       │                        │
│ apply   │ create new object     │ configure object       │
│         │ (needs complete spec) │ (accepts partial spec) │
│         │                       │                        │
│ replace │         ERROR         │ delete object          │
│         │                       │ create new object      │
└─────────┴───────────────────────┴────────────────────────┘