我尝试从客户的角度来回答您的问题:
这个功能试图解决什么问题?
其目的是减少对资源类型发出 Watch 请求的客户端对 kube-apiserver 的负载。书签的目的是让客户端知道服务器已将所有事件发送给客户端resourceVersion
在书签事件中指定。这是为了确保如果客户端的手表出现故障或通道关闭(超时后),客户端可以从以下位置恢复手表:resourceVersion
最后在书签事件中返回。它更像是一个检查点事件,没有真正的变异事件,如添加、修改、删除。
客户端可能已经缓存了作为常规“添加”、“修改”、“删除”事件的一部分接收到的资源版本,但请考虑以下情况:您正在查看的资源在过去 30 分钟内没有更新,并且resourceVersion
您已缓存的是“100”。
在没有书签事件的情况下,您将尝试从“100”恢复,但服务器可能返回“410 Gone”,表明它没有该版本或版本太旧。在这种情况下,客户端将必须执行一个列表来获取最新的资源版本并从那里启动监视,或者通过不指定资源版本从最新的位置启动监视,这对于服务器处理来说更昂贵。
在存在书签事件的情况下,服务器可能会尝试向您发送资源版本为“150”的书签事件,指示您已处理该版本,并且在重新启动时您可以从那里开始处理。
文档中的这个人为示例说明了这一点。您在 rv="10245" 处启动观察程序,处理一些直到 rv="10596" 的事件,然后服务器向您发送一个带有 rv="12746" 的书签,以便在重新启动时您可以从那里开始处理。
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245&allowWatchBookmarks=true
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
...
{
"type": "BOOKMARK",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "12746"} }
}
我应该什么时候使用它?
为了有效地处理您观看的资源上的更改事件,处理书签似乎比不处理更好。不过,无法保证书签的传送 - 服务器可能不支持它(如果它运行的是旧版本的 Kubernetes),或者可能根本不发送书签。
我可以不使用并且不错过活动吗?
是的,您完全可以这样做,但是如果您使用书签,丢失事件的可能性就会降低。另请记住,它不仅对客户端有利,而且对 kube-apiserver 也有利,因为如果它具有您在书签中收到的“新鲜”资源版本,它可以从本地缓存返回事件,如果没有,它将不得不执行从 etcd 中一致读取。我建议this https://www.youtube.com/watch?v=PLSDvFjR9HY观看视频以了解 Watch 事件的幕后运作方式。
我该如何使用它?
根据您所使用的客户端库,用法可能会有所不同,但在原始 HTTP 请求中,您可以指定此查询参数:允许观看书签=true
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245&allowWatchBookmarks=true
如果您正在使用客户去 https://github.com/kubernetes/client-go,有一个叫做 Reflector 的工具,并且this https://github.com/kubernetes/client-go/blob/master/tools/cache/reflector.go#L409是它请求书签的方式this https://github.com/kubernetes/client-go/blob/master/tools/cache/reflector.go#L518就是它如何处理它。
当我收到书签事件时我应该做什么?
从 Bookmark 事件中提取 resourceVersion 并将其缓存起来,以便在您因任何原因尝试重新启动观察程序时使用。