kube-apiserver限流配置
k8s v1.19.0
watch这种长时间运行请求不受限流影响。
普通限流
客户端访问kube-apiserver,限流参数有max-mutating-requests-inflight(默认值是200,对应操作类请求)和max-requests-inflight(默认值是400,对应查询类请求),即同一时刻最多处理200个写请求和400个读请求。
staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go
WithMaxInFlightLimit函数
1. 初始化空channel。
2. 写入channel 1个值,处理请求,取出1个值。
3. 如果写入channel失败,请求来自system:master组才处理,否则报错请求太多。
分别创建容量为max-requests-inflight和max-mutating-requests-inflight的channel,在channel中有余量情况下才能处理请求,没有余量时直接丢弃,不是每秒限流值。
根据是否为操作类请求,选择channel。
开启APF
API优先级和公平性(APF)解决多个客户端之间请求相互影响的问题,避免某个客户端请求量大导致别的客户端因限流而处理慢。其中,优先级指高优先级请求比低优先级优先处理,公平性指同级别的请求公平处理。
从k8s 1.20开始,APIPriorityAndFairness门控默认开启。
开启APF,kube-apiserver增加启动参数。
- --runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true
- --feature-gates=APIPriorityAndFairness=true
APF限流
请求进入kube-apiserver后,根据FlowSchema拆分成流,FlowSchema绑定优先级。
默认FlowSchema和PriorityLevelConfiguration
k get flowschema
k get prioritylevelconfiguration
kube-apiserver总并发量=max- requests-inflight+max-mutating-requests-inflight,默认值是600,总并发量按照PriorityLevelConfiguration中NOMINALCONCURRENCYSHARES(求和计算相对比值*总并发量)分配到不同优先级(exempt没有NOMINALCONCURRENCYSHARES,不限流)。
global-default的flowschema spec
matchingPrecedence表示匹配优先级,值越小优先级越高。
flowSchema+distinguisherMethod确定flow。
global-default的prioritylevelconfiguration spec
nominalConcurrencyShares:并发量
handSize:请求分发队列数量
queueLengthLimit:队列长度限制
queues:当前队列总数
因为kubelet使用的证书(参考/etc/kubernetes/kubelet.conf)对应的用户组是system:nodes,所以kubeadm join走system-node-high限流。
因为kubeconfig对应的用户组是system:masters,所以kubectl命令走exempt(不限流),与不开启APF保持一致。
这里的clusterScope不是访问的资源必须集群粒度的含义。
for((i=1;i<=100;i++));
do
while true; do kubectl patch node kind-control-plane --type="json" -p="[{\"op\":\"replace\", \"path\":\"/metadata/annotations/a\",\"value\": \"${RANDOM}\"}]"; done &
done
启动100个子进程,不断调用kube-apiserver接口更新节点注解,在kube-apiserver打满情况下依然没有限流,说明kubectl命令不会被限流。
查看实时请求状态
kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
参考资料
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/feature-gates/