如何扩展Kubernetes管理的资源对象

栏目: 编程工具 · 发布时间: 7年前

内容简介:如何扩展Kubernetes管理的资源对象

kubernetes 逐渐成熟,也成为许多公司容器化平台的首选,然而在落地当中,每个企业面对的问题场景多少也有些不一样的,总是希望对kubernetes做改造,来更好的满足企业目前的需求.

然而fork一个k8s分支出来并不是一个好的选择,那么有其他方案吗?

接下来,我们先了解下kubernetes的apiserver

1.apiserver作为整个kubernetes集群的核心组件,让所有资源可被描述和配置;这里的资源包括了类似 网络、存储、pod这样的基础资源也包括了replication controller、deployment这样的管理对象;

2.apiserver某种程度上来说更像是包含了一定逻辑的对象数据库;接口上更加丰富、自带GC、支持对象 间的复杂逻辑;当然apiserver本身是无状态的 数据都在etcd当中;

3.apiserver 提供基于RESTful的管理接口,支持增删改查和patch、监听的操作,其他组件通过和apiserver的接口获取资源配置和状态,以实现各种资源处理逻辑

在k8s集群外 打造另一个apiserver来扩展k8s的资源,与原生k8s组成“联邦”;一来解除和社区版本的耦合 二来可以最大化定制需求.在一些场景下,这个方案更具灵活性和可操作性.

我们也部署了kubernetes集群,但是也遇到了一些挑战.一是kubernetes并不能解决所有容器化带来的问题,二来我们也看到了kubernetes这套框架在扩展性、灵活性等方面优点,所以我们已经在积极尝试实践k8s框架来延伸kubernetes方案;

那么好实现吗?有没有现成的开源框架方便实现这个方案呢,而不需要大海捞针,在kubernetest源码里去抽丝剥茧呢?

令人兴奋的是答案是肯定的,k8s 单独开源了apiserver的开发框架

项目地址( https://github.com/kubernetes/apiserver.git ) ,需要说明的是这个项目本身和kubernetes的代码保持同步的

那么我们接下来就看下如何利用k8s开源的框架构建特定资源的apiserver

由于已经有很多文章介绍apiserver的架构这里不再赘述,我主要讲下如何使用框架,从添加一个资源的过程来了解这个框架

先上架构图

如何扩展Kubernetes管理的资源对象

这里有几个概念要先介绍

Scheme: 定义了资源序列化和反序列化的方法 以及资源类型和版本的对应关系;这里我们可以理解成一张纪录表

Storage: 是对资源的完整封装,实现了资源创建、删除、watch等所有操作

APIGroupInfo: 是在同一个Group下的所有资源的集合

还需要注意的是: 一个资源对应着两个版本;一个版本是用户访问的接口对象(yaml或者json通过接口传递的格式) 另一个版本则是核心对象 实现了资源创建和删除等,并且直接参与持久化,对应了在etcd中存储;

这两个版本的资源是需要相互转化的,并且转换方法需要事先注册在Scheme中

接下来我们具体描述下apiserver框架下资源的构建过程

定义一个资源 先要定义好核心对象:

   type TestObjList struct {



        Items []TestObj 

   }



   type TestObj struct {}

资源的核心对象是该类型资源的主体,参与操作资源的相关方法和持久化

另外除了定义对象本身 还需要定义其对应的list以便支持list接口

然后定义该资源的"对外"版本-接口对象,可以和核心对象一样也可以不一样

例如,我们可以这样定义接口对象

   type TestObjList struct {



        Items []TestObj 

   }



   type TestObj struct {

        Number int

    }

但是Number值并不会被保存下来,因为核心对象中并没有这个值

接下来实现资源向scheme注册的接口函数 SchemeFunc---AddToScheme

    func addKnownTypes(scheme *runtime.Scheme) error {

        scheme.AddKnownTypes(SchemeGroupVersion,

            &TestObj{},

            &TestObjList{},

        )

        metav1.AddToGroupVersion(scheme, SchemeGroupVersion)

        return nil

    }

    SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)

    AddToScheme = SchemeBuilder.AddToScheme

那么我们就可以使用AddToScheme,把该对象类型(包括deepcopy和coversion方法)注册到Scheme

资源要能被restful接口访问到,是需要构建实现rest.Storage接口的对象;

我们可以借助 Registry.Store(实现了标准的存储对象接口)实现

    type REST struct {

        *registry.Store

    }



    func NewREST() *REST {

   

        store := &registry.Store{}



        return &REST{store}

    }

然后组装出APIGroupInfo(APIGroupInfo是包含了一组资源类型的集合)

    apiGroupInfo := apiserver.NewDefaultAPIGroupInfo(... Scheme)

    v1alpha1storage := map[string]rest.Storage{}

    v1alpha1storage["testobj"] = NewREST()

    apiGroupInfo.VersionedResourcesStorageMap["v1alpha1"] = v1alpha1storage

最后调用GenericAPIServer运行apiserver

GenericAPIServer.InstallAPIGroup(&apiGroupInfo).Run()

OK,现在你就可以像访问k8s 原生资源一样访问这个新的资源了

上文中代码 为了更好的突出显示资源创建逻辑,一些细节被隐藏掉了

最后总结一下:

kubernetes是一套容器化解决方案,也是一套资源管理的架构和标准.

Q&A

Q:需要扩展管理资源对象的场景是什么?能否举个例子说明一下

A:举个栗子,假如有这样一个场景,nginx作为反向代理,我们需要非常详细的管理具体配置,并且nginx的upstream不单单是容器还有许多部署在物理机和虚拟机上的应用,这就要求我们需要具体定义专门管理nginx的资源对象;由于企业应用场景是十分具体的,也就需要对于资源做具体描述

Q:能否讲下具体应用场景和联邦后的用法

A:场景上个问题讲过了 关于联邦我目前的方案是在自定义的controller里做相关联系和操作

Q:扩展api server和通过third party resource:heavy_plus_sign:controller的方式相比有哪些优点?支持和多个集群的联邦吗?k8s社区对这两种扩展模式的态度是怎么样的?

A:首先third party resource 在k8s里一直不是很稳定,再者third party resource和原生资源有很多不同(可以参考官方文档)满足一些小的场景可以,但是对于深度定制化(资源之间关联、权限限制等),我还是会选择扩展apiserver


以上所述就是小编给大家介绍的《如何扩展Kubernetes管理的资源对象》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

疯狂Java讲义(第4版)

疯狂Java讲义(第4版)

李刚 / 电子工业出版社 / 2018-1 / 109

《疯狂Java讲义(第4版)》是《疯狂Java讲义》的第4版,第4版保持了前3版系统、全面、讲解浅显、细致的特性,全面新增介绍了Java 9的新特性。 《疯狂Java讲义(第4版)》深入介绍了Java编程的相关方面,《疯狂Java讲义(第4版)》内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、J......一起来看看 《疯狂Java讲义(第4版)》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具