我从文档中了解到:

kubectl创建 在集群中创建一个新的k8s资源 kubectl取代 更新活动集群中的资源 kubectl应用 如果我想创建+替换(参考)

我的问题是

为什么在集群中执行相同的任务有三种操作? 这些操作的用例是什么? 它们在本质上有什么不同?


当前回答

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

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

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

其他回答

在CI脚本中运行时,如果资源已经存在,则创建会引发错误,因此使用命令式命令会遇到麻烦。

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

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

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

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

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

让我们创建一个简单的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之类的声明性命令旨在使其工作来调整集群的世界。

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

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

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

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

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

这些是命令式命令:

Kubectl run = Kubectl create deployment

优点:

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

缺点:

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

这些是命令式对象配置:

Kubectl create -f your-object-config.yaml

Kubectl delete -f your-object-config.yaml

Kubectl替换-f your-object-config.yaml

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

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

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

要求对对象模式有基本的了解。 需要编写YAML文件的额外步骤。

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

更简单,更容易理解。 Kubernetes 1.5版本之后更加成熟。

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

在文件上工作最好,而不是目录上。 对活动对象的更新必须反映在配置文件中,否则它们将在下一次替换期间丢失。

这些是声明性的对象配置

Kubectl diff -f configs/

Kubectl应用-f configs/

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

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

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

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