Kubernetes:声明式API

一. 简介

Kubernetes 的能力都是通过各种 API 对象来提供,API 对象正是我们使用 Kubernetes 的接口,我们正是通过操作这些提供的 API 对象来使用 Kubernetes 能力的。最常见的就是 kubectl apply 命令。

二. 声明式

对于我们使用 Kubernetes API 对象的方式,一般会编写对应 API 对象的 YAML 文件交给 Kubernetes(而不是使用一些命令来直接操作 API)。所谓“声明式”,指的就是只需要提交一个定义好的 API 对象来“声明”(这个 YAML 文件其实就是一种“声明”),表示所期望的最终状态是什么样子就可以了。而如果提交的是一个个命令,去指导怎么一步一步达到期望状态,这就是“命令式”了。

这意味着 kube-apiserver 在响应命令式请求(比如,kubectl replace)的时候,一次只能处理一个写请求,否则会有产生冲突的可能。而对于声明式请求(比如,kubectl apply),一次能处理多个写操作,并且具备 Merge 能力。

三. “声明式”与“命令式”区别

  1. 在“声明式API“中,通常具有如下特点:
  • API包含相对少量的相对较小的对象(资源)
  • 这些对象定义应用程序或基础结构的配置
  • 对象相对不频繁地更新
  • 通常需要读取和写入对象
  • 对象的主要操作是 CRUD-y (creating, reading, updating and deleting)
  • 不需要跨对象进行事务处理:API 代表期望的状态,而不是当前的状态
  1. “命令式API”中,通常具有如下特点:
  • 客户端说“执行此操作”,然后在完成后返回一个同步响应
  • 客户端说“执行此操作”,然后取回操作ID,并且必须检查单独的 Operation 对象以确定请求是否完成
  • 使用远程过程调用(RPCs)
  • 直接存储大量数据,例如,每个对象大于几kB,或者大于1000个对象。
  • 需要高带宽访问(持续每秒10s的请求)
  • 存储最终用户数据(例如图像,PII 等)或应用程序处理的其他大规模数据
  • 对象上的操作不是 CRUD-y 操作
  • 该 API 很难建模为对象
  • 选择了用“操作ID”或“操作对象”表示待处理的操作

四. API 对象

4.1 组成结构

一个 API 对象在 Etcd 里的完整资源路径,是由:Group(API组)、Version(API版本)和 Resource(API资源类型)三个部分组成的。

具体案例如下图:


Api architecture

可以看出,Kubernetes 里 API 对象的组织方式,其实是层层递进的。

4.2 YAML结构

借助之前的yaml文件,参考如下的一个结构:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: demo-statefulset
spec:
  serviceName: "demo-service"
  replicas: 3
  selector:
    matchLabels:
      app: demo-nginx
  template:
  ........

在这个 YAML 文件中,StatefulSet就是这个 API 对象的资源类型(Resource),apps 就是它的组(Group),v1 就是它的版本(Version)。

4.3 API 检索流程

对 Resource、Group 和 Version 进行检索,最终定位到API对象的流程如下:

  1. 匹配 Group
    在陪陪Group时,一般分俩类。
  • 核心 API 对象
    对于 Kubernetes 里的核心 API 对象,比如:Pod、Node 等,是不需要 Group 的,因为它们的 Group 是“”。对于这些 API 对象来说,Kubernetes 会直接在 /api 这个层级进行下一步的匹配过程。
  • 非核心 API 对象
    对于 StatefulSet 等非核心 API 对象来说,Kubernetes 就必须在 /apis 这个层级里查找它对应的 Group,进而根据“apps”这个 Group 的名字,找到 /apis/apps
    这些 API Group 的分类是以对象功能为依据的,比如 DeploymentStatefulSet 就都属于“apps” 这个 Group。

具体可查看如下这张图:


Group
  1. 匹配 Version
    对于 StatefulSet 这个 API 对象来说,Kubernetes 在 apps 这个 Group 下,匹配到的版本号就是 v1。在 Kubernetes 中,同一种 API 对象可以有多个版本,这正是 Kubernetes 进行 API 版本化管理的重要手段。这样,比如在 StatefulSet 的开发过程中,对于会影响到用户的变更就可以通过升级新版本来处理,从而保证了向后兼容。

  2. 匹配 Resource
    在前面匹配到正确的版本之后,Kubernetes 就知道,要创建的原来是一个 /apis/apps/v1 下的 StatefulSet 对象。

五. 概念拓展

5.1 CRD

CRD 的全称是 Custom Resource Definition。它指的就是,允许用户在 Kubernetes 中添加一个跟 Pod、Node 类似的、新的 API 资源类型,即:自定义 API 资源。

5.2 ListAndWatch

在 ListAndWatch 机制下,一旦 APIServer 端有新的实例被创建、删除或者更新,Reflector 都会收到“事件通知”。
ListAndWatch 方法的含义是:

  • 首先,通过 APIServer 的 LIST API“获取”所有最新版本的 API 对象。
  • 然后,再通过 WATCH API 来“监听”所有这些 API 对象的变化。

六. 总结

综上,Kubernetes“声明式 API”的独特之处:

  • 首先,所谓“声明式”,指的就是只需要提交一个定义好的 API 对象来“声明”所期望的状态。
  • 其次,“声明式 API”允许有多个 API 写端,以 PATCH 的方式对 API 对象进行修改,而无需关心本地原始 YAML 文件的内容。
  • 最后,基于上面俩种能力,Kubernetes 才可以基于对 API 对象的增、删、改、查,在完全无需外界干预的情况下,完成对“实际状态”和“期望状态”的调谐(Reconcile)过程。

所以“声明式 API“ 才是 Kubernetes 项目编排能力“赖以生存”的核心所在,PaaS平台与这完全没有可比性。

欢迎收藏个人博客: Wyatt's Blog ,非常感谢~

Reference

https://docs.openshift.com/container-platform/4.5/rest_api/workloads_apis/workloads-apis-index.html
https://time.geekbang.org/column/article/42493?utm_campaign=guanwang&utm_source=baidu-ad&utm_medium=ppzq-pc&utm_content=title&utm_term=baidu-ad-ppzq-title
https://blog.csdn.net/KevinBetterQ/article/details/104012293
https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/

你可能感兴趣的:(Kubernetes:声明式API)