K8s是如何Watch的?

1. 概述

进入 K8s 的世界,会发现几乎所有对象都被抽象为了资源(Resource),包括 K8s Core Resources(Pod, Service, Namespace 等)、CRD、APIService 扩展的资源类型。同时 K8s 底层将这些资源统一抽象为了 RESTful 的存储(Storage),一方面服务端按目录形式(/registry/xxx) 存放在 ETCD 中,另一方面也为客户端提供了 RESTful API 接口,便于对资源的操作(get/post/put/patch/delete 等)。

K8s Watch API 就是为资源提供的一种持续监听其变化的机制,当资源有任何变化的时候,都可以实时、顺序、可靠的传递给客户端,使得用户可以针对目标资源进行灵活应用与操作。

那 K8s Watch 机制是怎么实现的呢?底层具体依赖了哪些技术?

本文将从 HTTP 协议、APIServer 启动、ETCD Watch 封装、服务端 Watch 实现、客户端 Watch 实现等方面,对 K8s Watch 实现机制进行了解析。

大致流程如下

本文及后续相关文章都基于 K8s v1.23

2. 从 HTTP 说起

2.1 Content-Length

如下图所示,HTTP 发送请求 Request 或服务端 Response,会在 HTTP header 中携带 Content-Length,以表明此次传输的总数据长度。如果 Content-Length 长度与实际传输长度不一致,则会发生异常(大于实际值会超时, 小于实际值会截断并可能导致后续的数据解析混乱)。

curl baidu.com -v

> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: baidu.com
> Accept: */*

< HTTP/1.1 200 OK
< Date: Thu, 17 Mar 2022 04:15:25 GMT
< Server: Apache
< Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
< ETag: "51-47cf7e6ee8400"
< Accept-Ranges: bytes
< Content-Length: 81
< Cache-Control: max-age=86400
< Expires: Fri, 18 Mar 2022 04:15:25 GMT
< Connection: Keep-Alive
< Content-Type: text/html

<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>

如果服务端提前不知道要传输数据的总长度,怎么办?

2.2 Chunked Transfer Encoding

HTTP 从 1.1 开始增加了分块传输编码(Chunked Transfer Encoding),将数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。数据块长度以十六进制的形式表示,后面紧跟着 \r\n,之后是分块数据本身,后面也是 \r\n,终止块则是一个长度为 0 的分块。

> GET /test HTTP/1.1
> Host: baidu.com
> Accept-Encoding: gzip

< HTTP/1.1 200 OK
< Server: Apache
< Date: Sun, 03 May 2015 17:25:23 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Content-Encoding: gzip

4\r\n        (bytes to send)
Wiki\r\n     (data)
6\r\n        (bytes to send)
pedia \r\n   (data)
E\r\n        (bytes to send)
in \r\n
\r\n
chunks.\r\n  (data)
0\r\n        (final byte - 0)
\r\n         (end message)

为了实现以流(Streaming)的方式 Watch 服务端资源变更,HTTP1.1 Server 端会在 Header 里告诉 Client 要变更 Transfer-Encoding 为 chunked,之后进行分块传输,直到 Server 端发送了大小为 0 的数据。

2.3 HTTP/2

HTTP/2 并没有使用 Chunked Transfer Encoding 进行流式传输,而是引入了以 Frame(帧) 为单位来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值