跳到主要内容
08:44:02
🔅🔆

Kubernetes 对象管理

kubectl 命令行工具支持多种不同的方式来创建和管理 Kubernetes 对象。本文概述这些不同的管理方法。想深入了解 kubectl 管理对象的详细信息,可以阅读 Kubectl Book。

官方文档参考​

页面链接
Kubernetes 对象管理(本篇主参考)https://kubernetes.io/zh-cn/docs/concepts/overview/working-with-objects/object-management/

三种管理技巧总览​

只用一种技术

应该只使用一种技术来管理 Kubernetes 对象。在同一对象上混合和匹配多种技术将导致未定义行为。

管理技术作用于建议环境支持的写者学习难度
指令式命令活跃对象开发项目1+最低
指令式对象配置单个文件生产项目1中等
声明式对象配置文件目录生产项目1+最高

指令式命令​

使用指令式命令时,用户直接在集群中的活跃对象上进行操作,将操作作为参数或标志传给 kubectl 命令。这是开始学习或在集群中运行一次性任务的推荐方法。由于该技术直接在活跃对象上操作,它不提供以前配置的历史记录。

例子——通过创建 Deployment 对象来运行 nginx 容器的实例:

kubectl create deployment nginx --image nginx

与对象配置相比的优点:

  • 命令用单个动词表示。
  • 命令仅需一步即可对集群进行更改。

与对象配置相比的缺点:

  • 命令不与变更审查流程集成。
  • 命令不提供与更改关联的审核跟踪。
  • 除了实时内容外,命令不提供记录源。
  • 命令不提供用于创建新对象的模板。

指令式对象配置​

在指令式对象配置中,kubectl 命令显式指定操作(创建、替换等)、可选标志和至少一个文件名。指定的文件必须包含 YAML 或 JSON 格式的对象的完整定义。对象定义的详细格式可查阅 Kubernetes API 参考。

例子:

# 创建配置文件中定义的对象
kubectl create -f nginx.yaml

# 删除两个配置文件中定义的对象
kubectl delete -f nginx.yaml -f redis.yaml

# 通过覆盖活动配置来更新配置文件中定义的对象
kubectl replace -f nginx.yaml

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

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

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

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

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

  • 指令式对象配置行为更加简单易懂。
  • 从 Kubernetes 1.5 版本开始,指令式对象配置更加成熟。

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

  • 指令式对象配置更适合文件,而非目录。
  • 对活动对象的更新必须反映在配置文件中,否则会在下一次替换时丢失。
replace 会丢弃配置文件之外的变更

kubectl replace 这类指令式命令会用新提供的规约整体替换现有规约,并放弃对配置文件中缺少的字段所做的所有更改。此方法不应与对象规约会被独立于配置文件更新的资源类型一起使用。例如类型为 LoadBalancer 的 Service,它的 externalIPs 字段就是独立于集群配置进行更新的——用 replace 会把这些独立变更直接抹掉。

声明式对象配置​

使用声明式对象配置时,用户对本地存储的对象配置文件进行操作,但用户不定义要对该文件执行的操作——kubectl 会自动检测每个文件的创建、更新和删除操作。这使得配置可以作用于整个目录,根据目录中各配置文件的情况对不同对象执行不同操作。

声明式为何能保留他人修改

声明式对象配置保留其他编写者所做的修改,即使这些更改并未合并到对象配置文件中。其实现方式是使用 patch API 操作仅写入观察到的差异,而不是像 replace 那样用 API 操作替换整个对象配置。

例子——处理 configs 目录中的所有对象配置文件,创建并更新活跃对象。可以先用 diff 子命令查看将要进行的更改,然后再应用:

# 预览将发生的变更
kubectl diff -f configs/
# 应用变更
kubectl apply -f configs/

递归处理目录:

kubectl diff -R -f configs/
kubectl apply -R -f configs/

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

  • 对活动对象所做的更改即使未合并到配置文件中,也会被保留下来。
  • 更好地支持对目录进行操作,并自动检测每个文件的操作类型(创建、修补、删除)。

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

  • 声明式对象配置难于调试,出现异常时结果难以理解。
  • 使用 diff 产生的部分更新会创建复杂的合并和补丁操作。

三种方式优缺点对比速查​

维度指令式命令指令式对象配置声明式对象配置
操作对象活跃对象单个配置文件配置文件目录
操作类型命令里显式指定命令里显式指定kubectl 自动检测
变更历史/审计无有(可入 Git)有(可入 Git)
保留他人修改否否(replace 覆盖)是(patch 方式)
学习成本最低中等最高
适用场景开发、一次性任务生产项目(单人维护文件)生产项目(目录批量管理)

我的总结与避坑清单​

  1. 同一个对象永远只用一种管理方式,最常见的事故是:平时用 apply 管理部署,临时排查时手滑执行了 replace 或 create,直接报错或覆盖掉线上变更。
  2. 生产环境首选 kubectl apply -f <目录>(声明式),并且先 kubectl diff 预览再 apply,把"意外变更"挡在提交之前。
  3. 少用 kubectl replace,尤其对 LoadBalancer Service 这类有字段会被控制器/用户独立更新的资源,replace 会静默丢弃文件里没写的变更;需要改配置就改文件再 apply。
  4. apply 的清单要和 Git 仓库保持单一事实来源:改集群先改 Git 再 apply,禁止只在集群上 kubectl edit 而不回写文件,否则下次 apply 会把改动冲掉。
  5. 目录化管理时注意 -R 递归标志:apply -f configs/ 默认不递归,子目录里的清单会被漏掉,用 -R 或把清单放平铺目录。
  6. 指令式命令只留给临时操作:建个测试 Deployment、看一下效果可以 kubectl create deployment,但事后要导出清单入库(kubectl get deploy xxx -o yaml > xxx.yaml),避免配置只存在于集群里。
🛡️本站已安全运行2334天23时18分58秒
Bottom GIF
Top GIF