Kubectl应用vs Kubectl创建?

我从文档中了解到:

  • kubectl create
    
  • 集群中创建一个新的k8s资源
  • kubectl replace
    
    更新活动集群
  • 中的资源
  • kubectl apply
    
    如果我想做create + replace (< a href = " https://kubernetes。io / docs /用户指南/ kubectl-overview noreferrer“rel = >引用< / >)

我的问题是

  1. 为什么在集群中执行相同的任务有三种操作?
  2. 这些操作的用例是什么?
  3. 它们在本质上有什么不同?
155639 次浏览

这是两种不同的方法:

必要的管理

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

声明式管理

kubectl apply声明式管理方法的一部分,其中您可能应用于活动对象的更改(即通过scale)是"即使你apply其他改变对象。

你可以在Kubernetes对象管理文档中阅读更多关于命令式和声明式管理的内容。

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

当在CI脚本中运行时,你会遇到命令式命令的问题,因为如果资源已经存在,创建将引发一个错误。

你能做的就是使用--dry-run=true-o yaml选项应用(声明式模式)命令的输出:

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

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

这在某些不能使用声明式模式的情况下非常有用(例如在创建docker-registry secret时)。

以我的理解,给一个更直接的回答:

apply -对现有对象进行增量更改
create -创建一个全新的对象(以前不存在/已删除) < br > < br > < br > 从Kubernetes网站链接的DigitalOcean文章中获取:

我们在这里使用apply而不是create,以便将来我们可以增量地对Ingress Controller对象应用更改,而不是完全覆盖它们。

下面来自官方文档的解释帮助我理解了kubectl apply

此命令将比较您正在推送的配置版本与以前的版本,并应用您所做的更改,而不会覆盖对未指定属性的任何自动更改。

另一方面,kubectl create将创建(应该是不存在的)资源。

它们是必要的命令:

__abc0 = __abc1

优点:

  • 简单、易学、易记。
  • 只需要一个步骤就可以对集群进行更改。

缺点:

  • 不要与变更评审过程集成。
  • 不要提供与变更相关的审计跟踪。
  • 除了实时的记录,不要提供其他记录来源。
  • 不要为创建新对象提供模板。

它们是命令式对象配置:

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创建可以一次处理一个对象配置文件。这也被称为命令式管理

Kubectl create -f filename|url

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

< p >细节:< br > < a href = " https://kubernetes。Io /docs/tasks/manage-kubernetes-objects/ declarator -config/" rel="nofollow noreferrer">https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/ https://kubernetes.io/docs/tasks/manage-kubernetes-objects/imperative-config/ < / p >

我们喜欢Kubernetes是因为一旦我们给了他们我们想要的东西,它就会在没有我们参与的情况下找到实现它的方法。

“创造”就像扮演上帝,把事情掌握在自己手中。当您只想使用POD而不关心Deployment/Replication Controller时,它很适合用于本地调试。

“apply”是按规则行事。“apply”就像一个主工具,可以帮助您创建和修改,并且不需要您管理pod。

对于初学者来说,这是理解命令式模式和声明式模式之间区别的最好方法之一。


enter image description here


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


编辑

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

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

必要的:

  • 拿一个平底锅。
  • 打开炉子。
  • 锅中加入水、糖、咖啡粉、牛奶
  • 等到咖啡准备好
  • 用杯子盛咖啡。

声明:

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

从K8s的角度来看:

你必须自己管理不同的资源,如pods、service、replica sets等。

声明: 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      │
└─────────┴───────────────────────┴────────────────────────┘

这可以用简单的例子来总结:-

让我们创建一个简单的yaml来部署一个包含nginx图像的pod。

pod.yaml


apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx

现在我们使用kubectl命令-创建一个pod

kubectl create -f pod.yaml

现在一个名为nginx的pod被创建了,你可以通过-获取运行的pod的信息

kubectl get pods -o wide

和详细的查看豆荚由

kubectl describe pod nginx

现在如果我想在我的pod中做一些改变。Yaml文件是这样的-

pod.yaml


apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
tier: frontend
title: frontend
spec:
containers:
- name: nginx
image: nginx

现在试试命令

kubectl create -f pod.yaml

要应用pod.yaml中的更改。

它的输出是-

来自服务器的错误(AlreadyExists):创建"pod.yaml"已经存在

但是有了命令-

kubectl apply -f pod.yaml

输出为-

豆荚/ nginx配置

正如在第一个评论中,它非常详细地解释了create像命令式命令专注于它们分配的任务,你不能给它们分配更多的任务来调整集群的世界,但是apply像声明式命令被设计用来调整集群的世界。

这个问题很深刻,也很好。下面是我对这个问题的思考:

K8s有三种资源管理方法

  • 命令对象管理:直接使用命令操作kubernetes资源。例如:

    kubectl run nginx-pod --image=nginx:1.17.1 --port=80

  • 命令类型对象配置:通过命令配置和配置文件操作Kubernetes资源。例如:

    kubectl create/patch -f nginx-pod.yaml

  • 声明式对象配置:通过apply命令和配置文件操作kubernetes资源。例如:

    kubectl apply -f nginx-pod.yaml

< span style=" font - family:宋体;"> < / th >类型 < span style=" font - family:宋体;"> < / th >操作对象 < span style=" font - family:宋体;">适合环境 < span style=" font - family:宋体;"> < / th >优势 < span style=" font - family:宋体;"> < / th >缺点 < span style=" font - family:宋体;">基于命令的对象管理 . > < span style=" font - family:宋体;"> < / td对象> < span style=" font - family:宋体;"测试env > < / td > < span style=" font - family:宋体;"简单> < / td > < span style=" font - family:宋体;">只能操作活动对象,不能审计和跟踪 < span style=" font - family:宋体;"> . >命令类型对象配置 < span style=" font - family:宋体;"道明> >文件< / < span style=" font - family:宋体;"> < / td >勇气来发展 < span style=" font - family:宋体;">可审计可跟踪 . >可审计可跟踪 < span style=" font - family:宋体;">当项目比较大时,配置文件比较多,操作比较麻烦 . >配置文件比较多 < span style=" font - family:宋体;">声明性对象配置 . > < span style=" font - family:宋体;"道明> >目录< / < span style=" font - family:宋体;"> < / td >勇气来发展 < span style=" font - family:宋体;">支持目录操作 < span style=" font - family:宋体;">在意外情况下很难调试