- 文档首页
容器服务
容器服务 VKE
最佳实践
集群
Kubernetes 开发者最佳实践
Kubernetes 开发者最佳实践
本文主要描述使用容器服务过程中关于访问控制面组件、优化客户端访问模式相关建议和最佳实践。
使用 list-watch 模式替代全量 list
背景信息
作为 Kubernetes 开发者,您的组件可能:
- 需要定期查询一些 Kubernetes 对象的列表。
- 需要在多个节点上运行(尤其 DaemonSet 方式部署的组件)。
通常情况下通过定期调用 list API 来查询对象状态,但该方法每次必须加载所有对象到 kube-apiserver 内存中进行序列化并传输。这类请求会占用控制面大量 CPU 和内存,使控制面(Control Plane)过载或请求超时,即使定期查询的 Kubernetes 对象状态未发生变化,也会在 kube-apiserver 上造成高负载。
推荐方案
强烈建议避免全量 list,替换为 list-watch 模式,即先通过调用 list API 加载所有对象后,后续使用 watch API 获取对象状态的增量变更。list-watch 模式与全量 list 相比,可有效缩短 kube-apiserver 处理请求的时间、减少请求流量,如果对象状态未发生更改,则不会产生额外的负载。 补充说明
无论是全量 list 还是 list-watch 模式,建议在 list 请求中设置 ResourceVersion 参数(ResourceVersion=0),从 kube-apiserver cache 中读取数据,减少 kube-apiserver 与 etcd 数据库的交互次数。
说明
- VKE 的 kube-apiserver 内置了限流规则,避免大量 list 请求导致 kube-apiserver 内存溢出(OOM),但 client-go 在收到限流响应后会自动重试,因此一般情况下不会导致您的 list 请求失败。
减少 watch 和 list 产生的不必要流量
Kubernetes 在内部使用 watch API 发送关于对象更新的通知。即便 watch 调用需要的资源比定期 list 调用要少得多,但在大规模集群中的 watch 调用也会占用大量集群资源,影响集群性能。最大的影响来自于创建从多个位置观察频繁更改对象的 watch 调用,例如对运行在多个节点上的组件对应的 Pod 数据进行 watch 调用。集群上安装的第三方代码或扩展程序,可能会在后台创建此类 watch 调用。 我们推荐以下最佳实践:
- 减少 watch 和 list API 调用产生的不必要处理操作和流量。
- 避免创建从多个节点观察频繁更改的对象的 watch(例如 DaemonSet)。
- 建议在单个节点上创建一个中央控制器,实现对象数据的监听及处理。
- 仅对必要的对象进行 watch 操作,避免对集群全量对象进行 watch 操作,例如每个节点上的 kubelet 只 watch 调度到同一节点上的 Pod。
- 如果您直接使用 client-go 库,可以在构造 Informer 时设置 watch 过滤器。代码片段如下:
- 避免部署需要执行大量 watch 或 list 调用的第三方组件或扩展程序,从而影响集群性能。
停用 API 访问凭证的自动挂载
在 Kubernetes 1.22 之前版本,如果您在创建 Pod 时未指定 ServiceAccount(服务账号),Kubernetes 会自动执行以下操作:
- 将默认的 ServiceAccount 分配给 Pod。
- 挂载 ServiceAccount 的 API 访问凭证作为 Pod 的 Secret。
- 对于每个已挂载的 Secret,kubelet 会创建一个 watch,以观察每个节点上该 Secret 的更改。
在大规模集群中,上述操作意味着数千个不必要的 watch 调用,可能会在 kube-apiserver 上产生大量负载。
API 序列化协议建议使用 Protobuf
无论您使用 controller-runtime 库还是直接使用 client-go 库,都可以在 KubeConfig 中设置编码格式,代码样例如下:
最近更新时间:2026.10.23 10:37:21