美文网首页
Kubernetes API

Kubernetes API

作者: 程序员札记 | 来源:发表于2022-12-01 22:06 被阅读0次

Kubernetes把其管理的资源均视为API对象,并对外提供REST风格的API来操纵这些对象。Kubernetes API由kube-apiserver组件提供,Kubernetes内部各组件与kube-apiserver通信也是使用API来驱动的,除此之外,命令行工具比如kubectl以及各种Kubernetes客户端程序均是使用API与Kubernetes通信。

APIServer

在kubernetes架构概念层面上,Kubernetes由一些具有不同角色的服务节点组成。而master的控制平面由 Apiserver Controller-manager 和 Scheduler 组成。

Apiserver 从概念上理解可以分为 api 和 object 的集合,api 可以理解为,处理读写请求来修改相应 object 的组件;而 object 可以表示为 kubernetes 对象,如 Pod, Deployment 等 。

基于声明式的API

在命令式 API 中,会直接发送要执行的命令,例如:运行、停止 等命令。在声明式API 中,将声明希望系统执行的操作,系统将不断将自身状态朝希望状态改变。

为什么使用声明式

在分布式系统中,任何组件随时都可能发生故障,当组件故障恢复时,需要明白自己需要做什么。在使用命令式时,出现故障的组件可能在异常时错过调用,并且在恢复时需要其他外部组件进行干预。而声明式仅需要在恢复时确定当前状态以确定他需要做什么。

External APIs

在kubernetes中,控制平面是透明的,及没有internal APIs。这就意味着Kubernetes组件间使用相同的API交互。这里通过一个例子来说明外部APIs与声明式的关系。

例如,创建一个Pod对象,Scheduler 会监听 API来完成创建,创建完成后,调度程序不会命令被分配节点启动Pod。而在kubelet端,发现pod具有与自己相同的一些信息时,会监听pod状态。如改变kubelet则修改状态,如果删除掉Pod(对象资源不存在与API中),那么kubelet则将终止他。

为什么不使用Internal API

使用External API可以使kubernetes组件都使用相同的API,使得kubernetes具有可扩展性和可组合性。对于kubernetes中任何默认组件,如不足满足需求时,都可以更换为使用相同API的组件。

另外,外部API还可轻松的使用公共API来扩展kubernetes的功能

API组成

一个API的组成为 一个 API 组Group , 一个版本 Version , 和一个资源 Resource ; 简称为 GVR


image.png

转换为实际的http路径为:

/api/{version}/namespaces/{namespace_name}/resources rural/{actual_resources_name}
/api/v1/namespaces/default/pods/pods123

而GVR中的R代表的是RESTful中的资源,转换为Kubernetes中资源应为 Kind,简称为 GVK,K在URI中表示在:

/apis/{GROUP}/{VERSION}/namespaces/{namespace}/{KIND}

请求和处理

这里讨论API请求和处理,API的一些数据结构位于 k8s.io/api,并处理集群内部与外部的请求,而Apiserver 位于 k8s.io/apiserver/pkg/server提供了http服务。

那么,当 HTTP 请求到达 Kubernetes API 时,实际上会发生什么?

首先HTTP请求在 DefaultBuildHandlerChain (可以参考k8s.io/apiserver/pkg/server/config.go)中注册filter chain,过滤器允许并将相应的信息附加至 ctx.RequestInfo; 如身份验证的相应

  • k8s.io/apiserver/pkg/server/mux 将其分配到对应的应用
  • k8s.io/apiserver/pkg/server/routes 定义了REST与对应应用相关联
  • k8s.io/apiserver/pkg/endpoints/groupversion.go.InstallREST() 接收上下文,从存储中传递请求的对象。
    image.png

API前缀

image.png

API中的前缀无疑会增加URL的长度,这不由得会让我们思考以下几个问题:

  • 前缀存在的意义是什么呢?

  • Kubernetes API都有哪些前缀?

要回答这个问题就要从API的定义来说起,API英文全称是Application Programming Interface,即应用程序编程接口。那么从广义上说,Kubernetes 的kube-apiserver组件对外暴露的所有端点都可以称作API,比如:

"/api/v1","/apis/admissionregistration.k8s.io","/apis/apps","/apis/authentication.k8s.io","/healthz","/livez","/metrics","/version"

应用程序可以使用这些接口来实现特定的功能,比如使用/api/v1apis/apps接口来创建资源,使用/healthz来查询集群健康状态,所以这些接口都是API。

但是,往往我们所说的Kubernetes API是狭义上的概念,即专指那些表示Kubernetes资源的API,所以为了与其他API有所区分,Kubernetes特意加了api前缀,该前缀表示这些API用于管理Kubernetes资源。

用于管理Kubernetes资源的API前缀除了api外,还有apis,在Kubernetes早期的设计中,只有api前缀,后来为了引入API组的设计,又添加了apis前缀,简单地说,使用api前缀的API是Kubernetes最核心的一组API,而使用apis前缀的API是Kubernetes发展过程中引入的分组API。

API组

前文提到Kubernetes早期只有以api为前缀的API,这些API提供了Kubernetes最核心的功能。随着Kubernetes的不断演进,Kubernetes需要引入更过的功能,也即需要提供更多的API,这不仅给Kubernetes带来了沉重的负担,也给用户带了困扰。

一方面,随着Kubernetes提供的功能增多,Kubernetes自身开发和维护难度越来越大,另一方面,用户往往只需要Kubernetes提供的部分功能。所以为了使Kubernetes更容易扩展和演进,同时可以让用户有选择性地开启和关闭非核心功能,Kubernetes设计者们提出了API分组的理念。

所谓API分组理念是指把Kubernetes的API按照功能分组,该理念被提出时Kubernetes已经有了以api为前缀的一组核心API,考虑到兼容策略,这组API不适宜修改,所以API分组实际上针对非核心的扩展API,后续新加的功能统一使用apis为前缀,并把API按组区分,部分API组如下所示:
"/apis/apps""/apis/autoscaling""/apis/rbac.authorization.k8s.io"...

出现在前缀apis后面的就是API组,比如apps表示一组用于应用管理的API,autoscaling表示一组用于应用自动扩展的API,rbac.authorization.k8s.io表示一组用于基于角色控制的API。

把API分组最大的好处在于用户可以自由地开启和关闭相应的非核心功能。用户可以使用kube-apiserver组件提供的--runtime-config参数来显式地控制某项功能是否开启。比如:

--runtime-config=autoscaling/v1=false,rbac.authorization.k8s.io/v1=true

上面的配置显式地将autoscaling功能关闭,同时把rbac.authorization.k8s.io功能开启。需要说明的是,相当大一部分API组默认是开启的,比如默认情况下rbac.authorization.k8s.io这组API是开启的,这意味着上面配置中rbac.authorization.k8s.io/v1=true是多余的,出现在本例中仅用于说明API组可以显式地控制开启和关闭。

把API分组另一非常重要的好处在于,它可以给每组API按照功能成熟度划分成不同的版本,比如v1alpha1v1beta1v1等。

API版本

每组API都有相应的版本表示其成熟度,比如autoscaling就有多个版本:
"/apis/autoscaling/v1","/apis/autoscaling/v2beta1","/apis/autoscaling/v2beta2",

为API提供版本并且多版本共存的意义在于为用户提供清晰的成熟度参考,比如版本名包含alpha表示该功能正在实验过程中,不推荐应用在生产环境中,因此Kubernetes默认不会开启这些功能,版本名包含beta表示该功能基本可用,希望用户尝试并提供反馈,因此Kubernetes往往默认启用这些功能,版本名为vx表示功能已固定,相应的API也不会再修改,用户可以放心使用。

为API分组同时为每个API提供多个版本,这允许每组功能可以不同的速度演进,而不必互相影响。

小结

了解一个应用的功能,从API入手往往能快速地掌握住该应用的概况,包括它是什么,它能用来做什么以及怎么使用它。本节简要地介绍了Kubernetes的API设计,借此读者可以从宏观上对Kubernetes API有个基本的了解,为将来详细了解每个功能点,也就是每个具体的API打下基础。

Kubernetes API的分组设计为其提供了无限的扩展能力,借此机制可以轻松地为Kubernetes提供扩展功能,用户不仅可以使用CRD(Custom Resource Definition)功能来提供新的API,还可以通过扩展apiserver来扩展功能。

前文也提到,提出API分组理念以前,Kubernetes就存在了以api为前缀的一组API,这了保持兼容性,这组核心API并没有划分到特定的组,它的API格式则是prefix/version/resource(少了group名字),比如/api/v1/Pods。通常我们在说API版本时往往是指group/version,即带上组名和版本,为了描述上的方便,社区开发者日常交流时往往称这组特别的API为core组。

相关文章

网友评论

      本文标题:Kubernetes API

      本文链接:https://www.haomeiwen.com/subject/szdyfdtx.html