带你读《云原生应用开发:Operator原理与实践》——2.2.5 List-Watch 原理

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 带你读《云原生应用开发:Operator原理与实践》——2.2.5 List-Watch 原理

2.2.5 List-Watch 原理


List-Watch 机制是 Kubernetes 的系统消息通知机制,该机制确保了消息的实时性、顺序性和可靠性。List-Watch 由两部分组成:List 和 Watch。List 负责调用资源的 List RESTful API ,基于 HTTP 短链接实现;Watch 则调用资源的 Watch RESTful API,负责监听资源变更事件,基于 HTTP 长链接实现,也是本节重点分析的对象。

以 Deployment 资源为例,调用其 List 和 Watch 接口,结果见代码清单 2-33。

List 接口返回 Deployment 资源列表,比较简单。

代码清单 2-33

GET /apis/apps/v1/deployments
...
{
 "kind": "DeploymentList",
 "apiVersion": "apps/v1",
 "metadata": {...}
 "items": [
 {
 "metadata": {...},
 "spec": {...},
 "status": {...}
 },
 ...
 ]
}

Watch 接口返回事件(Event),这里采用 HTTP 长链接持续监听 Deployment 资源相关事件,每当有事件产生就返回一个 Event 。返回值的类型有 ADDED、MODIFIED 等,表示增加、修改等操作,Object 包含变更后最新的资源信息。

这里 Watch 接口的实现利用了 HTTP/1.1 协议的分块传输编码(Chunked Transfer Encoding),当客户端调用 Watch 接口时,Kubernetes APIServer 在 Response Header 中设置 Transfer-Encoding 的值为 chunked(见代码清单 2-34),表示采用分块传输编码,客户端收到该信息后,便和服务端保持该链接,并等待下一个数据块,即资源的事件信息。

代码清单 2-34

GET /apis/apps/v1/watch/deployments?watch=yes
---
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
...
{
 "type": "MODIFIED",
 "object": {
 "kind": "Deployment",
 "apiVersion": "apps/v1",
 "metadata": {...},
 "spec": {...},
 "status": {...}
 }
}

维 基 百 科

HTTP 分块传输编码允许服务器为动态生成的内容维持 HTTP 持久链接。通常,持久链接需要服务器在开始发送消息体前发送 Content-Length 消息头字段,但是对于动态生成的内容来说,在内容创建完之前是不可知的。使用分块传输编码将数据分解成一系列数据块,并以一个或多个块发送,这样服务器发送数据时不需要预先知道发送内容的总的大小。

List-Watch 功能对应到 Client-go 中,就由 Reflector 组件负责实现,其本质是将 Kubernetes 中的对象资源数据存储到本地并实时更新,拥有很高的可靠性、实时性和顺序性。Reflector 首先通过 List 获取 Kubernetes 中指定类型的资源对象,基于资源对象的 ResourceVersion 信息,使用 Watch 监听该类型资源事件,从而确保事件消息的实时性,并且资源对象 ResourceVersion 的递增特性确保了消息事件的顺序性。当 Watch 监听意外断开时,Reflector 会重新 List-Watch 资源,以确保可靠性,由于使用 Watch 长链接监听替换轮询 List 来获得最新资源状态,极大减轻了 Kubernetes APIServer 的访问压力,在确保消息事件实时性的同时也保证了性能。

下面分析 Reflector 的关键实现,首先通过 NewReflector 函数创建 Reflector 对象,通过 Run 方法启动监听并处理事件,而 Run 方法中最核心的就是 List-Watch 方法,其核心逻辑分为 List、定时同步、Watch 这 3 个部分。

(1) List:调用 List 方法获取资源数据,将其转化为资源对象列表,并最终同步到 DeltaFIFO 队列中。

(2)定时同步:利用定时器定时触发 Resync 机制,将 Indexer 中的资源对象同步到 DeltaFIFO 队列中。

(3) Watch:监听环境中资源的变化,并调用相应事件处理函数进行处理。

核心代码分析见代码清单 2-35。

代码清单 2-35

func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
 //...
 if err := func() error {
 //...
 
 go func() {
 //...
 // 如果 listerWatcher 支持,则尝试以块的形式收集列表
 // 如果 listerWatcher 不支持,则尝试第一个列表请求返回完整的响应
 pager := pager.New(pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.
Object, error) {
 return r.listerWatcher.List(opts)
 }))
 
 //...
 // 返回完整列表
 list, err = pager.List(context.Background(), options)
 }()
 
 //...
 // 获取资源版本号
 resourceVersion = listMetaInterface.GetResourceVersion()
 
 // 将资源数据转换为资源对象列表
 items, err := meta.ExtractList(list)
 
 // 将资源信息存储到 DeltaFIFO 中
 if err := r.syncWith(items, resourceVersion); err != nil {
 return fmt.Errorf("unable to sync list result: %v", err)
 }
 //...
 }(); err != nil {
 return err
 }
go func() {
 // 返回重新同步的定时通道,里面有计时器
 resyncCh, cleanup := r.resyncChan()
 //...
 for {
 //...
 if r.ShouldResync == nil || r.ShouldResync() {
 // Resync 机制会将 Indexer 本地存储的资源对象同步到 DeltaFIFO 中
 if err := r.store.Resync(); err != nil {
 //...
 }
 }
 // 重新启用定时器定时触发
 resyncCh, cleanup = r.resyncChan()
 }
 }()
 for {
 ...
 // 监听资源变化
 w, err := r.listerWatcher.Watch(options)
 // 处理监听到的各类事件,并调用预先注册的 Add、Delete、Update 函数进行处理
 if err := r.watchHandler(start, w, &resourceVersion, resyncerrc, stopCh);
 ...
 }
} 

其中, watchHandler 中设置了事件处理函数,从 ResultChan() 方法返回的 Channel 中获取事件,并根据事件类型(event.Type)将事件分发给对应的处理函数,这里处理函数的逻辑都是将事件同步到 DeltaFIFO 队列中,具体见代码清单 2-36。

代码清单 2-36

func (r *Reflector) watchHandler(start time.Time, w watch.Interface, resourceVersion 
*string, errc chan error, stopCh <-chan struct{}) error {
 //...
 for {
 select {
 //...
 case event, ok := <-w.ResultChan():
 //...
 switch event.Type {
 case watch.Added:
 err := r.store.Add(event.Object)
 case watch.Modified:
 err := r.store.Update(event.Object)
 case watch.Deleted:
 err := r.store.Delete(event.Object)
 }
 //...
 }
 }
 //...
}
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 监控 Cloud Native
云原生时代下的应用开发与部署实践
【10月更文挑战第4天】在云原生的浪潮中,开发者和运维人员面临着新的挑战和机遇。本文将通过实际案例,展示如何在云平台上高效地开发、部署和管理应用,同时确保系统的可扩展性和高可用性。我们将深入探讨容器化技术、微服务架构以及持续集成/持续部署(CI/CD)流程的实施策略,旨在为读者提供一套完整的云原生解决方案框架。
|
2月前
|
Kubernetes Cloud Native 持续交付
云原生技术在现代应用开发中的角色与实践
【9月更文挑战第9天】 随着云计算技术的飞速发展,云原生(Cloud Native)已经成为推动企业数字化转型的核心力量。本文将深入探讨云原生的基本概念、关键技术及其在实际开发中的应用案例,旨在为读者提供一条清晰的云原生技术学习路径和应用指南。通过实例分析,我们将揭示云原生如何优化资源管理、提升应用性能及加快部署速度,进而帮助企业构建更加灵活、可靠和高效的软件系统。
|
8天前
|
Kubernetes Cloud Native 持续交付
云原生技术在现代应用开发中的实践与思考
【10月更文挑战第35天】云原生技术,作为云计算的进阶形态,正引领着软件开发和运维的新潮流。本文将深入探讨云原生技术的核心理念、关键技术组件以及在实际项目中的应用案例,帮助读者理解如何利用云原生技术优化应用架构,提高开发效率和系统稳定性。我们将从容器化、微服务、持续集成/持续部署(CI/CD)等角度出发,结合实际代码示例,展现云原生技术的强大能力。
|
17天前
|
监控 Cloud Native 持续交付
云原生技术深度解析:重塑现代应用开发与部署范式####
本文深入探讨了云原生技术的核心概念、关键技术组件及其在现代软件开发中的重要性。通过剖析容器化、微服务架构、持续集成/持续部署(CI/CD)等关键技术,本文旨在揭示云原生技术如何促进应用的敏捷性、可扩展性和高可用性,进而推动企业数字化转型进程。不同于传统摘要仅概述内容要点,本部分将融入具体案例分析,直观展示云原生技术在实际应用中的显著成效与挑战应对策略,为读者提供更加丰富、立体的理解视角。 ####
|
29天前
|
Kubernetes Cloud Native 持续交付
云原生技术:重塑现代应用开发与部署模式####
本文深入探讨了云原生技术的核心概念、发展历程及其在现代软件开发和部署中的关键作用。通过分析云原生架构的特点,如容器化、微服务、持续集成与持续部署(CI/CD),以及它如何促进应用的可伸缩性、灵活性和效率,本文旨在为读者提供一个关于云原生技术全面而深入的理解。此外,还将探讨实施云原生策略时面临的挑战及应对策略,帮助组织更好地把握数字化转型的机遇。 ####
|
28天前
|
人工智能 Serverless API
云原生应用开发平台CAP:一站式应用开发及生命周期管理解决方案
阿里云的云应用开发平台CAP(Cloud Application Platform)是一款一站式应用开发及应用生命周期管理平台。它提供丰富的Serverless与AI应用模板、高效的开发者工具链及企业级应用管理功能,帮助开发者快速构建、部署和管理云上应用,大幅提升研发、部署和运维效能。
87 1
|
1月前
|
Kubernetes Cloud Native 持续交付
云原生技术在现代应用开发中的实践与展望
【10月更文挑战第7天】随着技术的不断演进,云计算已从简单的资源租用模式转变为支持复杂、高效、灵活的云原生应用架构。本文将深入探讨云原生技术的核心概念及其在现代应用开发中的应用,通过分析Kubernetes容器编排和微服务架构的实践案例,揭示云原生技术如何推动软件开发的现代化进程。文章旨在为开发者和架构师提供一套实用的云原生应用开发指南,同时展望未来云原生技术的发展方向。
29 8
|
1月前
|
Cloud Native 测试技术 云计算
云原生技术在现代应用开发中的角色与实践
【9月更文挑战第31天】本文深入探讨了云原生技术如何革新现代应用开发流程,通过实际案例分析,揭示了其对提高开发效率、确保系统可扩展性和可靠性的显著影响。文章不仅介绍了云原生的核心概念,还提供了实施策略和最佳实践,旨在为开发者提供一条清晰的云原生转型之路。
|
2月前
|
Kubernetes Cloud Native 持续交付
云原生技术在现代应用开发中的实践与思考
【9月更文挑战第23天】本文将深入探讨云原生技术如何革新现代应用的开发流程。通过分析云原生的核心概念、优势以及实际应用案例,我们旨在揭示这一新兴技术范式如何助力开发者和企业更高效、灵活地构建和部署应用程序。文章还将提供具体代码示例,展示云原生技术在实际项目中的应用,帮助读者更好地理解和掌握该技术。
|
2月前
|
Cloud Native 持续交付 开发者
云原生技术在现代应用开发中的应用与实践
【9月更文挑战第22天】本文将深入探讨云原生技术如何革新现代应用开发,通过实际案例分析其对提高开发效率、促进持续集成与交付的显著影响。我们将从云原生的基本概念出发,逐步展开到容器化、微服务架构、自动化管理的实践操作,以及这些技术如何协同工作以支持复杂应用的快速迭代和扩展。文章旨在为开发者提供一套云原生技术的实践框架,帮助他们构建更加灵活、可维护的应用系统。