K8S自定义资源

K8S 中可以实现自定义资源类型,它是K8S API的一种扩展。K8S中自定义的资源类型可以动态注册和销毁,当用户创建一个自定义资源类型后,用户可以通过使用kubectl命令来创建该类型资源,操作同内置资源对象无异。

如何判断是否该使用自定义资源

考虑使用自定义资源(API聚合) 考虑使用单独API
API是声明式的 API不适合声明式
你希望通过kubectl读写新对象 kubectl命令的支持是非必须的
你希望通过k8s ui(dashboard等)查看新的资源类型对象 k8s ui不必支持查看该资源
你是正在开发新的API 你已经完成服务开发,并且正常工作
愿意接受资源rest path限制,例如namespace和api group 你需要特定的rest path来适配已有的api
你的资源对象会被限制在集群或者namespace中 集群或namespace 不适合你的项目,你需要精细控制资源路径
你希望重用k8s api feature 你不需要这些feature

自定义资源扩展方式

在K8S中扩展自定义资源共有两种实现方式:CRD、 API Aggregate。

两种实现方式各有特点,K8S提供两种方式来满足不同用户的不同需求,既不影响易用性、也不影响灵活性。

CRD

CRD特点

  1. 使用简单
  2. 只需实现controller逻辑即可,不必关心资源对象存储、CURD等一系列操作
  3. crd允许用户创建新的资源类型而无需添加额外的API服务器,使用它无需了解API Aggregate

该CustomResourceDefinition API资源让您可以定义自定义资源。定义CRD对象会使用您指定的名称和架构创建一个新的自定义资源。Kubernetes API服务并处理您的自定义资源的存储。CRD对象的名称必须是有效的 DNS子域名。

这使您不必编写自己的API服务器来处理自定义资源,但是实现的通用性意味着您的灵活性比 API服务器聚合要小。

有关如何注册新的自定义资源,使用新资源类型的实例以及使用控制器来处理事件的示例,请参考自定义控制器示例

API Aggregate

API Aggregate

  1. 需要额外编程
  2. 允许用户自定义实现超过API提供的能力:数据如何存储、API版本转换等
  3. 可把k8s apiserver看做代理,最终api的处理逻辑需要用户自己实现,对用户来说,它只是扩展了k8s api

通常,Kubernetes API中的每个资源都需要处理REST请求并管理对象持久存储的代码。Kubernetes API主服务器处理诸如Pod和Services之类的内置资源,还可以通过CRD通用地处理自定义资源。

在汇聚层,您可以通过编写和部署自己的独立API服务器提供自定义资源的专用实现。主API服务器将请求处理的自定义资源委托给您,使其对所有客户端可用。

如何选择

CRD 更易用,AA(API Aggregated)更灵活,根据需求要选用合适的方案。

通常来说,在以下几种情况下可能CRD是一个好的选择(考虑易用性):

  1. 你有一些字段
  2. 正在使用公司内部资源,或作为小型开源项目的一部分(非商业产品)

易用性比较

CRDs AA
无需设计方案,用户可选择任意开发语言实现CRD controller 需要在Go编程和构建二进制包和镜像
没有额外的服务运行,被API server接管 要创建的附加服务可能会失败。
一旦创建了CRD,就不提供持续的支持。任何bug修复都将作为常规的Kubernetes Master升级的一部分。 可能需要定期从上游获取错误修复,并重新构建和更新聚合的API服务器。
不必管理多版本API。例如,当控制资源的client时,可以用API同步升级 你需要处理多个版本的API;例如,当开发一个与世界共享的扩展时。

高级特性和灵活性

AA 提供更高级的API特性和对其他特性的定制;例如,存储层。

Feature 描述 CRDs AA
Validation 帮助用户避免错误,允许您独立于客户端发展API。当有许多客户端不能同时更新时,这些特性最有用。 YES,大多数验证都可以使用OpenAPI v3.0验证在CRD中指定。附加的验证Webhook支持的任何其他验证。 YES,任意的验证检查
Defaulting YES,要么通过OpenAPI v3.0验证默认关键字(1.17中GA),要么通过一个可变的Webhook(尽管这将在etcd读取旧对象时不运行) YES
Multi-versioning 允许通过两个API版本服务相同的对象。可以帮助简化API更改,比如重命名字段。如果您控制您的客户端版本,则不太重要。 YES,crd资源版本 YES
Custom Storage 如果您需要使用不同的性能模式进行存储(例如,时间序列数据库而不是键值存储)或安全性隔离(例如,敏感信息的加密等)。 NO YES
Custom Business Logic 在创建、读取、更新或删除对象时执行任意检查或操作 YES,webhook YES
Scale Subresource 允许像HorizontalPodAutoscaler和PodDisruptionBudget这样的系统与你的新资源交互 YES YES
Status Subresource 允许细粒度的访问控制,其中用户写入spec部分,控制器写入status部分。允许在自定义资源数据突变时生成递增的对象(需要在资源中单独的规范和状态部分) YES YES
Other Subresources 添加CRUD以外的操作,如“logs”或“exec”。 NO YES
strategic-merge-patch 新的endpoint支持用Content-Type: application/strategic-merge-patch+json的PATCH操作,用于更新可能被本地和服务器修改的对象。有关更多信息,请参见“使用kubectl补丁更新API对象 NO YES
Protocol Buffers 新的资源支持希望使用Protocol Buffers的客户端 NO YES
OpenAPI Schema 是否有一个OpenAPI (swagger)模式可以从服务器动态获取类型?通过确保只设置允许的字段,用户可以避免字段名称拼写错误吗?是否强制执行类型(换句话说,不在string类型字段中放入int类型?) YES,基于OpenAPI v3.0验证模式(1.16中GA) YES

通用Feature


Feature 考虑使用单独API
CRUD 支持通过http、kubectl对资源的curd基本操作
Watch 支持通过http的watch操作
Discovery 像kubectl和dashboard这样的客户端自动提供对资源的列表、显示和字段编辑操作
json-patch 支持Content-Type: application/json-patch+json的PATCH操作
merge-patch 支持Content-Type: application/merge-patch+json的PATCH操作
HTTPS 使用https
Built-in Authentication 对扩展的访问使用核心API服务器(聚合层)进行身份验证
Built-in Authorization 对扩展的访问可以重用核心API服务器使用的授权;例如,RBAC。
Finalizers 阻塞扩展资源的删除操作,直到外部的cleanup操作发生
Admission Webhooks 在create/update/delete操作时对资源设置默认值和校验
UI/CLI Display kubectl dashboard可以展示这些资源
Unset versus Empty 客户端可以区分未设置的字段和零值的字段。
Client Libraries Generation Kubernetes提供了通用的client库,以及用于生成特定类型的client库的工具
Labels and annotations 跨对象的通用元数据,工具知道如何为核心和自定义资源编辑这些元数据

其他注意事项

结尾

本文翻译自k8s官方文档