kube-apiserver限流机制原理

打印 上一主题 下一主题

主题 510|帖子 510|积分 1530

本文分享自华为云社区《kube-apiserver限流机制原理》,作者:可以交个朋友。
背景

apiserver是kubernetes中最告急的组件,一旦遇到恶意刷接口或请求量凌驾承载范围,apiserver服务可能会崩溃,导致整个kubernetes集群不可用。所以我们必要对apiserver做限流处理来提升kubernetes的健壮性。
k8s-apiserver限流能力发展过程

apiserver限流能力的发展分为两个阶段:
kubernetes 1.18版本之前kube-apiserver只是将请求分成了变更类型(create、update、delete、patch)和非变更类型(get、list、watch),并通过启动参数设置了两种类型的最大并发数。
  1. --max-requests-inflight          ## 限制同时运行的非变更类型请求的个数上限,0表示无限制。
  2. --max-mutating-requests-inflight   ## 限制同时运行的变更类型请求的个数上限。0 表示无限制。
复制代码
此时的apiserver限流能力较弱,若某个客户端错误的向kube-apiserver发起大量的请求时,必然会壅闭kube-apiserver,影响其他客户端的请求,因此高阶的限流APF就诞生了。
kubernetes1.18版本之后APF( APIPriorityAndFairness )成为kubernetes的默认限流方式。 APF以更细粒度的方式对请求进行分类和隔离,根据优先级和公平性进行处理。
  1. --enable-priority-and-fairness   ##  该值作为APF特性开关,默认为true
  2. --max-requests-inflight、--max-mutating-requests-inflight    ## 当开启APF时,俩值相加确定kube-apiserver的总并发上限
复制代码
两个阶段限流能力对比
限流能力1.18版本前1.18版本后(APF)颗粒度仅根据是否变更做分类可以根据请求对象、请求者身份、命名空间等做分类隔离性一个坏用户可能堵塞整个系统为请求分配固定队列,坏请求只能撑爆其使用的队列公平性会出现饿死用公平性算法从队列中取出请求优先级无有特权级别,可让告急请求不被限制APF关键资源介绍

APF通过FlowSchema 和 PriorityLevelConfiguration两个资源配置限流策略。
FlowSchema:办理老版本分类颗粒度粗的问题。根据rules字段匹配请求,匹配规则包含:请求对象、实行操作、请求者身份和命名空间
  1. apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
  2. kind: FlowSchema                 # 一个kubernetes集群中可以定义多个FlowSchema
  3. metadata:
  4.   name: myfl
  5. spec:
  6.   distinguisherMethod:           # 可选值为:ByNamespace或ByUser,用于把请求分组。属于同组的请求会分配到固定的queue中,如果省略该参数,则该FlowSchema匹配的所有请求都将视为同一个分组。
  7.     type: ByUser
  8.   matchingPrecedence: 90         # 数字越小代表FlowSchema的匹配顺序越在前,取值范围:1~10000。
  9.   priorityLevelConfiguration:    # FlowSchema关联的priorityLevelConfiguration
  10.     name: mypl
  11.   rules:
  12.   - nonResourceRules:            # 匹配非资源型:匹配接口URL
  13.     - nonResourceURLs:
  14.       - '*'
  15.     resourceRules:               # 匹配资源型:匹配apigroup、namespace、resources、verbs
  16.     - apiGroups:
  17.       - '*'
  18.       namespaces:
  19.       - '*'
  20.       resources:
  21.       - '*'
  22.       verbs:
  23.       - get
  24.       - create
  25.       - list
  26.       - update
  27.     subjects:                   # 匹配请求者主体:可选Group、User、ServiceAccount
  28.     - group:
  29.         name: '*'
  30.       kind: Group
  31.     - kind: User
  32.       user:
  33.         name: '*'
  34.     - kind: ServiceAccount
  35.       serviceAccount:
  36.         name: myserviceaccount
  37.         namespace: demo
复制代码
PriorityLevelConfiguration:办理老版本隔离性差的问题和优先级问题,并定义了限流细节(总队列数、队列长度、是否可排队)。当请求与某个FlowSchema匹配后,该请求会关联FlowSchema中指定的PriorityLevelConfiguration资源,每个PriorityLevelConfiguration相互隔离,且能遭受的并发请求数也不一样
  1. apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
  2. kind: PriorityLevelConfiguration          ## 每个PriorityLevelConfiguration有自己独立的限流配置, PriorityLevelConfiguration之间是完全隔离的。
  3. metadata:
  4.   name: mypl
  5. spec:
  6.   type: Limited                           # 设置是否为特权级别,如果为Exempt则不进行限流,如果为Limited则进行限流
  7.   limited:
  8.     assuredConcurrencyShares: 2           # 值越大,PriorityLevelConfiguration的并发上限越高。若当前并发执行数未达到并发上限,则PL处于空闲状态。
  9.     limitResponse:                        # 定义如何处理当前无法被处理的请求
  10.       type: Queue                         # 类型,Queue或者Reject,Reject直接返回429并拒绝,Queue将请求加入队列
  11.       queuing:
  12.         handSize: 1                       # 根据ByNamespace或ByUser对请求分组,每个分组对应queues的数量,
  13.         queueLengthLimit: 20              # 此PriorityLevelConfiguration中每个队列的长度
  14.         queues: 2                         # 此PriorityLevelConfiguration中的队列数
复制代码
一个FlowSchema只能关联一个priorityLevelConfiguration,多个FlowSchema可以关联同一个priorityLevelConfiguration
PriorityLevelConfiguration并发上限 = assuredConcurrencyShares / 所有assuredConcurrencyShares之和 * apiserver总并发数APF处理过程


请求与集群中的FlowSchema列表按照次序依次匹配,每个FlowSchema的matchingPrecedence字段决定其在列表中的次序,matchingPrecedence字段值越小,越靠前,越先进行匹配请求。
根据FlowSchema资源中的rules规则进行匹配,匹配方式可以是 “请求的资源类型”、“请求的动作类型”、“请求者的身份”、“请求的命名空间” 等多个维度。
若请求与某个FlowSchema乐成匹配,匹配就会竣事。FlowSchema关联着一个PriorityLevelConfiguration,每个PriorityLevelConfiguration中包含许多queue,根据FlowSchema.spec.Distinguisher字段将请求进行"分组",根据分组来分配queue,分配queue数量由PriorityLevelConfiguration资源的handSize字段决定,假如省略该参数,则该FlowSchema匹配的所有请求都将视为同一个"分组"。
每个PriorityLevelConfiguration资源都有独立的并发上限,assuredConcurrencyShares字段为apiserver总并发数的权重占比,值越大分配的并发上限就越高,当PriorityLevelConfiguration达到并发上限后,请求会根据所属的"分组"写入固定的queue中,请求被壅闭等待。请求与queue的固定关联可以让恶意用户只影响其使用的queue,而不会影响同PriorityLevelConfiguration中的其他queue。
当PriorityLevelConfiguration未达到并发上限时,fair queuing算法从所有queue中选择一个合适的queue取出请求,解除请求的壅闭,实行这个请求。fair queuing算法能包管同一个 PriorityLevelConfiguration 中的所有queue被处理机会平等。
APF实战

kubernetes原生自带了一些FlowSchema和PriorityLevelConfiguration规则,我们选择一个检察,如下图:

下面我们创建新的APF规则:当请求对象是apf命名空间中的deployment,则进行"apfpl"限流规则。
  1. apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
  2. kind: FlowSchema
  3. metadata:
  4.   name: apffl
  5. spec:
  6.   matchingPrecedence:  150
  7.   priorityLevelConfiguration:
  8.     name: apfpl                           ## 关联名为apfpl的PriorityLevelConfiguration
  9.   rules:
  10.     - resourceRules:
  11.       - apiGroups:
  12.           - apps
  13.         clusterScope: true
  14.         namespaces:
  15.           - apf                           ## 匹配apf命名空间
  16.         resources:
  17.           - deployments                   ## 匹配操作deployment的请求
  18.         verbs:
  19.           - '*'                           ## 匹配任意操作类型
  20.       subjects:
  21.         - kind: Group
  22.           group:
  23.             name: '*'                     ## 匹配任意组身份  
  24. ---
  25. apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
  26. kind: PriorityLevelConfiguration
  27. metadata:
  28.   name: apfpl
  29. spec:
  30.   limited:
  31.     assuredConcurrencyShares: 2            
  32.     limitResponse:                         ## 设置限流处理细节
  33.       queuing:
  34.         handSize: 1  
  35.         queueLengthLimit: 20                 
  36.         queues: 2  
  37.       type: Queue
  38.   type: Limited                             ## 对请求做限流处理
复制代码
接着在apf命名空间和default命名空间分别创建deployment进行测试。apf_fs为请求被分类到的 FlowSchema 的名称,apf_pl为该请求的优先级名称。检察apiserver日志信息,见下图:

循环操作deployment,我们可以使用命令检察是否触发限流等待
  1. kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
复制代码

返回waitingRequests非0,则代表触发最大并发数,有请求被限流进入等待队列。PriorityLevelConfiguration资源不为空闲表示已达到并发上限
 
点击关注,第一时间了解华为云新鲜技术~
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表