乐趣区

关于云原生:KubeCube-新增版本转换K8s-尝鲜再也不用担心影响老版本了

多租户可视化 K8s 治理平台 KubeCube 近日迎来了新版本的公布,新版本减少了 K8s 版本转化、HNC GA 版本适配、审计信息国际化、warden 被动上报模式,为集群和我的项目设置 Ingress 域名后缀等个性,也修复了若干已知问题,详见 ChangeLog。

该版本中最次要的个性是 Version-Conversion 能力的反对,使得接入 KubeCube 的用户无需感知被 KubeCube 接管的 K8s 集群版本,能够应用指定版本的 K8s API 来操作 K8s 资源,KubeCube 会做自适应转化;同时 KubeCube 也将这个能力包装成 SDK 供内部应用。

为什么须要多 K8s 版本转化?

在理论的生产场景中,用户的 K8s 集群往往固置于某一稳固版本,并随着工夫的推移,在该 K8s 集群中积淀了大量的业务、工具、计划等,同时 K8s 社区又会一直的推出更高的版本,此时降级 K8s 版本往往须要比拟高的代价。

K8s 的版本升级,并不总是保障 API 的完满兼容,绝大多数的 API 会经验从 Development level –> Alpha level –> Beta level –> Stable level 的倒退阶段,现实状况下,用户应该应用 Stable level 的 API 用于生产环境,然而事实中,用户所应用的某一资源的 API 很可能处于 Stable level 以下的阶段,比方 extensions/v1beta1 的 Deployment 和 apps/v1 的 Deployment。详见 K8S API 变动布局。

当用户须要在管制面纳管多 K8s 集群时,用户临时不心愿降级老的稳固的 K8s 集群,又心愿新增的 K8s 集群是比拟高的版本,这时,管控面的 KubeCube,就可能提供拜访多版本 K8s 的能力,对外裸露对立的 K8s 格调的 RESTfule API,用户既能够应用准确的 GVR 去拜访不同版本的 K8s 资源,也可用应用对立版本的 GVR 去拜访不同版本的 K8s 资源,KubeCube 会做自适应转化。

K8s native convert

  1. K8s api workflow
  1. K8s version convert

K8s 版本转换准则

  1. 同一个 group 的不同 version 都能够转换成该 group 的 internalVersion
  2. 某一 group 的 internalVersion 能够转换成该 group 下的任一 versionK8s

版本转化的外围 ——scheme

Scheme 中领有 concerter 转化器,其外部寄存了各个 API 注册的版本转化函数。

type Scheme struct {
    ...

    // converter stores all registered conversion functions. It also has
    // default converting behavior.
    converter *conversion.Converter

    ...
}

// Converter knows how to convert one type to another.
type Converter struct {
    // Map from the conversion pair to a function which can
    // do the conversion.
    conversionFuncs          ConversionFuncs
    generatedConversionFuncs ConversionFuncs

    // Set of conversions that should be treated as a no-op
    ignoredUntypedConversions map[typePair]struct{}}

咱们曾经晓得 internalVersion 和指定 version 之间的转换规则,它们的转换函数位于 k8s apis 的定义文件夹下,如:pkg/apis/apps/v1/zz_generated.conversion.go

// Code generated by conversion-gen. DO NOT EDIT.

package v1

import (...)

func init() {localSchemeBuilder.Register(RegisterConversions)
}

// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {...}

这些转化函数,个别由 install 包下的 Install(scheme) 函数注册到 Scheme 中。

// Package install installs the apps API group, making it available as
// an option to all of the API encoding/decoding machinery.
package install

import (...)

func init() {Install(legacyscheme.Scheme)
}

// Install registers the API group and adds types to a scheme
func Install(scheme *runtime.Scheme) {utilruntime.Must(apps.AddToScheme(scheme))
    utilruntime.Must(v1beta1.AddToScheme(scheme))
    utilruntime.Must(v1beta2.AddToScheme(scheme))
    utilruntime.Must(v1.AddToScheme(scheme))
    utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta2.SchemeGroupVersion, v1beta1.SchemeGroupVersion))
}

注册完的转会函数,将会在 Convert () 办法中应用。

// Convert will translate src to dest if it knows how. Both must be pointers.
// If no conversion func is registered and the default copying mechanism
// doesn't work on this type pair, an error will be returned.
// 'meta' is given to allow you to pass information to conversion functions,
// it is not used by Convert() other than storing it in the scope.
// Not safe for objects with cyclic references!
func (c *Converter) Convert(src, dest interface{}, meta *Meta) error {
  // 转换函数 map 的 key
    pair := typePair{reflect.TypeOf(src), reflect.TypeOf(dest)}
  
  // 理论的 convert 句柄
    scope := &scope{
        converter: c,
        meta:      meta,
    }

    // ignore conversions of this type
    if _, ok := c.ignoredUntypedConversions[pair]; ok {return nil}
  // 应用事后注册的转换函数进行转换
    if fn, ok := c.conversionFuncs.untyped[pair]; ok {return fn(src, dest, scope)
    }
    if fn, ok := c.generatedConversionFuncs.untyped[pair]; ok {return fn(src, dest, scope)
    }

    dv, err := EnforcePtr(dest)
    if err != nil {return err}
    sv, err := EnforcePtr(src)
    if err != nil {return err}
    return fmt.Errorf("converting (%s) to (%s): unknown conversion", sv.Type(), dv.Type())
}

KubeCube version conversion

理解了 K8s 版本转换的大抵思路后,KubeCube 如果须要做版本转换的能力,须要做到以下几点:

  1. 保护版本转换专用的 Scheme
  2. 注册所有的 K8s 的 API 转换函数,并提供拓展办法
  3. 应用 discovery client 提前做 src api 和 dest api 的转换查看
  4. Conversion func register

KubeCube 会默认注册所有 K8s 原生资源的转换函数,同时也提供注册自定义资源转换函数的入口。

  1. Greeting target cluster
  1. Controller-runtime client support

KubeCube 的版本转化 SDK 提供了 Wrap controller-runtime 的 client.Client 的能力,能够将 client.Client 降级为具备版本转化能力的句柄。

写在最初

将来咱们会继续提供更多功能,帮忙企业简化容器化落地。也欢送大家参加奉献,提出贵重的倡议。增加以下微信进入 KubeCube 交换群。

理解更多

KubeCube 用户治理与身份认证深刻解读
KubeCube 多集群治理
KubeCube 开源:简化 Kubernetes 落地的六大个性
KubeCube 主页:https://www.kubecube.io/
GitHub:https://github.com/kubecube-i…

作者简介:蔡鑫涛,网易数帆轻舟容器平台资深开发,KubeCube Committer

退出移动版