回忆KubernetesApi

Kubernetes API 是经过 HTTP 供给的依据资源 (RESTful) 的编程接口。 它支撑经过规范 HTTP 动词(POST、PUT、PATCH、DELETE、GET)检索、创立、更新和删去主要资源。关于某些资源,API 包括额外的子资源,答应细粒度授权(例如:将 Pod 的详细信息与检索日志分隔), 为了方便或许进步功率,能够以不同的表明方式接受和服务这些资源。

Kubernetes 支撑经过 watch 实现高效的资源改变告诉。 Kubernetes 还供给了共同的列表操作,以便 API 客户端能够有效地缓存、跟踪和同步资源的状况

先要清晰API资源

  • 资源类型(Resource Type) 是 URL 中运用的名称(podsnamespacesservices
  • 一切资源类型都有一个详细的表明(它们的目标方式),称为 类别(Kind)
  • 资源实例的列表称为 调集(Collection)
  • 资源类型的单个实例称为 资源(Resource) ,通常也表明一个 目标(Object)
  • 关于某些资源类型,API 包括一个或多个 子资源(sub-resources) ,这些子资源表明为资源下的 URI 路径

再清晰资源URL的规矩

  • /api前缀是kubernetes核心目标的URL,例如pod,configmap,service等,这些目标都是归于core包中的。

    例如:/api/v1/pods,/api/v1/configmaps

  • /apis前缀归于拓展资源的URL,例如deployment,deamonset

    其URL依照:

    • 集群规模资源: /apis/GROUP/VERSION/RESOURCETYPE
    • 命名空间规模资源:/apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE

再清晰资源版别resourceVersion

资源版别是标识服务器内部目标版别的字符串。 客户端能够运用资源版别来确认目标何时更改, 或许在获取列出监督资源时表达数据共同性要求。 资源版别有必要被客户端视为不透明的,而且未经修正地传回服务器。

你不能假设资源版别是数字的或可排序的。 API 客户端只能比较两个资源版别的持平性(这意味着你不能比较资源版别的大于或小于关系)。

  • metadata 中的 resourceVersion

    客户端在资源中查找资源版别,这些资源包括来自用于 watch 的呼应流资源,或许运用 list 枚举的资源。

    • v1.meta/ObjectMeta – 资源的 metadata.resourceVersion 值标明该实例前次被更改时的资源版别。

    • v1.meta/ListMeta – 资源调集即 list 操作的呼应)的 metadata.resourceVersion 所标明的是 list 呼应被结构时的资源版别。

    一个是资源被修正时的resourceVersion

    一个是在咱们结构list恳求时的resourceVersion

  • 查询字符串中的 resourceVersion 参数

    getlistwatch 操作支撑 resourceVersion 参数。API 服务器依据你恳求的操作和 resourceVersion 的值对 resourceVersion 参数进行不同的解说。 假如你设置 resourceVersionMatch 那么这也会影响匹配产生的方法。

1.检测资源

Kubernetes API 答应客户端对目标或调集宣布初始恳求,然后跟踪自该初始恳求以来的更改:watch。 客户端能够发送 list 或许 get 恳求,然后宣布后续 watch 恳求。

为了使这种更改跟踪成为可能,每个 Kubernetes 目标都有一个 resourceVersion 字段, 表明存储在底层耐久层中的该资源的版别。在检索资源调集(命名空间或集群规模)时, 来自 API 服务器的呼应包括一个 resourceVersion 值。 客户端能够运用该 resourceVersion 来启动对 API 服务器的 watch

当你发送 watch 恳求时,API 服务器会呼应更改流。 这些更改逐项列出了在你指定为 watch 恳求参数的 resourceVersion 之后产生的操作(例如 createdeleteupdate)的成果。 整个 watch 机制答应客户端获取当前状况,然后订阅后续更改,而不会丢掉任何事情。

咱们能够经过list恳求获取资源信息,进行第一步的全局同步全量更新,后续依据resourceVersion进行watch监听,以进行后续的资源增量更新。咱们后续学习的client-go很多用到list+watch特性,这个咱们后续再进行深度介绍。

有了解过ETCD的同学应该清楚revision,其实resourceVersion就是利用了ETCD中revision + watch特性,每逢资源进行改变,则服务端则会发送一个对应的事情event告知客户端。假如客户端 watch 衔接断开,则该客户端能够从最后回来的 resourceVersion 开端新的 watch 恳求; 客户端还能够履行新的 get/list 恳求并从头开端。

1.1 List/Watch

# list操作
# 获取default命名空间下的service
# 注: $KUBEAPI是我个人设置的kube api地址
$ curl $KUBEAPI/api/v1/namespaces/default/services# ------
# 输出如下:
# 其间resourceVersion就是资源版别 全局单调递增
#{
#  "kind": "PodList",
#  "apiVersion": "v1",
#  "metadata": {"resourceVersion":"5767454"},
#  "items": [...]
#}# watch操作
# 检测从resourceVersion=5767454开端(例如 create、delete、apply 或 update)的告诉
$ curl $KUBEAPI/api/v1/namespaces/default/services?watch=1&resourceVersion=5767454#------
# 首先会进行ADD事情增量
# 后续对service进行修正或删去,会对应获取到
# MODIFIED/DELETED事情

注意:给定的 Kubernetes 服务器只会保留必定的时刻内产生的前史改变列表。 运用 etcd3 的集群默认保存曩昔 5 分钟内产生的改变。 当所恳求的 watch 操作由于资源的前史版别不存在而失败, 客户端有必要能够处理因此而回来的状况代码 410 Gone,清空其本地的缓存, 从头履行 get 或许 list 操作, 并依据新回来的 resourceVersion 来开端新的 watch 操作。

关于订阅调集,Kubernetes 客户端库通常会为 list -然后- watch 的逻辑供给某种方式的规范工具。 (在 Go 客户端库中,这称为 反射器(Reflector),坐落 k8s.io/client-go/tools/cache 包中。

1.2 Bookmarks

为了减轻短前史窗口的影响,Kubernetes API 供给了一个名为 BOOKMARK 的监督事情。 这是一种特别的事情,用于符号客户端恳求的给定 resourceVersion 的一切更改都已发送。

在Kubernetes中,Kubernetes API拜访的书签(Bookmark)是一种机制,用于在长时刻运行的操作中跟踪资源列表的状况。它答应客户端在屡次恳求之间坚持一个耐久的游标,并回来一组资源的片段而不是完好的资源列表。

运用书签功能能够分批次地获取资源列表,从而降低对API服务器的负载,并减少呼应时刻。客户端能够运用书签机制来定期轮询资源列表,而无需每次恳求获取整个列表。

在Kubernetes API中,书签由resourceVersion字段表明,它是一个表明资源版别的字符串。当客户端建议一个带有书签的API恳求时,API服务器会回来该资源列表的快照,并在呼应中包括新的书签值。客户端能够将此书签值用于后续恳求,以获取自前次恳求以来更新的资源列表。

经过运用书签,客户端能够有效地追踪和处理很多资源,而无需在每个恳求中获取整个列表。这关于监督和同步资源状况十分有用,特别是当资源数量庞大时。

运用书签的好处是,您能够确保在从头衔接到API服务器后不会错失任何重要的资源更改。经过指定从前观察到的资源版别作为书签,API将回来从该版别之后产生的事情,以便您能够从从前的状况康复并接收到完好的更改前史。

这关于需求实时监控资源更改的应用程序和工具十分有用。经过运用书签,您能够坚持与Kubernetes集群的同步,并接收到在您断开衔接期间产生的任何重要更改的告诉。这能够避免您在从头衔接后需求从头获取整个资源列表,并使您能够有效地处理资源的增量更新。

1.3 Chunk

在较大规模集群中,检索某些资源类型的调集可能会导致十分大的呼应,从而影响服务器和客户端。 例如,一个集群可能有数万个 Pod,每个 Pod 大约相当于 2 KiB 的编码 JSON。 跨一切命名空间检索一切 Pod 可能会导致十分大的呼应 (10-20MB) 并消耗很多服务器资源。

你能够恳求 API 服务器经过运用页(Kubernetes 将其称为“块(Chunk)”)的方法来处理 list, 完成单个调集的呼应。 要以块的方式检索单个调集,针对调集的恳求支撑两个查询参数 limitcontinue, 而且从调集元 metadata 字段中的一切 list 操作回来呼应字段 continue。 客户端应该指定他们期望在每个带有 limit 的块中接收的条目数上限,假如调集中有更多资源, 服务器将在成果中回来 limit 资源并包括一个 continue 值。

作为 API 客户端,你能够鄙人一次恳求时将 continue 值传递给 API 服务器, 以指示服务器回来下一页()成果。继续下去直到服务器回来一个空的 continue 值, 你能够检索整个调集。

watch 操作类似,continue 令牌也会在很短的时刻(默以为 5 分钟)内过期, 并在无法回来更多成果时回来 410 Gone 代码。 这时,客户端需求从头开端履行上述检视操作或许疏忽 limit 参数。

类似于咱们平常业务开发中的分页查询

请注意,调集的 resourceVersion 在每个恳求中坚持不变, 这表明服务器正在向你显示 Pod 的共同快照。 在版别 10245 之后创立、更新或删去的 Pod 将不会显示, 除非你在没有继续令牌的情况下宣布单独的 list 恳求。 这使你能够将大恳求分红更小的块,然后对整个调集履行 watch 操作,而不会丢掉任何更新。

remainingItemCount 是调集中未包括在此呼应中的后续项目的数量。 假如 list 恳求包括标签或字段选择器, 则剩余项目的数量是不知道的,而且 API 服务器在其呼应中不包括 remainingItemCount 字段。 假如 list 是完好的(由于它没有分块,或许由于这是最后一个块),没有更多的剩余项目, API 服务器在其呼应中不包括 remainingItemCount 字段。 remainingItemCount 的用处是估量调集的巨细。

1.4 410 Gone 呼应

服务器不需求供给一切老的资源版别,在客户端恳求的是早于服务器端所保留版别的 resourceVersion 时,能够回来 HTTP 410 (Gone) 状况码。 客户端有必要能够容忍 410 (Gone) 呼应。 参看高效检测改变以了解怎么在监测资源时处理 410 (Gone) 呼应。

假如所恳求的 resourceVersion 超出了可应用的 limit, 那么取决于恳求是否是经过高速缓存来满意的,API 服务器可能会回来一个 410 Gone HTTP 呼应。

咱们在client-go中,进行list恳求都会进行判断资源是否可用,后续咱们深究源码的时候能够看到对应410判断errcode的逻辑。

2.写在最后

本文作为对学习client-go的一个预热,摘取了k8s官方关于kubernetesAPI几个点,有助于针对咱们后续研究client-go源码知道底层的恳求是怎么构建。我以为学习技能永远是: 文档 >= 博客 + 视频。期望我们能够多多查阅官方文档。期望每一次阅读,都能品出不一样的知识。

下一篇文章咱们将对client-goinformer架构的Reflector源码进行深化解析,探究一下,Reflector底层是怎么处理封装上述恳求。

3.参考

kubernetesAPI概念