learning/k8s-intermediate/obj/manage.md
kubectl 命令行工具支持多种途径以创建和管理 Kubernetes 对象。本文档描述了3种不同的方式。更多的细节,请参考 Kubectl book
</AdSenseTitle>| 管理方式 | 操作对象 | 推荐的环境 | 参与编辑的人数 | 学习曲线 |
|---|---|---|---|---|
| 指令性的命令行 | Kubernetes对象 | 开发环境 | 1+ | 最低 |
| 指令性的对象配置 | 单个 yaml 文件 | 生产环境 | 1 | 适中 |
| 声明式的对象配置 | 包含多个 yaml 文件的多个目录 | 生产环境 | 1+ | 最高 |
::: danger
同一个Kubernetes对象应该只使用一种方式管理,否则可能会出现不可预期的结果
:::
::: tip Kuboard
:::
当使用指令性的命令行(imperative commands)时,用户通过向 kubectl 命令提供参数的方式,直接操作集群中的 Kubernetes 对象。此时,用户无需编写或修改 .yaml 文件。
这是在 Kubernetes 集群中执行一次性任务的一个简便的办法。由于这种方式直接修改 Kubernetes 对象,也就无法提供历史配置查看的功能。
创建一个 Deployment 对象,以运行一个 nginx 实例:
kubectl run nginx --image nginx
下面的命令完成了相同的任务,但是命令格式不同:
kubectl create deployment nginx --image nginx
与编写 .yaml 文件进行配置的方式相比的优势:
缺点:
使用指令性的对象配置(imperative object configuration)时,需要向 kubectl 命令指定具体的操作(create,replace,apply,delete等),可选参数以及至少一个配置文件的名字。配置文件中必须包括一个完整的对象的定义,可以是 yaml 格式,也可以是 json 格式。
::: warning
replace 指令将直接使用对象中新的 spec 内容替换原有的 spec 内容,如果原有spec中存在配置文件中没有定义的字段,都将被丢弃。这种方法不能够应用在那些 spec 对象独立于配置文件进行更新的情况。例如 LoadBalancer 类型的 Service,其 spec 中的 externalIPs 字段由集群更新。
:::
通过配置文件创建对象
kubectl create -f nginx.yaml
删除两个配置文件中的对象
kubectl delete -f nginx.yaml -f redis.yaml
直接使用配置文件中的对象定义,替换Kubernetes中对应的对象:
kubectl replace -f nginx.yaml
与指令性命令行相比的优点:
与指令性命令行相比的缺点:
与声明式的对象配置相比的优点:
与声明式的对象配置相比的缺点:
当使用声明式的对象配置时,用户操作本地存储的Kubernetes对象配置文件,然而,在将文件传递给 kubectl 命令时,并不指定具体的操作,由 kubectl 自动检查每一个对象的状态并自行决定是创建、更新、还是删除该对象。使用这种方法时,可以直接针对一个或多个文件目录进行操作(对不同的对象可能需要执行不同的操作)。
::: tip
声明式对象配置将保留其他用户对Kubernetes对象的更新,即使这些更新没有合并到对象配置文件中。因为当Kubernetes中已经存在该对象时,声明式对象配置使用 patch API接口,此时会把变化的内容更新进去,而不是使用 replace API接口,该接口替换整个 spec 信息。
:::
处理 configs 目录中所有配置文件中的Kubernetes对象,根据情况创建对象、或更新Kubernetes中已经存在的对象。可以先执行 diff 指令查看具体的变更,然后执行 apply 指令执行变更:
kubectl diff -f configs/
kubectl apply -f configs/
递归处理目录中的内容:
kubectl diff -R -f configs/
kubectl apply -R -f configs/
与指令性的对象配置相比,优点有:
缺点:
::: tip 作者在实际部署一个 30+ 微服务部署单元的 Spring Cloud 应用时,编写了 40 多个 YAML 文件,每个 YAML 文件多达 100-500 行配置。为了使同一套 YAML 文件能够适应开发、测试、生产环境,将其分成 base、dev、test、staging、prod 等目录,使用 kustomize 将公共部分提取到 base 中。在经历了如此这般的痛苦之后,编写了 Kuboard。
从更好地学习和理解 Kubernetes 的角度来说,是一定要学会如何使用 kubectl 的,实际在 Kubernetes 上部署微服务应用时,您会发现 Kuboard 用起来更顺手。 :::