client-go 的 QPS 和 Burst 限速

1. 什么是 QPS 和 Burst ?

在 kubernetes client-go 中,QPS 和 Burst 是用于控制客户端与 Kubernetes API 交互速率的两个关键参数:

QPS (Queries Per Second)

定义:表示每秒允许发送的请求数量,即限速器的平滑速率。

用途:用来控制客户端与 API Server 的持续请求速率。

场景:适用于需要长时间维持均匀的 API 调用的情况。

Burst

定义:表示瞬时允许发送的最大请求数量,即限速器的突发容量。

用途:允许在短时间内发送的请求数量上限,适用于突发性调用场景。

场景:例如,客户端初始化时,需要快速获取大量资源。

2. 实验验证

可以通过编写代码,发送大量 API 请求来验证 QPS 和 Burst 的行为。以下是一个实验示例:

go 复制代码
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"sync"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 加载 kubeconfig
	kubeconfig := flag.String("kubeconfig", "~/.kube/config", "Path to kubeconfig file")
	flag.Parse()
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		log.Fatalf("Failed to load kubeconfig: %v", err)
	}

	// 设置 QPS 和 Burst
	config.QPS = 5.0  // 每秒 5 个请求,也是默认设置
	config.Burst = 10 // 突发允许 10 个请求,也是默认设置

	// 创建客户端
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatalf("Failed to create clientset: %v", err)
	}

	// 统计开始时间
	startTime := time.Now()

	// 使用 WaitGroup 追踪请求完成
	var wg sync.WaitGroup
	totalRequests := 50
	wg.Add(totalRequests)

	// 发送大量请求
	for i := 0; i < totalRequests; i++ {
		go func(i int) {
			defer wg.Done()
			_, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
			if err != nil {
				log.Printf("Request %d failed: %v", i, err)
			} else {
				log.Printf("Request %d succeeded", i)
			}
		}(i)
	}

	wg.Wait()
	fmt.Printf("Total time taken: %v\n", time.Since(startTime))
}

配置 QPS 和 Burst:

设置 QPS = 5,表示每秒最多发送 5 个请求。

设置 Burst = 10,允许在瞬时突发时最多发送 10 个请求。

当发生客户端限流时,会出现类似如下输出:

sh 复制代码
2025/01/10 15:01:50 Request 32 succeeded
I0110 15:01:50.468917    3083 request.go:729] Waited for 1.19372275s due to client-side throttling, not priority and fairness, request: GET:https://127.0.0.1:63092/api/v1/pods
2025/01/10 15:01:50 Request 33 succeeded

当发生客户端限流时,请求排队,实际完成时间会被延长。

实验结果:

当设置 QPS = 5,Burst = 10 时,请求全部成功,完成耗时 8s

当设置 QPS = 1,Burst = 2 时,请求全部成功,完成耗时 48s

调整建议

如果需要高频请求,可适当增大 QPS 和 Burst,避免客户端过度限流。

同时,合理设置参数,可以避免客户端过高的并发负载影响集群稳定性。

源码机制

client-go 使用令牌桶进行速率限制,桶容量为 burst 大小,按照每秒生成 QPS 个令牌的速率产生令牌(不会实际启动协程生成令牌,而是根据时钟计算),只有拿到令牌才能请求 kube-apiserver,如下图所示:

reference: client-go QPS、Burst和令牌桶

相关推荐
终端行者15 小时前
k8s之Ingress服务接入控制器
云原生·容器·kubernetes
学Linux的语莫20 小时前
k8s的nodeport和ingress
网络·rpc·kubernetes
aashuii1 天前
k8s通过NUMA亲和分配GPU和VF接口
云原生·容器·kubernetes
Most661 天前
kubesphere安装使用
kubernetes
Kentos(acoustic ver.)1 天前
云原生 —— K8s 容器编排系统
云原生·容器·kubernetes·云计算·k8s
哈里谢顿2 天前
Kubernetes 简介
kubernetes
__Smile°2 天前
k8s-MongoDB 副本集部署
云原生·容器·kubernetes
Jy_06222 天前
k8s 中的 deployment,statefulset,daemonset 控制器的区别
云原生·容器·kubernetes
果子⌂2 天前
Kubernetes 服务发布进阶
linux·运维·服务器·云原生·容器·kubernetes·云计算
Gold Steps.2 天前
K8s WebUI 选型:国外 Rancher vs 国内 KubeSphere vs 原生 Dashboard,从部署到使用心得谁更适合企业级场景?
云原生·容器·kubernetes