K8s-kubectl(变更对比策略和拓展命令)

基于1.25

什么是变更对比策略

  • kuebctl apply 通过JSON/YAML,标准输入输出获取K8s集群进行配置更新

  • Kubectl edit 实时编辑K8s资源对象

  • kubectl patch 提供更新资源对象

  • kubectl diff 本地文件和实时资源对比

所以存在了不同的对比策略场景:

  • 变更对比逻辑在哪进行(服务端还是客户端)
  • 针对什么资源对象可以进行变更对象
  • 使用说明变更对比算法

服务端应用和客户端应用

服务端应用

通过声明式的方法,kuebctl 发送完整的对象描述去创建和更新对象。

kubectl提供了俩个命令参数实现支持服务端:

  • server-side:服务端应用的开关,当设置为true时,开启并使用服务端应用
  • force-conflicts:冲突解决策略,当设置为true;会强制应用变更

kubectl apply 和kubectl diff 都支持启用服务端应用

kubectl patch 值提供服务端应用的变更方式

客户端应用

与服务端不同,客户端在处理变更和冲突逻辑之后,把处理后的变更发送给服务端

  • kubectl apply 和 kubectl diff 默认使用客户端应用更新策略
  • kubectl edit 和 kubectl annotation 值提供客户端更新策略

  1. 获取变更配置:kubectl把用户提供的变更内容转换为runtime.Object对象后,会进一步将改对象编码为JSON格式的字节数组,作为待变更配置
  2. 获取服务端对象:kubectl请求kube-apisever获取最新服务端对象
  3. 计算变更内容:kubectl内部有一个专门计算变更的Patcher工具,会比形成完整的变更差异
  4. 应用变更内容:kubectl计算之后的作为参数,使用Patch进行kube-apiserver请求变更
  • 使用客户端变更,可以减少kube-apiserver压力
  • 如果多个来源同一时间请求变更,可能失败,kubectl实现了失败检测重试机制
    • 如果失败的原因是变更冲突,才进入重试(最大重试次数5)
    • 第一次重试,先从kube-apiserver获取最新资源
    • 第2-5次,为了减少频繁获取,退避1s重试

策略对比器和JSON对比器

kubectl支持提供了策略对比器(strategicpatch)和JSON对比器(jsonmerepatch)俩种

策略对比器

除了常规的字段对比,策略对比还支持使用对应的内置资源来对应OpenAPI资源类型提供的Schema信息进行对比,还可以进行更复杂的指令策略(Directive)对比

在实际中,常用的指令策略-retainKeys

  • 描述在变更时需要整体保留/替换字段

JSON对比器

无法从kube-apiserver中获取自定义资源的对象的OpenAPI,在K8s源码中也无法为每个用户自定义资源对象特定的资源实现类。

实现对比:

  • 先把用户自定义的资源对象转换为JSON格式,然后递归便利对比JSON对象的各个字段,找到全部变更内容

  • JSON无法实现高级对比,但是JSON支持注入预检查(PreconditionFunc)实现拓展对比

双路合并和三路合并

k8s对比分三类:新增字段、修改字段、删除字段

双路合并(2-way-Merge):基于变更配置和当前配置 来计算变更

  • kubectl edit|kubectl taint|kubectl cordon 等

三路合并(3-way-Merge):当前配置(服务端获取的完整的资源对象配置)、变更配置(由用户提供的、待生效的资源配置)、最后应用配置(用户提供的、已生效的最新资源配置)

  • 最后的应用配置通过读取配置的annotation的kubectl.kubernetes.io/last-applied-configuration注解内容来获取

  • 在更新成功后,变更配置会被写入``kubectl.kubernetes.io/last-applied-configuration`

三路合并流程

  1. 比较变更配置和当前配置
    • 将变更配置中存在、当前配置中不存在的字段作为新增字段
    • 将变更配置和当前配置中都存在但值不同的字段作为修改字段
    • 忽略当前配置中存在、变更配置中不存在的字段
  2. 比较变更配置和最后应用配置,将最后应用配置中存在、变更配置中不存在的字段作为删除字段
  3. 合并第一步的新增字段和修改字段,以及第2步中的删除字段,合并的内容作为变更内容

拓展命令

除了预置的kubectl命令,kubectl还支持插件拓展命令

拓展原理

设计插件,需要循环以下设计原则:

  1. 无需在kubectl上进行任何安装和配置,符合一定命名规范的二进制文件都可以直接作为插件(设置到/usr/bin/kubectl-educate-dplphins,就可以使用kubectl educate dplphins
  2. kubectl 所有输入参数都会提供给二进制文件
    • 拓展命令执行优先级最低,输入参数先匹配到核心,就会先匹配

拓展命令管理器Krew

Krew上K8s官方提供的拓展命令管理工具,实现对拓展命令的查找、安装、使用和管理

#1.更新可用命令
kubectl krew update
#2.搜索可用的拓展命令
kubectl krew seacrch
#3.安装拓展命令
kubectl krew install access-matrix
#4.使用拓展命令
kubectl access-matrix
# 5.更新拓展命令
kubectl krew upgrade
#6.卸载拓展命令
kubectl krew uninstall access-matrix