【云原生系列】第二篇 为什么K8s API需要resourceVersion

本文探讨了Kubernetes(K8s) API中的resourceVersion的重要性,它用于实现增量监听和数据同步,确保在分布式环境中数据的一致性和效率。resourceVersion与Etcd的revision紧密相关,但在K8s中作为独立的版本标识。文章详细阐述了Get请求的三种情况,并解释了resourceVersion在K8s控制器组件如Deployment、ReplicaSet和Scheduler中的作用。

系列文章目录

第一篇 为什么Etcd的Watch不会丢数据?
第二篇 为什么K8s API需要resourceVersion?


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

K8s控制器模式的核心在于快速且高效地获取数据变化。
举个例子,Deployment控制器需要感知到新建的deployment资源,然后驱动replicaset控制器创建出Pod。

获取数据变化依赖于Etcd v3高性能watch特性,而在watch特性中,版本号revision是数据增量同步的核心。

为什么需要版本号,而不是每次都获取最新数据呢?

如果没有版本号,client或者server出现异常后,因为不能获取到异常过程中的数据,就会出现数据丢失。简言之,版本号是数据增量同步的核心。
当client因网络异常出现闪断之后,可以通过版本号从etcd快速获取异常后的数据,无需进行全量同步。

K8s中通过什么实现增量监听逻辑呢?

答案是Resource Version

为什么不直接用etcd的revision呢?
Resouce version又和etcd revision有啥关系呢?

resourceVersion的维护其实是利用了底层存储etcd的Revision机制,资源对象的每次修改,都会引起resourceVersion变化,且集群范围内唯一;
从k8s源码中可以看到resourceVersion就是Etcd中的modRevision

一、resource初体验

查看任意pod的yaml文件,在metadata部分,都可以看到resourceVersion字段

[root@k8s-node1 ~]# kubectl get po nginx-ds-8vn2h -o yaml
apiVersion: v1
kind: Pod
metadata:
<think>嗯,我现在要了解Kubernetes如何基于原生对象来扩展Kubernetes对象。首先,我需要回忆一下Kubernetes的基本概念。Kubernetes是一个容器编排系统,管理容器化应用,它有很多原生对象,比如Pod、Deployment、Service这些。用户可能需要自定义资源来满足特定需求,这时候就需要扩展。 那问题来了,怎么扩展呢?我记得有Custom Resource Definitions(CRD),应该是最常见的方法。用户可以通过CRD定义自己的资源类型,然后使用控制器来管理这些资源的状态。但用户的问题提到是基于原生对象进行扩展,可能CRD是其中一种方式。但还有其他方法吗?比如Aggregated API Servers,或者使用Annotations和Labels来扩展元数据? 接下来,我需要分步骤理清楚。首先,扩展Kubernetes对象的方式主要有两种:自定义资源(CRD)和聚合层API。CRD允许用户创建新的资源类型,而聚合层API允许将第三方API服务集成到Kubernetes API中,扩展API的功能。另外,用户还可以通过修改现有对象的Annotations或Labels来添加元数据,但这可能不算真正的扩展对象结构。 然后,CRD的具体步骤是怎样的?用户需要定义一个CRD的YAML文件,指定组、版本、作用域(Cluster或Namespaced),以及结构定义(通过OpenAPI v3 schema)。然后应用这个CRD到集群,之后就可以创建自定义资源的实例了。控制器需要监听这些资源的变化,并根据逻辑调整实际状态以匹配期望状态。 聚合API的话,需要部署一个独立的API服务器,并注册到KubernetesAPI聚合层。这样,当用户请求特定的API路径时,Kubernetes会将请求转发到聚合的API服务器处理。这种方法适合更复杂的扩展需求,但实现起来比CRD复杂。 另外,Operator模式是基于CRD和控制器的一种设计模式,用于自动化应用管理。比如Etcd Operator,可以自动处理备份、恢复、升级等操作。Operator的核心就是CRD和对应的控制器。 那么,用户的问题是如何基于原生对象扩展。可能CRD是在原生对象的基础上,添加新的资源类型,而原生对象如Deployment、Service等保持不变。或者,用户可能想扩展原生对象的功能,比如通过Admission Webhooks在创建或修改对象时进行验证或修改,或者使用Mutating Webhooks动态修改对象配置。 另外,KubernetesAPI扩展机制允许在不修改核心代码的情况下添加新功能。比如,Horizontal Pod Autoscaler(HPA)原本只支持CPU指标,但通过自定义指标API,用户可以扩展HPA支持其他指标。 总结起来,扩展Kubernetes对象的主要方法包括: 1. 自定义资源定义(CRD):添加新的资源类型。 2. 聚合API:集成第三方API服务。 3. 使用Annotations和Labels添加元数据。 4. Admission Webhooks:动态修改或验证对象。 5. Operator模式:自动化管理自定义资源。 需要详细说明每种方法的适用场景和实现步骤。比如CRD适合需要新增资源类型的情况,而聚合API适合需要更复杂逻辑或与其他系统集成的场景。Admission Webhooks适合在对象创建/更新时进行策略实施或默认值设置。 另外,控制器的作用是关键,无论是CRD还是聚合API,都需要有对应的控制器来监听资源变化并执行相应操作。控制器的实现通常使用client-go库,与Kubernetes API进行交互。 最后,应该给出一个例子,比如创建一个CRD的YAML文件,然后创建一个自定义资源的实例,并说明如何部署控制器来管理它。这样用户能更直观地理解整个过程。</think>Kubernetes 允许通过多种方式扩展其原生对象的能力,以下是基于原生对象进行扩展的核心方法及步骤: --- ### **1. 自定义资源定义(Custom Resource Definition, CRD)** **适用场景**:需要定义全新的资源类型,与原生对象(如 Pod、Deployment)形成互补。 **实现步骤**: 1. **定义 CRD** 创建一个 YAML 文件描述自定义资源的元数据,例如: ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myresources.example.com spec: group: example.com versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer scope: Namespaced names: plural: myresources singular: myresource kind: MyResource ``` - `group`:自定义 API 组名。 - `versions`:支持的 API 版本及结构定义(通过 OpenAPI v3 Schema)。 - `scope`:资源作用域(`Namespaced` 或 `Cluster`)。 2. **部署 CRD** 使用 `kubectl apply -f crd.yaml` 将 CRD 提交到集群。 3. **创建自定义资源实例** 编写自定义资源的 YAML 文件: ```yaml apiVersion: example.com/v1 kind: MyResource metadata: name: my-resource-instance spec: replicas: 3 ``` 4. **开发控制器** 使用 `client-go` 库编写控制器,监听自定义资源的变化并实现业务逻辑(例如根据 `spec.replicas` 创建对应数量的 Pod)。 --- ### **2. 聚合 API(Aggregation Layer)** **适用场景**:需要深度集成第三方服务或实现复杂逻辑的扩展。 **实现步骤**: 1. **部署独立 API 服务** 开发一个独立的 API 服务器(需实现 KubernetesAPI 接口规范)。 2. **注册聚合 API** 创建 `APIService` 对象,将请求路由到自定义 API 服务器: ```yaml apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: name: v1alpha1.example.com spec: service: name: my-api-service namespace: default group: example.com version: v1alpha1 insecureSkipTLSVerify: true groupPriorityMinimum: 1000 versionPriority: 100 ``` 3. **验证聚合 API** 通过 `kubectl get apiservices` 检查状态,确保新 API 已注册。 --- ### **3. 扩展原生对象行为** #### **(1) Admission Webhooks** **适用场景**:动态修改或验证原生对象的配置。 **实现方式**: - **Mutating Webhook**:在对象持久化前修改其内容(如自动注入 Sidecar 容器)。 - **Validating Webhook**:验证对象是否符合策略(如禁止使用高危镜像)。 **步骤**: 1. 开发 Webhook 服务(需 HTTPS 端点)。 2. 创建 `MutatingWebhookConfiguration` 或 `ValidatingWebhookConfiguration` 对象,指定触发条件和目标服务。 #### **(2) 控制器模式(Controller Pattern)** **适用场景**:增强原生对象的能力(如自动清理未使用的 ConfigMap)。 **实现方式**: - 编写控制器监听原生对象(如 Pod、Service)的事件,并触发自定义逻辑。 --- ### **4. 使用 Operator 模式** **适用场景**:自动化管理有状态应用(如数据库、中间件)。 **核心组件**: - **CRD**:定义应用的自定义资源(如 `RedisCluster`)。 - **控制器**:根据资源状态执行扩缩容、备份等操作。 **案例**(以 etcd Operator 为例): 1. 部署 etcd Operator。 2. 创建 `EtcdCluster` 资源,Operator 自动创建 etcd 集群并管理生命周期。 --- ### **对比与选型** | 方法 | 复杂度 | 灵活性 | 典型用例 | |--------------------|--------|--------|----------------------------| | CRD + 控制器 | 中 | 高 | 自定义业务资源(如 `CronJob` 扩展) | | 聚合 API | 高 | 极高 | 集成外部系统(如 Istio 控制面) | | Admission Webhooks | 中 | 中 | 安全策略、默认值注入 | | Operator | 高 | 高 | 有状态应用自动化管理 | --- ### **总结** - **轻量级扩展**:优先选择 CRD,快速定义新资源。 - **深度集成**:使用聚合 API 或 Operator。 - **行为增强**:通过 Admission Webhooks 或监听原生对象事件。 实际应用中,常组合多种方式(如 CRD + Webhook + 控制器)实现复杂需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值