赞
踩
本文分享自华为云社区《kube-apiserver限流机制原理》,作者:可以交个朋友。
apiserver是kubernetes中最重要的组件,一旦遇到恶意刷接口或请求量超过承载范围,apiserver服务可能会崩溃,导致整个kubernetes集群不可用。所以我们需要对apiserver做限流处理来提升kubernetes的健壮性。
apiserver限流能力的发展分为两个阶段:
- --max-requests-inflight ## 限制同时运行的非变更类型请求的个数上限,0表示无限制。
- --max-mutating-requests-inflight ## 限制同时运行的变更类型请求的个数上限。0 表示无限制。
此时的apiserver限流能力较弱,若某个客户端错误的向kube-apiserver发起大量的请求时,必然会阻塞kube-apiserver,影响其他客户端的请求,因此高阶的限流APF就诞生了。
- --enable-priority-and-fairness ## 该值作为APF特性开关,默认为true
- --max-requests-inflight、--max-mutating-requests-inflight ## 当开启APF时,俩值相加确定kube-apiserver的总并发上限
两个阶段限流能力对比
限流能力 | 1.18版本前 | 1.18版本后(APF) |
---|---|---|
颗粒度 | 仅根据是否变更做分类 | 可以根据请求对象、请求者身份、命名空间等做分类 |
隔离性 | 一个坏用户可能堵塞整个系统 | 为请求分配固定队列,坏请求只能撑爆其使用的队列 |
公平性 | 会出现饿死 | 用公平性算法从队列中取出请求 |
优先级 | 无 | 有特权级别,可让重要请求不被限制 |
APF通过FlowSchema 和 PriorityLevelConfiguration两个资源配置限流策略。
- apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
- kind: FlowSchema # 一个kubernetes集群中可以定义多个FlowSchema
- metadata:
- name: myfl
- spec:
- distinguisherMethod: # 可选值为:ByNamespace或ByUser,用于把请求分组。属于同组的请求会分配到固定的queue中,如果省略该参数,则该FlowSchema匹配的所有请求都将视为同一个分组。
- type: ByUser
- matchingPrecedence: 90 # 数字越小代表FlowSchema的匹配顺序越在前,取值范围:1~10000。
- priorityLevelConfiguration: # FlowSchema关联的priorityLevelConfiguration
- name: mypl
- rules:
- - nonResourceRules: # 匹配非资源型:匹配接口URL
- - nonResourceURLs:
- - '*'
- resourceRules: # 匹配资源型:匹配apigroup、namespace、resources、verbs
- - apiGroups:
- - '*'
- namespaces:
- - '*'
- resources:
- - '*'
- verbs:
- - get
- - create
- - list
- - update
- subjects: # 匹配请求者主体:可选Group、User、ServiceAccount
- - group:
- name: '*'
- kind: Group
- - kind: User
- user:
- name: '*'
- - kind: ServiceAccount
- serviceAccount:
- name: myserviceaccount
- namespace: demo
- apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
- kind: PriorityLevelConfiguration ## 每个PriorityLevelConfiguration有自己独立的限流配置, PriorityLevelConfiguration之间是完全隔离的。
- metadata:
- name: mypl
- spec:
- type: Limited # 设置是否为特权级别,如果为Exempt则不进行限流,如果为Limited则进行限流
- limited:
- assuredConcurrencyShares: 2 # 值越大,PriorityLevelConfiguration的并发上限越高。若当前并发执行数未达到并发上限,则PL处于空闲状态。
- limitResponse: # 定义如何处理当前无法被处理的请求
- type: Queue # 类型,Queue或者Reject,Reject直接返回429并拒绝,Queue将请求加入队列
- queuing:
- handSize: 1 # 根据ByNamespace或ByUser对请求分组,每个分组对应queues的数量,
- queueLengthLimit: 20 # 此PriorityLevelConfiguration中每个队列的长度
- queues: 2 # 此PriorityLevelConfiguration中的队列数
一个FlowSchema只能关联一个priorityLevelConfiguration,多个FlowSchema可以关联同一个priorityLevelConfiguration
PriorityLevelConfiguration并发上限 = assuredConcurrencyShares / 所有assuredConcurrencyShares之和 * apiserver总并发数
1.kubernetes原生自带了一些FlowSchema和PriorityLevelConfiguration规则,我们选择一个查看,如下图:
2.下面我们创建新的APF规则:当请求对象是apf命名空间中的deployment,则进行"apfpl"限流规则。
- apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
- kind: FlowSchema
- metadata:
- name: apffl
- spec:
- matchingPrecedence: 150
- priorityLevelConfiguration:
- name: apfpl ## 关联名为apfpl的PriorityLevelConfiguration
- rules:
- - resourceRules:
- - apiGroups:
- - apps
- clusterScope: true
- namespaces:
- - apf ## 匹配apf命名空间
- resources:
- - deployments ## 匹配操作deployment的请求
- verbs:
- - '*' ## 匹配任意操作类型
- subjects:
- - kind: Group
- group:
- name: '*' ## 匹配任意组身份
- ---
- apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
- kind: PriorityLevelConfiguration
- metadata:
- name: apfpl
- spec:
- limited:
- assuredConcurrencyShares: 2
- limitResponse: ## 设置限流处理细节
- queuing:
- handSize: 1
- queueLengthLimit: 20
- queues: 2
- type: Queue
- type: Limited ## 对请求做限流处理
3.接着在apf命名空间和default命名空间分别创建deployment进行测试。apf_fs为请求被分类到的 FlowSchema 的名称,apf_pl为该请求的优先级名称。查看apiserver日志信息,见下图:
4.循环操作deployment,我们可以使用命令查看是否触发限流等待
kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
返回waitingRequests非0,则代表触发最大并发数,有请求被限流进入等待队列。PriorityLevelConfiguration资源不为空闲表示已达到并发上限。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。