1. 当K8s集群开始"罢工":Too many requests异常现象解析
最近在排查一个生产环境问题时,发现日志里频繁出现这样的错误信息:"failed to list *v1.Endpoints: Too many requests: Too many requests, please try again later"。更糟糕的是,部分节点开始陆续出现NotReady状态,整个集群就像突然"罢工"了一样。这种情况在很多业务突增的场景下特别常见,特别是在使用client-go与Kubernetes API Server交互时。
这个异常的本质是API Server的自我保护机制被触发。想象一下API Server就像一家热门餐厅,当同时涌入的顾客(请求)超过餐厅接待能力(并发限制)时,经理就会在门口挂出"客满"的牌子(返回429 Too many requests)。在K8s中,这个限制主要来自三个关键环节:
- client-go客户端的令牌桶限流器(默认QPS=5,Burst=10)
- API Server的总并发限制(默认400读+200写)
- 节点心跳机制(Lease对象每10秒更新一次)
当这三个环节中的任何一个出现瓶颈,都可能引发连锁反应。比如节点心跳因为限流而无法及时上报,API Server就会认为节点不健康,将其标记为NotReady状态。这种情况在集群规模较大或业务突增时尤为明显。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 深入client-go:你的客户端真的在"守规矩"吗?
client-go作为Kubernetes的官方客户端库,内置了一套完善的限流机制。默认配置下,它使用令牌桶算法进行流量控制,参数如下:
go复制// 默认QPS为5,Burst为10
config := &rest.Config{
QPS: 5,
Burst: 10,
}
这个配置意味着:
- 正常情况下每秒最多发送5个请求(QPS)
- 允许短时间内突发最多10个请求(Burst)
令牌桶算法的工作方式可以类比为一个漏水的水桶:
- 桶初始时有10个令牌(Burst值)
- 每秒钟自动补充5个令牌(QPS值)
- 每次请求需要消耗1个令牌
- 当桶中没有足够令牌时,请求会被限流
在实际应用中,很多开发者会忽略这个配置
