• k8s异常Too many requests: Too many requests, please try again later.


    问题现象

    服务中使用了k8s client-go,日志里频繁出现如下异常信息,且部分节点出现NotReady状态。

    1. failed to list *vI. Endpoints: Too many requests: Too m
    2. any requests, please try again later.

    关于k8s Apiserver的限流

    通过总量限流,这种方案是比较简单粗暴的

    读请求并发量限制

    --max-requests-inflight int     Default: 400

    This and --max-mutating-requests-inflight are summed to determine the server's total concurrency limit (which must be positive) if --enable-priority-and-fairness is true. Otherwise, this flag limits the maximum number of non-mutating requests in flight, or a zero value disables the limit completely.

    写请求并发量限制

    --max-mutating-requests-inflight int     Default: 200

    This and --max-requests-inflight are summed to determine the server's total concurrency limit (which must be positive) if --enable-priority-and-fairness is true. Otherwise, this flag limits the maximum number of mutating requests in flight, or a zero value disables the limit completely.

    关于--enable-priority-and-fairness

    --enable-priority-and-fairness     Default: true

    If true and the APIPriorityAndFairness feature gate is enabled, replace the max-in-flight handler with an enhanced one that queues and dispatches with priority and fairness。

    因此默认配置下,ApiServer的总并发量限制=400+200

    关于k8s集群节点心跳

    节点心跳的上报也是经过ApiServer,因此触发限流后,会导致心跳上报失败。

    Kubernetes 节点发送的心跳帮助你的集群确定每个节点的可用性,并在检测到故障时采取行动。

    节点的心跳由kubelet发送。

    心跳类型心跳方式
    更新节点的.status默认间隔5min
    更新kube-node-lease空间里的Lease对象默认间隔10s

    kubelet 负责创建和更新节点的 .status,以及更新它们对应的 Lease。

    当节点状态发生变化时,或者在配置的时间间隔内没有更新事件时,kubelet 会更新 .status。 .status 更新的默认间隔为 5 分钟(比节点不可达事件的 40 秒默认超时时间长很多)。

    kubelet 会创建并每 10 秒(默认更新间隔时间)更新 Lease 对象。 Lease 的更新独立于节点的 .status 更新而发生。 如果 Lease 的更新操作失败,kubelet 会采用指数回退机制,从 200 毫秒开始重试, 最长重试间隔为 7 秒钟。

    关于client-go的并发限制

    client-go访问ApiServer时,也进行了client端的限流,采用令牌桶限流算法

    By default in client-go the Burst is 10 and QPS is 5。

    保持QPS=5,应对突发流量QPS=burst。初始令牌桶里有burst个token。

    1. // QPS indicates the maximum QPS to the master from this client.
    2. // If it's zero, the created RESTClient will use DefaultQPS: 5
    3. QPS float32
    4. // Maximum burst for throttle.
    5. // If it's zero, the created RESTClient will use DefaultBurst: 10.
    6. Burst int
    1. func flowcontrol.NewTokenBucketRateLimiter(qps float32, burst int) flowcontrol.RateLimiter
    2. NewTokenBucketRateLimiter creates a rate limiter which implements a token bucket approach.
    3. The rate limiter allows bursts of up to 'burst' to exceed the QPS,
    4. while still maintaining a smoothed qps rate of 'qps'.
    5. The bucket is initially filled with 'burst' tokens,
    6. and refills at a rate of 'qps'.
    7. The maximum number of tokens in the bucket is capped at 'burst'.

  • 相关阅读:
    Java如何将字符串String转换为整型Int
    【Linux】使用ntpdate同步
    Java生产者消费者模式
    物联网技术融合成为新趋势,LPWAN2.0泛在物联·ZETA生态大会在深圳召开
    Springboot2 注解
    一文搞懂│php 中的 DI 依赖注入
    Bridge Champ助力我国桥牌阔步亚运, Web3游戏为传统项目注入创新活力
    复盘:智能座舱系列文一,他到底是什么
    1212. 查询球队积分
    SpringBoot: Controller层的优雅实现
  • 原文地址:https://blog.csdn.net/hugo_lei/article/details/134050684