加强 Kubernetes 能力:利用 CRD 定义多版本资源的实现方式
姚灿武,Rancher 中国研发工程师,拥有 7 年云计算领域经验,热衷开源技术,在云原生相关技术领域拥有丰富的开发和实践经验。
CRD,即自定义资源定义(Custom Resource Definition),是 Kubernetes API 中一个强大的扩展机制。通过 CRD,用户可以定义自己的资源类型,来扩展 Kubernetes 的 API 和资源类型。CRD 定义可以用于创建多个版本的资源,这对于 Kubernetes 集群的演变和升级非常有用。
在本文中,我们将介绍 Kubernetes CRD 的版本概念和使用方法;讨论如何在 CRD 中定义多个版本的资源,并讨论资源数据存储和数据转换的实现方式。最后,我们将介绍如何开发 CRD webhook,以便在 Kubernetes 中实现 CRD 版本兼容。
多版本 CRD
多版本 CRD 是指在 CRD 中定义多个版本的 API,每个版本的 API 可以有自己的规则,这样就可以在不影响旧版本应用程序的情况下,对新版本应用程序进行更新和升级。
要创建多版本 CRD,我们需要定义一个 Custom Resource Definition 对象,该对象包含多个 version 字段。每个 version 字段都有一个 schema,其中包含了自定义资源的属性和规则。
通过一个例子来说明,以下是一个单版本 CRD 示例:
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: foos.sample.webhook.io spec: conversion: strategy: None group: sample.webhook.io names: kind: Foo listKind: FooList plural: foos shortNames: - foo - foos singular: foo scope: Namespaced versions: - name: v1 schema: openAPIV3Schema: properties: apiVersion: type: string kind: type: string metadata: type: object type: object served: true storage: true
文件中规定版本信息以及资源的名称、类型等信息。通过 kubectl apply 命令,可以将该 CRD 文件应用到 Kubernetes 集群中,从而在集群中创建一个新的资源类型 Foo,例如:
apiVersion: sample.webhook.io/v1 kind: Foo metadata: name: foo-sample
上述自定义资源 Foo 只有一个 v1 版本,如果我们需要更新自定义资源中的某个字段,就需要更新 Foo 的版本,例如更新为 v2 版本,就要在 CRD 文件中添加 v2 版本的定义,例如:
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: foos.sample.webhook.io spec: versions: - name: v1 schema: openAPIV3Schema: properties: apiVersion: type: string kind: type: string metadata: type: object type: object served: true storage: false - name: v2 schema: openAPIV3Schema: properties: alias: type: string apiVersion: type: string kind: type: string metadata: type: object type: object served: true storage: true
在上述 CRD 文件中,我们定义了两个版本,v1 和 v2。v2 相比 v1 新增了一个 alias 字段。
资源数据存储
为确保 Kubernetes 能够正确地将自定义资源持久化到存储中,并且能够正确地从存储中读取和还原自定义资源。CRD 中定义了 spec.versions.storage 字段,用于指示使用哪个版本的 CRD 持久化到存储中。在一个 CRD 定义中,只能有一个版本的 storage 字段的值为 true。
上述例子中,我们定义了两个版本,v1 和 v2。v1 版本 storage 字段为 false,v2 版本 storage 字段为 true,这表明 Kubernetes etcd 中存储的是 v2 版本的资源数据。
那么对于未被选定的版本的数据如何存储呢?以上面 foo-sample
为例,我们来看下 etcd 中是怎么存储的,结果如下:
/registry/sample.webhook.io/foos/default/foo-sample {"apiVersion":"sample.webhook.io/v2","kind":"Foo","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"sample.webhook.io/v1\",\"kind\":\"Foo\",\"metadata\":{\"annotations\":{},\"name\":\"foo-sample\",\"namespace\":\"default\"}}\n"},"creationTimestamp":"2023-05-22T09:49:03Z","generation":1,"managedFields":[{"apiVersion":"sample.webhook.io/v1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}}},"manager":"kubectl-client-side-apply","operation":"Update","time":"2023-05-22T09:49:03Z"}],"name":"foo-sample","namespace":"default","uid":"3360f129-31f7-4a3f-8991-7694524d9a78"}}
第一行是 foo-sample
的 key,第二行是 foo-sample
json 格式表示的内容,其中 apiVersion
为 sample.webhook.io/v2
,这表明即便 v1 版本的资源也以 v2 版本的格式存储。
数据转换
当自定义资源支持多个版本时,因为只能以某一个版本的格式进行存储,所以需要在存储的版本和提供的版本之间进行转换,实现多版本兼容。
- 如果转换涉及模式变更, 并且需要自定义逻辑,则应该使用 Webhook 来完成。在 CRD 中配置 webhook 示例如下:
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition ... spec: conversion: strategy: Webhook webhook: clientConfig: caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ2akNDQVdPZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQkdNUnd3R2dZRFZRUUtFeE5rZVc1aGJXbGoKYkdsemRHVnVaWEl0YjNKbk1TWXdKQVlEVlFRRERCMWtlVzVoYldsamJHbHpkR1Z1WlhJdFkyRkFNVFk0TkRjegpPRGswTXpBZUZ3MHlNekExTWpJd056QXlNak5hRncwek16QTFNVGt3TnpBeU1qTmFNRVl4SERBYUJnTlZCQW9UCkUyUjVibUZ0YVdOc2FYTjBaVzVsY2kxdmNtY3hKakFrQmdOVkJBTU1IV1I1Ym1GdGFXTnNhWE4wWlc1bGNpMWoKWVVBeE5qZzBOek00T1RRek1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUZYWDQzaEZRdjRyOApKelR1UkJ0b3lqUmRtWjhIRkExbWZnOXJnTWVlNnVXZ20wMXBNR3lSRnFna3Z1RHF5RUlMTUtCRDduQ2IrVFp3CitBR3loVWhTV0tOQ01FQXdEZ1lEVlIwUEFRSC9CQVFEQWdLa01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWUQKVlIwT0JCWUVGRzg2VnpCcW1wRUcrUWlrS0d1SGNIQlJwS2R3TUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDSVFDaQp5SFFyeGNXN3dUM0dwRWhyNklQQWpXWDVJOSt4Y0dkUGQzQURKS0hwZ2dJaEFJQmhTc00xd1hxMU80VUlaWWZwCkNWVkxwaCtvUVMvMzI5OHMwS0VqWW9FTAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== service: name: webhook-sample namespace: default path: /v1/webhook/conversion port: 443 conversionReviewVersions: - v1
- 如果没有模式变更,则可使用默认的
None
转换策略,为不同版本提供服务时只有apiVersion
字段会被改变。
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition ... spec: ... conversion: strategy: None
CRD webhook 开发
与 Admission Webhook一样,CRD webhook 也是一个 HTTP 回调,webhook service 就是一个 HTTP 服务。接口结构如下:
// ConversionReview describes a conversion request/response. type ConversionReview struct { metav1.TypeMeta `json:",inline"` // request describes the attributes for the conversion request. // +optional Request *ConversionRequest `json:"request,omitempty" protobuf:"bytes,1,opt,name=request"` // response describes the attributes for the conversion response. // +optional Response *ConversionResponse `json:"response,omitempty" protobuf:"bytes,2,opt,name=response"` }
Harvester 项目组在 harvester webhook框架中增加了 CRD webhook 的支持,开发者只需要实现 Converter
接口并把它注册到 webhook server 中,然后启动 webhook server 即可。
// Converter is a interface to convert object to the desired version type Converter interface { GroupResource() schema.GroupResource Convert(Object *unstructured.Unstructured, desiredAPIVersion string) (*unstructured.Unstructured, error) }
具体开发细节请参考示例 webhook sample。
总 结
在实际产品进化演变过程中,多版本兼容一直是一个重要的问题。Kubernetes CRD 采用选定某一个版本进行持久化,并使用 webhook 实现多版本数据转换的策略来解决多版本兼容性问题。在 Kubernetes 外的其他项目中,这种策略也值得学习借鉴。
参 考
Versions in Custom Resource Definitions:https://kubernetes.io/zh-cn/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
OceanBase 是如何关闭主备线程的?
本文总结了 OceanBase 与 MySQL 在主备同步命令和数据保护上的区别。 作者:何文超 爱可生南区交付服务部 DBA 团队成员,主要负责 MySQL 故障处理,MySQL 高可用架构改造,OceanBase 相关技术支持。爱好足球,羽毛球。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 背景 在 MySQL 主备同步中,存在 stop slave;reset slave all 这样的命令来控制关闭主备线程,删除主备相关信息。 那么在分布式的 OceanBase 中是否存在类似场景?两者的命令是否相同?又有什么区别? 说明 MySQL 中是主备库同步;OceanBase 中类似场景存在于主备集群中。 OceanBase 主备集群没有 stop slave; reset slave all 的命令,但有类似场景。 下面来详细介绍 OceanBase 中的 “stop slave; reset slave all“。 环境准备 一套 OceanBase 主备集群。 OceanBase 中的 stop slave 下面通过几个实验...
- 下一篇
支持变量,IDEA 插件 Fast Request 2023.1.8 发布
简介 Restful Fast Request是一个类似于 Postman 的 IDEA 插件。它是一个强大的 restful api 工具包插件,可以根据已有的方法帮助您快速、自动生成 url 和 params。 Restful Fast Request = API 调试工具 + API 管理工具 + API 搜索工具。 它有一个漂亮的界面来完成请求、检查服务器响应、存储你的 api 请求和导出 api 请求。插件帮助你在 IDEA 界面内更快更高效得调试你的 API。 Restful Fast Request 为简化 API 调试而生 倾听用户的声音,不断提升自我,本次Restful Fast Request更新主要内容如下: 新功能、优化项、修复项 Environment 方法描述截断 Instant类型解析 Windows系统APIs中目录删除 1. Environment 1.1 定义 Environment中可以设置存储一些变量,并且在其他地方使用{{key}}来替换固定值或者魔法值。 可以在以下场景中使用{{key}} Url Headers Path Params UR...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- 设置Eclipse缩进为4个空格,增强代码规范
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库