Kubernetes APIService资源
1、概述
在kubernetes上扩展资源类型的方式有三种,第一种是CRD,CRD是kubernetes内建的资源类型,该类型资源主要用来创建用户自定义资源类型的资源;即通过CRD资源,可以将用户自定义资源类型转换为kubernetes上资源类型;第二种是自定义apiserver;这种方式要比第一种方式要复杂一点,需要用户手动开发程序实现对应功能的apiserver,让其用户创建自定义类型资源能够通过自定义apiserver实现;第三种方式就是修改现有kubernetes apiserver服务,让其支持对应用户自定义资源类型。
本文主要是讲解kubernetes的第二种扩展机制自定义apiserver,以及APIService资源。
2、Kubernetes原生apiserver
在开始聊自定义apiserver前,我们先来了解下kubernetes原生的apiserver。
2.1 apiserver资源组织逻辑
其实apiserver就是一个https服务器,我们可以使用kubectl工具通过https协议请求apiserver创建资源,删除资源,查看资源等等操作;每个请求都对应着restful api中的请求方法,对应资源就是http协议中的url路径;比如我们要创建一个pod,其kubectl请求apiserver 使用post方法将资源定义提交给apiserver;pod资源就是对应群组中的某个版本下某个名称空间下的某个pod资源。
客户端访问apiserver,对应资源类似上图中的组织方式;比如访问default名称空间下某个pod,其路径就为/apis/core/v1/namespace/default/pod/mypod;对应resource包含命名空间以及对应资源类型;
2.2 k8s原生apiserver组成
kubernetes原生apiserver主要有两个组件组成,第一个组件aggregator,其功能类似web代理服务器,第二个组件就是真正的apiserver;其工作逻辑是,用户请求首先送达给aggregator,由aggregator根据用户请求的资源,将对应请求路由至apiserver;简单讲aggregator这个组件主要作用就是用来路由用户请求;默认情况aggregator会把所有请求都路由至原生的apiserver上进行响应;如果我们需要自定义apiserver,就需要在默认的aggregator上使用APIService资源将自定义apiserver注册到原生的apiserver上,让其用户请求能够被路由至自定义apiserver进行响应;如下图
apiserver是kubernetes的唯一访问入口,默认客户端的所有操作都是发送给apiserver进行响应,我们自定义的apiserver要想能够被客户端访问,就必须通过内建apiserver中的aggregator组件中的路由信息,把对应路径的访问路由至对应apiserver进行访问;对应aggregator中的路由信息,由k8s内建APIService资源定义;简单讲APIService资源就是用来定义原生apiserver中aggregator组件上的路由信息;该路由就是将某某端点的访问路由至对应apiserver;
查看原生apiserver中的群组/版本信息:
[root@master1 ~]# kubectl api-versions admissionregistration.k8s.io/v1 admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 ........
只有上面列出的群组版本才能够被客户端访问,即客户端只能访问上述列表中群组版本中的资源,没有出现群组版本是一定不会被客户端访问到。在原生kubernetes集群根据业务需求创建的CRD资源的group/version信息也能通过上述命令查询到,假设我在原生kubernetes集群中创建了一个自定义CRD,其group是iam.zmc.io,version是v1alpha2,那么在kubernetes集群中查询对应APIService资源会查询到。
[root@master1 ~]# kubectl get apiservices.apiregistration.k8s.io v1alpha2.iam.zmc.io NAME SERVICE AVAILABLE AGE v1alpha2.iam.zmc.io Local True 14s
3、APIService资源的使用
3.1 APIService资源介绍
APIService 是用来表示一个特定的 GroupVersion
的中的 server,它的结构定义位于代码 staging/src/k8s.io/kube-aggregator/pkg/apis/apiregistration/types.go
中。
下面是一个 APIService 的示例配置:
[root@master1 ~]# cat apiservice-demo.yaml apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: name: v2beta1.auth.ilinux.io spec: insecureSkipTLSVerify: true group: auth.ilinux.io groupPriorityMinimum: 1000 versionPriority: 15 service: name: auth-api namespace: default port: 443 version: v2beta1
3.2 APIService资源详解
使用 apiregistration.k8s.io/v1beta1
版本的 APIService,在 metadata.name 中定义该 API 的名字。
使用上面的 yaml 的创建 v2beta1.auth.ilinux.io APIService。
insecureSkipTLSVerify
:当与该服务通信时,禁用 TLS 证书认证。强加建议不要设置这个参数,默认为 false。应该使用 CABundle 代替。service
:与该 APIService 通信时引用的 service,其中要注明 service 的名字和所属的 namespace,如果port参数为空的话,则所有的服务将在本地 443 端口处理所有通信。上述资源清单表示在aggregator上注册auth.ilinux.io/v2beta1这个端点,该端点对应的后端apiserver的service是default名称空间下的auth-api service;即客户端访问auth.ilinux.io/v2beta1下的资源都会被路由至default名称空间下的auth-api service进行响应;groupPriorityMinimum
:该组 API 的处理优先级,主要排序是基于groupPriorityMinimum
,该数字越大表明优先级越高,客户端就会与其通信处理请求。次要排序是基于字母表顺序,例如 v1.bar 比 v1.foo 的优先级更高。versionPriority
:VersionPriority 控制其组内的 API 版本的顺序。必须大于零。主要排序基于 VersionPriority,从最高到最低(20 大于 10)排序。次要排序是基于对象名称的字母比较。 (v1.foo 在 v1.bar 之前)由于它们都是在一个组内,因此数字可能很小,一般都小于 10。
3.3 查看集群支持的 APISerivce
作为 Kubernetes 中的一种资源对象,可以使用 kubectl get apiservice
来查看。
例如查看集群中所有的 APIService:
$ kubectl get apiservice NAME AGE v1. 2d v1.authentication.k8s.io 2d v1.authorization.k8s.io 2d v1.autoscaling 2d v1.batch 2d ........
另外查看当前 kubernetes 集群支持的 API 版本还可以使用kubectl api-versions
:
$ kubectl api-versions apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1beta1 apps/v1beta1 apps/v1beta2 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 ..........
3.4 应用清单
[root@master1 ~]# kubectl apply -f apiservice-demo.yaml apiservice.apiregistration.k8s.io/v2beta1.auth.ilinux.io created [root@master1 ~]# kubectl get apiservice |grep auth.ilinux.io v2beta1.auth.ilinux.io default/auth-api False (ServiceNotFound) 16s [root@master1 ~]# kubectl api-versions |grep auth.ilinux.io auth.ilinux.io/v2beta1
可以看到应用清单以后,对应的端点信息就出现在api-versions中;上述清单只是用来说明对应APIService资源的使用;其实应用上述清单创建apiservice资源没有实质的作用,其原因是我们对应名称空间下并没有对应的服务,也没有对应自定义apiserver;所以通常自定义apiserver,我们会用到APIService资源来把自定义apiserver整合进原生apiserver中;这块内容我们在metrics-server篇章讲解(metrics-server是用来扩展k8s的第三方apiserver,其主要作用是收集pod或node上的cpu和内存的指标数据,并提供一个api接口供kubectl top命令访问;默认情况kubectl top 命令是没法正常使用,其原因是默认apiserver上没有对应的接口提供收集pod或node的cpu,内存的指标数据;kubectl top命令主要用来显示pod/node资源的cpu,内存的占用比例;该命令能够正常使用必须依赖Metrics API)。
4、总结
APIService资源的主要作用就是在aggregator上创建对应的路由信息,该路由信息的主要作用是将对应端点访问路由至自定义apiserver所对应的service进行响应。
本文大部分内容参考本篇博文:https://www.cnblogs.com/qiuhom-1874/archive/2021/01/15/14279850.html
作者:Linux-1874