K8S 1.12大特性最快最深度解析:通过ComponentConfig更轻松安装和升级

931 阅读6分钟

前言

版本化组件配置文件是由华为在 Kubernetes 社区 v1.12 周期重点推动的特性,并在 Kubernetes 1.12 进入 alpha 阶段。接下来我们将叙述版本化组件配置文件的演变过程,以及以 kube-proxy 为例阐述如何将现有组件迁移到版本化配置文件,最后,作出一些未来工作设想。 作为 Kubernetes 的忠实粉丝,也必然感受到部署各个核心集群组件(kubelet,kube-proxy,scheduler 等)和管理命令行标志的痛苦。近两年,社区在尝试努力将使用命令行标识管理各个组件模式切换到更贴合 Kubernetes 风格的版本化配置文件模式,即组件配置。

从Kubernetes v1.10 开始,kubelet 正逐步从命令行标识迁移到版本配置文件,而且已经转换成 beta 版本(已支持动态 kubelet 配置)。为了支持这一特性,现有很多 kubelet 命令行标识已弃用或待删除。且在 v1.12 中,kubelet 组件版本配置文件特性已 GA。此外,kube-proxy 组件可以说已有GA版本的配置文件特性,这可从 local-up 脚本启动 kube-proxy 组件得到佐证。在K8S v1.12周期中,社区已将 kube-scheduler, kube-controller-manager, kube-apiserver 组件迁移为配置文件管理模式。社区将在 K8S v1.13 周期重点推动功能稳定性。

接下来,我将分以下几个部分简要展开叙述:

  • 为什么要为核心集群组件迁移到版本化配置文件
  • 组件的配置API的理想形态是怎样的
  • 如何将现有组件迁移到版本化配置文件
  • 总结与愿景

一、为什么要为核心集群组件迁移到版本化配置文件

一言以蔽之:便于管理,高效部署

具体来说,命令行标识存在但不限于以下问题:

  1. 标识是公共 API,但未进行版本化以及无法脱离组件二进制单独版本化:

    • 对于核心组件,二进制版本与 Kubernetes 版本相关联。对二进制文件采用语义版本控制,一般情况下无法突破主要版本控制。
    • 在一个 API 版本生命周期,我们会逐渐弃用单个参数,而不保证参数集的连续性。这将不但使用户使用不方便,而且导致 API 不太稳定。
    • 考虑到紧密耦合的接口兼容性,我们部署基于标识的配置版本升级通常不能独立于二进制文件。
  2. 在实际应用环境中,不免会重新配置组件某个参数值,流程复杂。目前情形是:以 kube-controller-manager 为例,假设启动参数变化,则需要重新启动组件二进制(进程)。但如果进程管理器配置是静态的,如配置命令行仅需要引用一个固定路径下的文件(如,kube-proxy 仅使用 —config 参数指定路径),则可以消除对参数化工具的依赖(如组件二进制)。

  3. 开发人员不可避免地将结构化数据嵌入到字符串中,还需要特定的解析器处理相应标识字段,这很容易引入错误。 想了解更多当前命令行标识模式的不足,可以查阅 mikedanese 提交的 kubernetes 组件配置、mtaufen 提交的版本化组件配置文件以及 sttts 提交的为 api-server 创建配置结构体等文档。

二、组件的配置API的理想形态

在组件二进制存在的目录运行如下命令:

$ component —help

可以看到,kube-proxy 至少包含 30 个命令行标识,kube-controller-manager 包含近 100 个命令行标识,kubelet 至少包含 120 个命令行标识。如前文所述,管理这些庞大数目的命令行标识对于一个k8s开发者来说都很艰难,何况小白使用用户。

我们期望每个核心集群组件拥有如下理想化的命令行:

$ component --config = path

显然,组件在其命令行上只显示一个标志。此标志接受具有版本化格式的配置文件的路径,而且所有其他组件相关配置信息都通过这个文件进行引用。 一般来说,每个核心集群组件应该:

  • 维护一个名为{component} .config.k8s.io的唯一 Kubernetes API 组,其中包含版本化的配置对象集,主要是每个版本中的 {Component}Configuration 结构,如 KubeProxyConfiguration。这个拥有组件配置特殊格式的结构将被API机制序列化。
  • 确保 {component} .config.k8s.io 符合 Kubernetes 标准的 API 弃用策略、API 约定和 API 更改策略。
  • 暴露名为 --config 的标识,该标识接受包含序列化 {Component}Configuration 结构文件的路径。
  • 使用 Kubernetes API 机制反序列化配置文件数据、应用默认文件和转换为内部版本以供运行时使用。(一般由 API 目录下 Install 包和 Scheme 包实现)
  • 在使用 Configuration 配置前验证内部版本(一般为 API 目录下的 validate 包实现)。如果验证失败,则拒绝运行指定的配置。
  • 确保第三方库(如 pflag 库)没有暴露标识。

三、如何将现有组件迁移到版本化配置文件

下面以 kube-proxy 为例,简要解答一下几个问题:

1、组件 API 组定义

如前文所述,kube-proxy 的组版本类型为: kubeproxy.config.k8s.io/ v1alpha1.KubeProxyConfiguration。 首先在 pkg/proxy/apis/kubeproxyconfig/register.go 中定义 GroupName,并把 KubeProxyConfiguration 加入到 `SchemeGroupVersion中作为内部版本类型,然后在pkg/proxy/apis/kubeproxyconfig/scheme/scheme.go`` 中定义解析和序列化特定版本的函数 Codecs,并把相应组类型加入到给定 Scheme 中。

2、如何读取配置文件

通过命令行标识 —config提供的文件路径,首先调用 loadConfigFromFile(file string) 读取配置文件,再调用 loadConfig (data []byte) 将文件内容解析为 {Componnet}Configuration结构,并对 API 组组名进行验证。

3、对配置文件进行验证

调用 Validate() 对 `{Componnet}Configuration`` 结构中属性进行验证,主要包含字段取值以及不同字段之间的关联性。 对具体细节不再展开叙述,感兴趣的童鞋可阅读社区 kube-proxy 源码。

总结与愿景

前文简单介绍了版本化组件配置文件的背景以及以 kube-proxy 为例大概了解的实现方式。

在接下来博文中,我将基于自己近期在 controller-manager 方面的经验,介绍 kube-controller-manager(cloud-controller-manager 暂不暴露 API 接口)的版本化组件配置文件思路以及实现。

最后,基于近期自己在 kube-controller-manager 组件配置方面的经验,接下来各核心组件还需要开展以下相关工作:

  • 解耦“累赘”的组件 API,已提交方案并在 1.1 已实现。
  • 为组件增加 —config 命令行标识,切换到 alpha 版本
  • 添加相应 e2e 测试,完整测试功能,切换到 beta 版本。
  • 启用或丢弃现有众多命令行标识,使版本化组件配置功能切换 GA。
  • 此外,kubeadm 和 cloud provider 也将 out of tree。

总的来说,Kubernetes 社区在朝着“核心做稳定,框架解耦、精简”这一目标前行。在此,我也诚挚邀请感兴趣的童鞋加入到社区上述或其他相关工作。