首页 > 其他分享 >27-K8 CRD:如何根据需求自定义你的 API?

27-K8 CRD:如何根据需求自定义你的 API?

时间:2024-01-11 13:57:00浏览次数:32  
标签:27 Kubernetes 自定义 apiserver API CRD type example

随着使用的深入,你会发现 Kubernetes 中内置的对象定义,比如 Deployment、StatefulSet、Configmap,可能已经不能满足你的需求了。你很希望在 Kubernetes 定义一些自己的对象,一来可以通过 kube-apiserver 提供统一的访问入口,二来可以像其他内置对象一样,通过 kubectl 命令管理这些自定义的对象。

Kubernetes 中提供了两种自定义对象的方式,一种是聚合 API,另一种是 CRD。

我们今天就来看看。

聚合 API

聚合 API(Aggregation API,AA)是自 Kubernetes v1.7 版本就引入的功能,主要目的是方便用户将自己定义的 API 注册到 kube-apiserver 中,并且可以像使用其他内置的 API 一样,通过 APIServer 的 URL 就可以访问和操作。

在使用 API 聚合之前,我们还需要通过一些参数在 kube-apiserver 中启用这个功能:

--requestheader-client-ca-file=<path to aggregator CA cert>
--requestheader-allowed-names=front-proxy-client
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--proxy-client-cert-file=<path to aggregator proxy cert>
--proxy-client-key-file=<path to aggregator proxy key>

Kubernetes 在 kube-apiserver 中引入了一个 API 聚合层(API Aggregation Layer),可以将访问请求转发到后端用户自己的扩展 APIServer 中。你可以参考这个文档学习如何安装一个扩展的 APIServer。当然,扩展的 APIServer 需要你自己修改并实现相关的代码逻辑。

  • Kubernetes apiserver 会判断 --requestheader-client-ca-file 指定的 CA 证书中的 CN 是否是 --requestheader-allowed-names 提供的列表名称之一。如果不是,则该请求被拒绝。如果名称允许,则请求会被转发。

  • 接着 Kubernetes apiserver 将使用由 --proxy-client-*-file 指定的文件来访问用户的扩展 APIServer。

下图就是用户发起请求后一个完整的身份认证流程,你可以阅读官方文档来详细了解步骤 。

Drawing 0.png

图 1:一个完整的身份认证流程

配置好了上述参数后, 为了让 kube-apiserver 知道我们自定义的 API,我们需要创建一个 APIService 的对象,比如:

apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: v1alpha1.wardle.example.com # 对象名称
spec:
  insecureSkipTLSVerify: true
  group: wardle.example.com # 扩展 Apiserver 的 API group 名称
  groupPriorityMinimum: 1000 # APIService 对对应 group 的优先级
  versionPriority: 15 # 优先考虑 version 在 group 中的排序
  service:
    name: myapi # 扩展 Apiserver 服务的 name
    namespace: wardle # 扩展 Apiserver 服务的 namespace 
  version: v1alpha1 # 扩展 Apiserver 的 API version

通过上述 YAML 文件,我们就在 kube-apiserver 中创建一个 API 对象组,其对应的组(Group)为 wardle.example.com,版本号为 v1alpha1。创建成功后,我们就可以通过 /apis/wardle.example.com/v1alpha1 这个路径访问了。至于这个对象组里提供了哪些对象,就需要我们在扩展的 APIServer 中声明出来了。

那 kube-apiserver 又是怎么知道将 /apis/wardle.example.com/v1alpha1 这个路径的所有请求转发到后端的扩展 APIServer 中的呢?我们注意到上面的 APIService 定义中,还有一个 spec.service 字段,就是在这里,我们指定了扩展 APIServer 的服务名,也就是说 kube-apiserver 会将 /apis/wardle.example.com/v1alpha1 这个路径的所有访问通过 API 聚合层转发到后端的服务 myapi.wardle.svc 上。

扩展 APIServer 的具体代码设计及逻辑,你可以参考sample-apiserver或者使用apiserver-builder

这种聚合 API 的方式对代码要求很高,但支持对 API 行为进行完全的掌控,比如你可以自己定义数据如何存储、API 各个版本的切换、各个对象的逻辑控制。

如果你只想简简单单地在 Kubernetes 中定义个对象,可以直接通过下面要介绍的 CRD 定义。

CRD

CRD(CustomResourceDefinitions)在 v1.7 刚引入进来的时候,其实是 ThirdPartyResources(TPR)的升级版本,而 TPR 在 v1.8 的版本被剔除了。CRD 目前使用非常广泛,各个周边项目都在使用它,比如 Ingress、Rancher。

我们来看一下官方的一个例子,通过如下的 YAML 文件,我们可以创建一个 API:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名字必须与下面的 spec 字段匹配,并且格式为 '<名称的复数形式>.<组名>'
  name: crontabs.stable.example.com
spec:
  # 组名称,用于 REST API: /apis/<组>/<版本>
  group: stable.example.com
  # 列举此 CustomResourceDefinition 所支持的版本
  versions:
    - name: v1
      # 每个版本都可以通过 served 标志来独立启用或禁止
      served: true
      # 其中一个且只有一个版本必需被标记为存储版本
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer
  # 可以是 Namespaced 或 Cluster
  scope: Namespaced
  names:
    # 名称的复数形式,用于 URL:/apis/<组>/<版本>/<名称的复数形式>
    plural: crontabs
    # 名称的单数形式,作为命令行使用时和显示时的别名
    singular: crontab
    # kind 通常是单数形式的驼峰编码(CamelCased)形式。你的资源清单会使用这一形式。
    kind: CronTab
    # shortNames 允许你在命令行使用较短的字符串来匹配资源
    shortNames:
    - ct

我们可以像创建其他对象一样,通过 kubectl create 命令创建。创建好了以后,一个类型为 CronTab 的对象就在 kube-apiserver 中注册好了,你可以通过如下的 REST 接口访问,比如 LIST 命名空间 ns1 下的 CronTab 对象,可以通过这个 URL“/apis/stable.example.com/v1/namespaces/ns1/crontabs/”访问。这种接口跟 Kubernetes 内置的其他对象的接口风格是一模一样的。

声明好了 CronTab,下面我们就来看看如何创建一个 CronTab 类型的对象。我们来看看官方给的一个例子:

apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: "* * * * */5"
  image: my-awesome-cron-image

通过 kubectl create 创建 my-new-cron-object 后,就可以通过 kubectl get 查看,并使用 kubectl 管理你的 CronTab 对象了。例如:

kubectl get crontab
NAME                 AGE
my-new-cron-object   6s

这里的资源名是大小写不敏感的,我们在这里可以使用缩写 kubectl get ct,也可以使用 kubectl get crontabs。

同时原生内置的 API 对象一样,这些 CRD 不仅可以通过 kubectl 来创建、查看、修改,删除等操作,还可以给其配置 RBAC 规则。

我们还能开发自定义的控制器,来感知和操作这些自定义的 API。这一部分我会在下一讲中介绍。

我们在创建 CRD 的时候,还可以一起定义 /status 和 /scale 子资源,如下所示:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer
            status:
              type: object
              properties:
                replicas:
                  type: integer
                labelSelector:
                  type: string
      # subresources 描述定制资源的子资源
      subresources:
        # status 启用 status 子资源
        status: {}
        # scale 启用 scale 子资源
        scale:
          # specReplicasPath 定义定制资源中对应 scale.spec.replicas 的 JSON 路径
          specReplicasPath: .spec.replicas
          # statusReplicasPath 定义定制资源中对应 scale.status.replicas 的 JSON 路径 
          statusReplicasPath: .status.replicas
          # labelSelectorPath  定义定制资源中对应 scale.status.selector 的 JSON 路径 
          labelSelectorPath: .status.labelSelector
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
    shortNames:
    - ct

这些子资源的定义,可以帮助我们在更新对象的时候,只更改期望的部分,比如只更新 status 部分,避免误更新 spec 部分。

同时 CRD 定义的时候还支持合法性检查设置默认值等操作,你可以参照文档来实践。

写在最后

当然,你也可以选择在其他地方定义新的 API,你可以参考这份文档确定是否需要在 Kubernetes 中定义 API,还是让你的 API 独立运行。

你可以通过这个网址中的内容来比较 CRD 和 聚合 API 的功能差异。简单来说,CRD 更为易用,而聚合 API 更为灵活。

Kubernetes 提供这两种选项以满足不同用户的需求,这样就既不会牺牲易用性也不会牺牲灵活性。

对于聚合 API 和 CRD,你还有什么问题的话,欢迎在留言区留言。

下一讲,我将介绍如何通过 Operator 扩展 Kubernetes API。


标签:27,Kubernetes,自定义,apiserver,API,CRD,type,example
From: https://www.cnblogs.com/huangjiale/p/17958429

相关文章

  • 28-面向 K8 编程:如何通过 Operator 扩展 Kubernete API?
    你好,我是正范。在上一讲,我们学习了如何通过一个YAML文件来定义一个CRD,即扩展API。这种扩展API跟Kubernetes内置的其他API同等地位,都可以通过kubectl或者REST接口访问,在使用过程中不会有任何差异。但只是定义一个CRD并没有什么作用。虽说kube-apiserver会将其数......
  • 【转】C# WinForm 自定义控件,DataGridView背景透明,TabControl背景透明
    原文:https://www.cnblogs.com/leavind/p/6732530.html 1usingSystem.ComponentModel;2usingSystem.Drawing;3usingSystem.Windows.Forms;4namespaceRaywindStudio.Components5{6publicclassTabCtrlX:TabControl7{8publicT......
  • 27-抽象类 Abstract
    抽象类是一个特殊的父类,其内部允许编写抽象方法 publicclassAbstractDemo{publicstaticvoidmain(String[]args){//抽象类不能实例化//Animalanimal=newAnimal();//error:Animalisabstract;cannotbeinstantiatedCatca......
  • Vue2 使用 Knova Canvas 合成图片、多个视频、音频在一个画面中并播放,自定义 video co
    本文转载https://blog.csdn.net/RosaChampagne/article/details/128020428?spm=1001.2014.3001.5502的文章安装插件npminstallvue-konva@2konva--save在main.js中使用importVuefrom'vue';importVueKonvafrom'vue-konva';Vue.use(VueKonva);相关实现代......
  • 想要数据去伪存真?不知道数据的真假?企查查开放平台的API来告诉你
    企查查开放平台使用说明:数据接入与应用实践在数字化时代,企业信息的透明度和可获取性对于商业决策至关重要。企查查开放平台作为一个提供企业数据服务的平台,为用户提供了便捷的数据接入方式和丰富的信息查询功能。本文将详细介绍如何使用企查查开放平台,以及如何将其应用于实际业务......
  • 使用Winform开发自定义用户控件,以及实现相关自定义事件的处理
    在我们一些非标的用户界面中,我们往往需要自定义用户控件界面,从而实现不同的内容展示和处理规则,本篇内容介绍使用Winform开发自定义用户控件,以及实现相关自定义事件的处理。1、用户控件的界面分析对于比较规范的界面,需要进行一定的分析,以便从中找到对应的规则,逐步细化为自定义用......
  • 自定义快捷键实操与踩坑
    0.缘起要做一个自定义快捷键的功能,web端实现。这里分为两块逻辑,一部分是快捷键的应用,一部分是快捷键的定义。先从应用说起,快捷键实际上是对浏览器按键动作的监听,不过由于浏览器本身也有快捷键,就会有冲突的情况,自定义的要求应运而生。快捷键的定义,其实类似于设置的功能,也是存、......
  • 【OpenVINO】 使用 OpenVINO CSharp API 部署 PaddleOCR 项目介绍
    前言: 在之前的项目中,我们已经使用OpenVINOTMCSharpAPI部署PaddleOCR全系列模型,但随着PaddleOCRv4版本发布以及OpenVINOCSharpAPI版本迭代,上一版本的项目已经不再适用。因此在推出的最新项目中,已经完成了对PaddleOCRv4的匹配,并且采用了最新版本的OpenVINOTMCSha......
  • 2024 年的 API 管理新动向
    本文译自:WhatWillBetheAPIManagementTrendsfor2024?原文链接:https://thenewstack.io/what-will-be-the-api-management-trends-for-2024/原文作者:KennHussey预计到2030年末,API管理 市场的规模将增长六倍,这一增长主要受到一个核心理念的推动:API完全控制了数字世界。随......
  • Gateway API 实践之(一)FSM Gateway 中的故障注入策略
    在之前的文章中,我们快速体验了FSMGateway-一个开源的K8sGatewayAPI的实现。在即将发布的FSM1.2中,FSMGateway将会带来更多的功能:故障注入策略限流策略会话保持策略负载均衡算法熔断策略访问控制策略健康检查策略TLS上游策略...后面我们会推出系列的文章来介绍这些功......