Kubernetes API 和流量控制:管理请求数量和排队进程

本文描述了我们最近遇到的一个真实案例:Kubernetes API 因其中一个集群中的大量请求而瘫痪。今天,我们将讨论我们如何处理这个问题,并提供一些关于如何预防它的提示。

高并发搞崩 Kubernetes API

一个非常普通的早晨,我们开始了对 Kubernetes API 的漫长研究,并确定了对它的请求的优先级。我们接到一位技术支持工程师的电话,他报告说客户的集群实际上无法运行(包括生产环境),并说必须采取一些措施。

我们连接到失败的集群,看到 Kube API 服务器已经耗尽了所有内存。它们会崩溃,重新启动,再次崩溃,然后一遍又一遍地重新启动。这最终导致 Kubernetes API 无法访问且完全无法运行。

由于这是一个生产集群,我们通过向控制平面节点添加处理器和内存来实施临时修复。我们一开始添加的资源不足。幸运的是,在下一批资源之后,API 稳定了下来。

寻找问题的根源

首先,我们评估了我们最终必须做出的改变的程度。最初,控制平面节点有 8 个 CPU 和 16 GB RAM。在我们的干预下,它们的大小增加到 16 个 CPU 和 64 GB RAM。

以下是问题发生时的内存消耗图:

内存消耗高达 50 GB。后来,我们发现,由于某些因素,Cilium pod 正在向 API 大量发送 LIST 请求。由于集群很大,并且有大量的节点(超过 200 个),同时请求会大大增加使用的内存量。

我们与客户达成一致,操作一个测试窗口,重新启动了 Cilium 代理,我们发现以下情况:

  • 其中一个 API 服务器上的负载正在增长。
  • 它消耗内存。
  • 它耗尽了节点上的所有内存。
  • 然后崩溃了。
  • 请求已重定向到另一台服务器。
  • 然后,同样的事情再次发生。

我们认为限制对 API 的并发 cilium-agent 请求的数量是个好主意。在这种情况下,稍微慢一点的 LIST 请求执行不会影响 Cilium 的性能。

解决方案

我们创建了以下内容和清单:FlowSchema PriorityLevelConfiguration

---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
kind: FlowSchema
metadata:name: cilium-pods
spec:distinguisherMethod:type: ByUsermatchingPrecedence: 1000priorityLevelConfiguration:name: cilium-podsrules:- resourceRules:- apiGroups:- 'cilium.io'clusterScope: truenamespaces:- '*'resources:- '*'verbs:- 'list'subjects:- group:name: system:serviceaccounts:d8-cni-ciliumkind: Group
---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
kind: PriorityLevelConfiguration
metadata:name: cilium-pods
spec:type: Limitedlimited:assuredConcurrencyShares: 5limitResponse:queuing:handSize: 4queueLengthLimit: 50queues: 16type: Queue

...并将它们部署到集群中。

重新启动 cilium-agent 不再导致显著的内存消耗变化。因此,我们能够将节点资源削减到原始资源。

我们做了什么,这些操作如何帮助消除多个 Kubernetes API 请求时的问题?阅读下面的细分。

在 Kubernetes API 中管理请求

在 Kubernetes 中,请求队列管理由 API 优先级和公平性 (APF) 处理。默认情况下,它在 Kubernetes 1.20 及更高版本中处于启用状态。API 服务器还提供了两个参数,(默认为 400)和(默认为 200),用于限制请求数量。如果启用了 APF,则将这两个参数相加,这就是 API 服务器的总并发限制的定义方式。--max-requests-inflight --max-mutating-requests-inflight

也就是说,还有一些更精细的细节需要考虑:

  • 长时间运行的 API 请求(例如,在 Pod 中查看日志或执行命令)不受 APF 限制的约束,WATCH 请求也不受限制。
  • 还有一个特殊的预定义优先级,称为 。来自此级别的请求将立即得到处理。exempt

APF 确保 Cilium 代理请求不会“限制”用户 API 请求。APF 还允许您设置限制,以确保无论 K8s API 服务器负载如何,重要请求始终得到处理

您可以使用以下两个资源配置 APF:

  • PriorityLevelConfiguration这定义了一个可用的优先级。
  • FlowSchema将每个传入请求映射到单个 .PriorityLevelConfiguration

优先级配置

每个都有自己的并发限制(份额)。总并发限制按其份额的比例分配给现有用户。PiorityLevelConfiguration PriorityLevelConfigurations

让我们按照以下示例计算该限制:

~# kubectl get prioritylevelconfigurations.flowcontrol.apiserver.k8s.io
NAME                 TYPE      ASSUREDCONCURRENCYSHARES   QUEUES   HANDSIZE   QUEUELENGTHLIMIT   AGE
catch-all            Limited   5                          <none>   <none>     <none>             193d
d8-serviceaccounts   Limited   5                          32       8          50                 53d
deckhouse-pod        Limited   10                         128      6          50                 90d
exempt               Exempt    <none>                     <none>   <none>     <none>             193d
global-default       Limited   20                         128      6          50                 193d
leader-election      Limited   10                         16       4          50                 193d
node-high            Limited   40                         64       6          50                 183d
system               Limited   30                         64       6          50                 193d
workload-high        Limited   40                         128      6          50                 193d
workload-low         Limited   100                        128      6          50                 193d
  1. 首先,将所有(260)相加。AssuredConcurrencyShares
  2. 现在,计算请求限制,例如,优先级:(400+200)/260*100 = 每秒 230 个请求。workload-low

让我们更改其中一个值,看看会发生什么。例如,让我们从 10 增加到 100。请求限制将降至 (400+200)/350*100 = 每秒 171 个请求。AssuredConcurrencyShares deckhouse-pod

通过增加 AssuredConcurrencyShares 数量,我们增加了特定级别的查询限制,但降低了所有其他级别的查询限制。

如果优先级中的请求数大于允许的限制,则请求将排队。您可以选择自定义队列参数。您还可以将 APF 配置为立即丢弃超出特定优先级限制的请求。

让我们看一下下面的例子:

---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
kind: PriorityLevelConfiguration
metadata:name: cilium-pods
spec:type: Limitedlimited:assuredConcurrencyShares: 5limitResponse:queuing:handSize: 4queueLengthLimit: 50queues: 16type: Queue

在这里,优先级配置为具有 .如果没有其他自定义优先级,则每秒会产生 12 个请求。请求队列设置为 200 个请求 (),并创建 16 个内部队列,以便更均匀地分配来自不同代理的请求。AssuredConcurrencyShares = 5 handSize * queueLengthLimit

关于 K8s 流量控制中优先级配置的一些重要细节:

  • 拥有更多队列可减少流之间的冲突次数,但会增加内存使用量。将其设置为禁用公平性逻辑,但仍允许对请求进行排队。1
  • 增加渲染,可以在不忽略单个请求的情况下处理高流量突发。但是,查询的处理速度较慢,并且需要更多的内存。queueLengthLimit
  • 通过更改 ,可以调整流之间发生冲突的可能性,以及在高负载情况下单个流可用的整体并发性。handSize

这些参数是通过实验选择的:

  • 一方面,我们需要确保此优先级的请求不会处理得太慢
  • 另一方面,我们需要确保 API 服务器不会因突然的流量峰值而过载

流架构

现在让我们继续讨论资源。它的作用是将请求映射到相应的 .FlowSchemaPriorityLevel

其主要参数有:

  • matchingPrecedence:定义应用顺序。数字越小,优先级越高。这样,您就可以从更具体的案例到更一般的案例编写重叠。FlowSchemaFlowSchemas
  • rules:定义请求过滤规则;格式与 Kubernetes RBAC 中的格式相同。
  • distinguisherMethod:指定一个参数(用户或命名空间),用于在将请求转发到优先级时将请求分成流。如果省略该参数,则所有请求都将分配给同一流。

例:

---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
kind: FlowSchema
metadata:name: cilium-pods
spec:distinguisherMethod:type: ByUsermatchingPrecedence: 1000priorityLevelConfiguration:name: cilium-podsrules:- resourceRules:- apiGroups:- 'cilium.io'clusterScope: truenamespaces:- '*'resources:- '*'verbs:- 'list'subjects:- group:name: system:serviceaccounts:d8-cni-ciliumkind: Group

在上面的示例中,我们选取了所有 LIST 请求,包括集群范围的请求以及从所有命名空间发送到所有资源的请求。主题包括来自服务帐户的所有请求。apiGroup: cilium.io d8-cni-cilium

我如何找出请求所在的位置和请求?FlowSchema PriorityLevelConfiguration

响应时,API 服务器会提供特殊标头 X-Kubernetes-PF-FlowSchema-UID 和 X-Kubernetes-PF-PriorityLevel-UID。您可以使用它们来查看请求的去向。

例如,让我们从 Cilium 代理的服务帐户向 API 发出请求:

TOKEN=$(kubectl -n d8-cni-cilium get secrets agent-token-45s7n -o json | jq -r .data.token | base64 -d)curl https://127.0.0.1:6445/apis/cilium.io/v2/ciliumclusterwidenetworkpolicies?limit=500  -X GET --header "Authorization: Bearer $TOKEN" -k -I
HTTP/2 200
audit-id: 4f647505-8581-4a99-8e4c-f3f4322f79fe
cache-control: no-cache, private
content-type: application/json
x-kubernetes-pf-flowschema-uid: 7f0afa35-07c3-4601-b92c-dfe7e74780f8
x-kubernetes-pf-prioritylevel-uid: df8f409a-ebe7-4d54-9f21-1f2a6bee2e81
content-length: 173
date: Sun, 26 Mar 2023 17:45:02 GMTkubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 7f0afa35-07c3-4601-b92c-dfe7e74780f8
7f0afa35-07c3-4601-b92c-dfe7e74780f8   d8-serviceaccountskubectl get prioritylevelconfiguration -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep df8f409a-ebe7-4d54-9f21-1f2a6bee2e81
df8f409a-ebe7-4d54-9f21-1f2a6bee2e81   d8-serviceaccounts

输出显示请求属于 d8-serviceaccounts 和 d8-serviceaccounts 。FlowSchema PriorityLevelConfiguration

需要关注的指标

Kubernetes API 提供了几个有用的指标来关注:

  • Apiserver_flowcontrol_rejected_requests_total:被拒绝的请求总数。
  • Apiserver_current_inqueue_requests:队列中当前的请求数量。
  • Apiserver_flowcontrol_request_execution_seconds:请求执行时间。

一些调试终结点也可能有助于获取有用的信息:

kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
PriorityLevelName,  ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests
system,             0,            true,   false,       0,               0
workload-high,      0,            true,   false,       0,               0
catch-all,          0,            true,   false,       0,               0
exempt,             <none>,       <none>, <none>,      <none>,          <none>
d8-serviceaccounts, 0,            true,   false,       0,               0
deckhouse-pod,      0,            true,   false,       0,               0
node-high,          0,            true,   false,       0,               0
global-default,     0,            true,   false,       0,               0
leader-election,    0,            true,   false,       0,               0
workload-low,       0,            true,   false,       0,               0kubectl get --raw /debug/api_priority_and_fairness/dump_queues
PriorityLevelName,  Index,  PendingRequests, ExecutingRequests, SeatsInUse, NextDispatchR,    InitialSeatsSum, MaxSeatsSum, TotalWorkSum
exempt,             <none>, <none>,          <none>,            <none>,     <none>,           <none>,          <none>,      <none>
d8-serviceaccounts, 0,      0,               0,                 0,          71194.55330547ss, 0,               0,           0.00000000ss
d8-serviceaccounts, 1,      0,               0,                 0,          71195.15951496ss, 0,               0,           0.00000000ss
...
global-default,     125,    0,               0,                 0,          0.00000000ss,     0,               0,           0.00000000ss
global-default,     126,    0,               0,                 0,          0.00000000ss,     0,               0,           0.00000000ss
global-default,     127,    0,               0,                 0,          0.00000000ss,     0,               0,           0.00000000ss

结论

我们最终通过设置请求队列管理解决了我们的问题。需要注意的是,这并不是我们在实践中遇到的唯一这种情况。在多次需要限制 API 请求之后,我们将 APF 配置作为 Kubernetes 平台的重要组成部分。利用它可以帮助我们和我们的客户减少大型、高负载 Kubernetes 集群中的 API 拥塞问题的数量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机二级考试C语言】C存储类

C 存储类 存储类定义 C 程序中变量/函数的存储位置、生命周期和作用域。 这些说明符放置在它们所修饰的类型之前。 下面列出 C 程序中可用的存储类&#xff1a; autoregisterstaticextern auto 存储类 auto 存储类是所有局部变量默认的存储类。 定义在函数中的变量默认为…

【linux】挂载U盘

cd /dev 进入/dev目录。在Linux系统中&#xff0c;/dev目录是设备文件的存储位置&#xff0c;包括硬件设备&#xff08;如磁盘、网卡等&#xff09;和虚拟设备&#xff08;如tty、null等&#xff09;。 fdisk -l 查看所有磁盘和分区的列表&#xff0c;最后一行就是usb设备的信息…

SSC | Blue Prism报告:2024年智能自动化(IA)7大趋势预测

近日&#xff0c;RPA行业领导者SS&C | Blue Prism发布《2024智能自动化&#xff08;IA&#xff09;趋势与预测》报告。报告中提到&#xff0c;智能自动化&#xff08;IA&#xff09;与流程管理的有效融合&#xff0c;是实现数字化转型成功的核心。采用业务流程管理&#xf…

免费开源OCR 软件Umi-OCR

Umi-OCR 是一款免费、开源、可批量的离线 OCR 软件&#xff0c;基于 PaddleOCR&#xff0c;适用于 Windows10/11 平台 免费&#xff1a;本项目所有代码开源&#xff0c;完全免费。方便&#xff1a;解压即用&#xff0c;离线运行&#xff0c;无需网络。高效&#xff1a;自带高效…

selenium-鼠标、等待

1、鼠标操作 常见鼠标操作包含在selenium.webdriver.common.action_chains的ActionChains 类中&#xff0c;常用的方法&#xff1a; context_click() 右击 double_click() 双击 click_and_hold() 左击悬停 move_to_element() 鼠标悬停 drag_and_drop() 拖动perform() 执行Acti…

【第十六节】变量与运算符-常见进制的理解与二进制转十进制的操作

计算机底层的存储都是二进制存储的 进制的分类 十进制 数字组成&#xff1a;0-9 进位规则&#xff1a;满十进一 二进制 数字组成&#xff1a;0-1 进位规则&#xff1a;满二进一 &#xff0c;以0b或0B开头 八进制 数字组成 &#xff1a;0-7 进位规则&#xff1a;满8进…

ElasticSearch使用篇

目录 一、 概述 二、创建索引 三、查询索引 四、删除索引 五、修改索引 六、批量操作 6.1 批量写入 6.2 批量创建文档create 6.3 普通创建或全量替换index 6.4 批量删除delete 6.5 批量修改update 6.6 组合应用 6.7 批量读取 一、 概述 es的操作是基于 Restful 风格…

数组的定义与越界问题

scanf标准读取函数 第一个冷知识&#xff0c;输入到scanf里面的内容都是字符串形式&#xff0c;但是&#xff01; scanf(“%d”,&a),%d决定了如何对输入的字符串进行操作 scanf用来读取标准输入&#xff0c;标准输入的内容需要放入到某个变量空间中去&#xff0c;因此变量…

Python数据分析案例34——IMDB电影评论情感分析(Transformer)

电影评论的情感分析 案例背景 很多同学对电影系列的数据都比较喜欢&#xff0c;那我就补充一下这个最经典的文本分类数据集&#xff0c;电影情感评论分析。用神经网络做。对国外的英文评论文本进行分类&#xff0c;看是正面还是负面情感。 数据集介绍 数据集&#xff1a;IMDb…

Python Tkinter Pack布局管理器

GUI 编程就相当于小孩子搭积木&#xff0c;每个积木块应该放在哪里&#xff0c;每个积木块显示为多大&#xff0c;也就是对大小和位置都需要进行管理&#xff0c;而布局管理器正是负责管理各组件的大小和位置的。此外&#xff0c;当用户调整了窗口的大小之后&#xff0c;布局管…

openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_RSA_keygen.c

文章目录 openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_RSA_keygen.c概述笔记END openssl3.2 - 官方demo学习 - pkey - EVP_PKEY_RSA_keygen.c 概述 官方指出 : RSA key 如果小于2048位, 就属于弱key 官方demo中, 给出的默认key长度为4096位 从名字生成上下文 初始化上下文…

sphinx,一个神奇的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个神奇的 Python 库 - sphinx。 Github地址&#xff1a;https://github.com/sphinx-doc/sphinx/ 在软件开发和项目管理中&#xff0c;文档是不可或缺的一部分。好的文档可以…

【计算机二级考试C语言】C运算符

C 运算符 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符&#xff0c;并提供了以下类型的运算符&#xff1a; 算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符 本章将逐一介绍算术运算符、关系运算符、逻辑运算符、位运算符、…

企业工商年报在哪找?如何批量获取?

企业年报是什么&#xff1f;有什么用&#xff1f; 企业年报是企业每年必须向工商行政管理机关和税务机关报送的年度报告&#xff0c;是指公司整个会计年度的财务报告及其他相关文件。主要包括企业基本信息、资产负债表、利润表、现金流量表、股东及股本变化情况等内容。 作用…

SpringBoot集成p6spy

P6Spy 是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。 通过 P6Spy 我们可以对 SQL 语句进行拦截,相当于一个 SQL 语句的记录器,这样我们可以用它来作相关的分析,比如性能分析。这里主要用于在控制台打印SQL时能自动将问号替换成实际参数打印一个可执行的SQL…

SQL 语言详解

SQL 详解 我们通常可以将 SQL 分为四类&#xff0c;分别是 DDL&#xff08;数据定义语言&#xff09;、DML&#xff08;数据操作语言&#xff09;、DQL&#xff08;数据查询语言&#xff09;和 DCL&#xff08;数据控制语言&#xff09;。DDL 主要用于创建、删除、修改数据库中…

309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 714.买卖股票的最佳时机含手续费 309.最佳买卖股票时机含冷冻期 力扣题目链接(opens new window) 给定一个整数数组&#xff0c;其中第 i 个元素代表了第 i 天的股票价格 。 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你…

云计算任务调度仿真04

这次分享一篇更加高级的云计算任务调度的文章和代码&#xff0c; 基于A3C学习和残差回归神经网络的随机边缘云计算环境动态调度 网络结构 结果 代码示例 这是基于pytorch实现的&#xff0c;所以复现起来没有什么难度&#xff0c;但是可以看到这有六层网络&#xff0c;而且…

KubeSphere 核心实战之一【在kubesphere平台上部署mysql】(实操篇 1/3)

文章目录 1、登录kubesphere平台2、kubesphere部署应用分析2.1、工作负载2.2、服务2.3、应用路由2.4、任务2.5、存储与配置2.6、部署应用三要素 3、部署mysql3.1、mysql容器启动实例3.2、mysql部署分析3.3、创建mysql的配置3.4、创建mysql的数据卷pvc3.5、创建mysql工作负载3.6…

java应用中swagger使用

文章目录 前言使用依赖引入配置注解使用controller中注解实体类注解 页面展示 前言 现在前后端分离式开发&#xff0c;最头疼的部分就是接口文档了。最讨厌两种人&#xff0c;一种是不写接口文档的人&#xff0c;另一种则是让我写接口文档的人。实际上&#xff0c;我们有一款特…