我从文档中了解到:
kubectl创建 在集群中创建一个新的k8s资源 kubectl取代 更新活动集群中的资源 kubectl应用 如果我想创建+替换(参考)
我的问题是
为什么在集群中执行相同的任务有三种操作? 这些操作的用例是什么? 它们在本质上有什么不同?
我从文档中了解到:
kubectl创建 在集群中创建一个新的k8s资源 kubectl取代 更新活动集群中的资源 kubectl应用 如果我想创建+替换(参考)
我的问题是
为什么在集群中执行相同的任务有三种操作? 这些操作的用例是什么? 它们在本质上有什么不同?
当前回答
这可以用简单的例子来总结:-
让我们创建一个简单的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创建-f pod.yaml
现在一个名为nginx的pod被创建了,你可以通过-获取运行的pod的信息
库贝特尔,把吊舱弄宽
和详细的查看豆荚由
kubectl描述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创建-f pod.yaml
要应用pod.yaml中的更改。
它的输出是-
来自服务器的错误(AlreadyExists):创建pod时出错。Yaml ": pods "nginx"已经存在
但是有了命令-
Kubectl应用-f pod.yaml
输出为-
豆荚/ nginx配置
在第一个评论中,它非常详细地解释了create之类的命令式命令专注于分配给它们的任务,你不能给它们分配更多的任务来调整集群的世界,但apply之类的声明性命令旨在使其工作来调整集群的世界。
其他回答
对于初学者来说,这是理解命令式模式和声明式模式之间区别的最好方法之一。
参考:https://www.digitalocean.com/community/tutorials/imperative-vs-declarative-kubernetes-management-a-digitalocean-comic
EDIT
有错误的例子中提到的图像。请参考评论以便更好地理解。
你也可以参考下面的例子。
必要的:
拿一个平底锅。 打开炉子。 锅中加入水、糖、咖啡粉、牛奶 等到咖啡准备好 用杯子盛咖啡。
声明:
告诉服务员你要一杯咖啡。他给你端咖啡。
从K8s的角度来看:
命令式:你必须自己管理不同的资源,如pod、服务、副本集等。
声明性: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 │
└─────────┴───────────────────────┴────────────────────────┘
这是两种不同的方法:
必要的管理
kubectl create就是我们所说的命令式管理。在这种方法中,你告诉Kubernetes API你想要创建、替换或删除什么,而不是你想要你的K8s集群世界是什么样子。
声明式管理
kubectl apply是声明式管理方法的一部分,在这种方法中,即使对对象应用了其他更改,也会“维护”对活动对象应用的更改(即通过缩放)。
您可以在Kubernetes对象管理文档中阅读更多关于命令式和声明式管理的内容。
在外行他们做不同的事情。如果资源存在,kubectl create会出错,而kubectl apply不会出错。
这个问题很深刻,也很好。下面是我对这个问题的思考:
K8s有三种资源管理方法
基于命令的对象管理:直接使用命令对kubernetes资源进行操作。例如: Kubectl运行nginx-pod——image=nginx:1.17.1——port=80 命令类型对象配置:通过命令配置和配置文件操作Kubernetes资源。例如: Kubectl create/patch -f nginx-pod.yaml 声明式对象配置:通过apply命令和配置文件操作kubernetes资源。例如: Kubectl应用-f nginx-pod.yaml
Type | Operate Object | Suitable for environment | Advantage | disadvantage |
---|---|---|---|---|
Command Based Object Management | Object | test env | Simple | Only active objects can be operated, but not audited or tracked |
Command Type Object Configuration | File | develop evn | Can be audited and tracked | When the project is large, there are many configuration files and the operation is troublesome |
Declarative Object Configuration | Directory | develop evn | Support directory operations | It is difficult to debug under unexpected circumstances |
以我的理解,给一个更直接的回答:
Apply -对现有对象进行增量更改 创建—创建一个全新的对象(以前不存在/已删除) 从Kubernetes网站上的一篇DigitalOcean文章中摘录如下:
我们在这里使用apply而不是create,以便将来我们可以增量地对Ingress Controller对象应用更改,而不是完全覆盖它们。