From 10fccce49aaaa7ea0df72bc8dc2cc75f484fa4fa Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Sun, 10 Jan 2021 16:47:49 +0800 Subject: [PATCH] [zh] Resync concepts/cluster-administration/flow-control.md --- .../cluster-administration/flow-control.md | 351 ++++++++++-------- 1 file changed, 206 insertions(+), 145 deletions(-) diff --git a/content/zh/docs/concepts/cluster-administration/flow-control.md b/content/zh/docs/concepts/cluster-administration/flow-control.md index 8ed87422ed..37f57d0fb1 100644 --- a/content/zh/docs/concepts/cluster-administration/flow-control.md +++ b/content/zh/docs/concepts/cluster-administration/flow-control.md @@ -6,7 +6,7 @@ min-kubernetes-server-version: v1.18 -{{< feature-state state="alpha" for_k8s_version="v1.18" >}} +{{< feature-state state="beta" for_k8s_version="v1.20" >}} - -## 启用 API 优先级和公平性 {#Enabling-API-Priority-and-Fairness} + +## 启用/禁用 API 优先级和公平性 {#enabling-api-priority-and-fairness} -APF 特性由特性门控控制,默认情况下不启用。有关如何启用和禁用特性门控的描述, +API 优先级与公平性(APF)特性由特性门控控制,默认情况下启用。 +有关特性门控的一般性描述以及如何启用和禁用特性门控, 请参见[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。 -APF 的特性门控叫做 `APIPriorityAndFairness` 。 -此特性要求必须启用某个 {{< glossary_tooltip term_id="api-group" text="API Group" >}}。 -你可以在启动 `kube-apiserver` 时,添加以下命令行标志来完成这些操作: +APF 的特性门控称为 `APIPriorityAndFairness`。 +此特性也与某个 {{< glossary_tooltip term_id="api-group" text="API 组" >}} +相关: +(a) 一个 `v1alpha1` 版本,默认被禁用; +(b) 一个 `v1beta1` 版本,默认被启用。 +你可以在启动 `kube-apiserver` 时,添加以下命令行标志来禁用此功能门控 +及 v1beta1 API 组: ```shell kube-apiserver \ ---feature-gates=APIPriorityAndFairness=true \ ---runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true \ -# …其他配置与之前相同 +--feature-gates=APIPriorityAndFairness=false \ +--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=false \ + # ...其他配置不变 ``` + +或者,你也可以通过 +`--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=true` +启用 API 组的 v1alpha1 版本。 + 将请求划分到流中之后,APF 功能将请求分配到队列中。 -分配时使用一种称为 {{< glossary_tooltip term_id="shuffle-sharding" text="混洗分片(Shuffle-Sharding)" >}} 的技术。 +分配时使用一种称为 {{< glossary_tooltip term_id="shuffle-sharding" text="混洗分片(Shuffle-Sharding)" >}} +的技术。 该技术可以相对有效地利用队列隔离低强度流与高强度流。 -## 默认值 {#Defaults} +## 默认值 {#defaults} APF 特性附带推荐配置,该配置对实验场景应该足够; 如果你的集群有可能承受较大的负载,那么你应该考虑哪种配置最有效。 @@ -213,7 +234,7 @@ APF 特性附带推荐配置,该配置对实验场景应该足够; workloads to be able to schedule on them. --> * `system` 优先级用于 `system:nodes` 组(即 Kubelets )的请求; -kubelets 必须能连上 API 服务器,以便工作负载能够调度到其上。 + kubelets 必须能连上 API 服务器,以便工作负载能够调度到其上。 * `leader-election` 优先级用于内置控制器的领导选举的请求 -(特别是来自 `kube-system` 名称空间中 `system:kube-controller-manager` 和 -`system:kube-scheduler` 用户和服务账号,针对 `endpoints`、`configmaps` 或 `leases` 的请求)。 -将这些请求与其他流量相隔离非常重要,因为领导者选举失败会导致控制器发生故障并重新启动, -这反过来会导致新启动的控制器在同步信息时,流量开销更大。 + (特别是来自 `kube-system` 名称空间中 `system:kube-controller-manager` 和 + `system:kube-scheduler` 用户和服务账号,针对 `endpoints`、`configmaps` 或 `leases` 的请求)。 + 将这些请求与其他流量相隔离非常重要,因为领导者选举失败会导致控制器发生故障并重新启动, + 这反过来会导致新启动的控制器在同步信息时,流量开销更大。 -* `workload-high` 优先级用于内置控制器的请求。 - - -* `workload-low` 优先级适用于来自任何服务帐户的请求,通常包括来自 Pods 中运行的控制器的所有请求。 - - +* `workload-high` 优先级用于内置控制器的请求。 +* `workload-low` 优先级适用于来自任何服务帐户的请求,通常包括来自 Pods + 中运行的控制器的所有请求。 * `global-default` 优先级可处理所有其他流量,例如:非特权用户运行的交互式 `kubectl` 命令。 -内置了两个 PriorityLevelConfiguration 和两个 FlowSchema,它们是内置的、不可重载的: +系统内置了两个 PriorityLevelConfiguration 和两个 FlowSchema,它们是不可重载的: * 特殊的 `exempt` 优先级的请求完全不受流控限制:它们总是立刻被分发。 特殊的 `exempt` FlowSchema 把 `system:masters` 组的所有请求都归入该优先级组。 -如果合适,你可以定义新的 FlowSchema,将其他请求定向到该优先级。 + 如果合适,你可以定义新的 FlowSchema,将其他请求定向到该优先级。 * 特殊的 `catch-all` 优先级与特殊的 `catch-all` FlowSchema 结合使用,以确保每个请求都分类。 -一般地,你不应该依赖于 `catch-all` 的配置,而应适当地创建自己的 `catch-all` FlowSchema 和 PriorityLevelConfigurations -(或使用默认安装的 `global-default` 配置)。 -为了帮助捕获部分请求未分类的配置错误,强制要求 `catch-all` 优先级仅允许一个并发份额, -并且不对请求进行排队,使得仅与 `catch-all` FlowSchema 匹配的流量被拒绝的可能性更高,并显示 HTTP 429 错误。 + 一般地,你不应该依赖于 `catch-all` 的配置,而应适当地创建自己的 `catch-all` + FlowSchema 和 PriorityLevelConfigurations(或使用默认安装的 `global-default` 配置)。 + 为了帮助捕获部分请求未分类的配置错误,强制要求 `catch-all` 优先级仅允许一个并发份额, + 并且不对请求进行排队,使得仅与 `catch-all` FlowSchema 匹配的流量被拒绝的可能性更高, + 并显示 HTTP 429 错误。 ## 健康检查并发豁免 {#Health-check-concurrency-exemption} @@ -306,8 +323,6 @@ requests from rate limiting. --> 如果添加以下 FlowSchema,健康检查请求不受速率限制。 -{{< caution >}} - +{{< caution >}} 进行此更改后,任何敌对方都可以发送与此 FlowSchema 匹配的任意数量的健康检查请求。 如果你有 Web 流量过滤器或类似的外部安全机制保护集群的 API 服务器免受常规网络流量的侵扰, 则可以配置规则,阻止所有来自集群外部的健康检查请求。 - {{< /caution >}} {{< codenew file="priority-and-fairness/health-for-strangers.yaml" >}} @@ -327,12 +342,14 @@ that originate from outside your cluster. ## 资源 {#Resources} @@ -341,6 +358,7 @@ PriorityLevelConfiguration. 定义隔离类型和可处理的并发预算量,还可以微调排队行为。 [FlowSchemas](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#flowschema-v1alpha1-flowcontrol-apiserver-k8s-io) 用于对每个入站请求进行分类,并与一个 PriorityLevelConfigurations 相匹配。 +此外同一 API 组还有一个 `v1alpha1` 版本,其中包含语法和语义都相同的资源类别。 ### PriorityLevelConfiguration {#PriorityLevelConfiguration} -一个 PriorityLevelConfiguration 表示单个隔离类型。每个 PriorityLevelConfigurations 对未完成的请求数有各自的限制,对排队中的请求数也有限制。 +一个 PriorityLevelConfiguration 表示单个隔离类型。每个 PriorityLevelConfigurations +对未完成的请求数有各自的限制,对排队中的请求数也有限制。 * `queues` 递增能减少不同流之间的冲突概率,但代价是增加了内存使用量。 -值为1时,会禁用公平排队逻辑,但仍允许请求排队。 + 值为 1 时,会禁用公平排队逻辑,但仍允许请求排队。 * `queueLengthLimit` 递增可以在不丢弃任何请求的情况下支撑更大的突发流量, -但代价是增加了等待时间和内存使用量。 + 但代价是增加了等待时间和内存使用量。 * 修改 `handSize` 允许你调整过载情况下不同流之间的冲突概率以及单个流可用的整体并发性。 - {{< note >}} - 较大的 `handSize` 使两个单独的流程发生碰撞的可能性较小(因此,一个流可以饿死另一个流), - 但是更有可能的是少数流可以控制 apiserver。 - 较大的 `handSize` 还可能增加单个高并发流的延迟量。 - 单个流中可能排队的请求的最大数量为 `handSize *queueLengthLimit` 。 - {{< /note >}} + + {{< note >}} + 较大的 `handSize` 使两个单独的流程发生碰撞的可能性较小(因此,一个流可以饿死另一个流), + 但是更有可能的是少数流可以控制 apiserver。 + 较大的 `handSize` 还可能增加单个高并发流的延迟量。 + 单个流中可能排队的请求的最大数量为 `handSize *queueLengthLimit` 。 + {{< /note >}} -随机分片 | 队列数 | 1个大象 | 4个大象 | 16个大象 +随机分片 | 队列数 | 1 个大象 | 4 个大象 | 16 个大象 |----------|-----------|------------|----------------|--------------------| | 12 | 32 | 4.428838398950118e-09 | 0.11431348830099144 | 0.9935089607656024 | | 10 | 32 | 1.550093439632541e-08 | 0.0626479840223545 | 0.9753101519027554 | @@ -484,7 +505,6 @@ FlowSchema 匹配一些入站请求,并将它们分配给优先级。 首先从 `matchingPrecedence` 数值最低的匹配开始(我们认为这是逻辑上匹配度最高), 然后依次进行,直到首个匹配出现。 -{{< caution >}} +{{< caution >}} 对一个请求来说,只有首个匹配的 FlowSchema 才有意义。 如果一个入站请求与多个 FlowSchema 匹配,则将基于 `matchingPrecedence` 值最高的请求进行筛选。 如果一个请求匹配多个 FlowSchema 且 `matchingPrecedence` 的值相同,则按 `name` 的字典序选择最小, @@ -540,6 +561,7 @@ FlowSchema 的 `distinguisherMethod.type` 字段决定了如何把与该模式 -## 诊断程序 {#Diagnostics} + +## 问题诊断 {#diagnostics} 启用了 APF 的 API 服务器,它每个 HTTP 响应都有两个额外的 HTTP 头: `X-Kubernetes-PF-FlowSchema-UID` 和 `X-Kubernetes-PF-PriorityLevel-UID`, @@ -559,18 +582,35 @@ have permission to view them, so when debugging you can use a command like kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" kubectl get prioritylevelconfigurations -o custom-columns="uid:{metadata.uid},name:{metadata.name}" ``` + 来获取 UID 到 FlowSchema 的名称和 UID 到 PriorityLevelConfigurations 的名称的映射。 - + ## 可观察性 {#Observability} - ### 指标 {#Metrics} + +{{< note >}} +在 Kubernetes v1.20 之前的版本中,标签 `flow_schema` 和 `priority_level` +的命名有时被写作 `flowSchema` 和 `priorityLevel`,即存在不一致的情况。 +如果你在运行 Kubernetes v1.19 或者更早版本,你需要参考你所使用的集群 +版本对应的文档。 +{{< /note >}} + * `apiserver_flowcontrol_rejected_requests_total` 是一个计数器向量, -记录被拒绝的请求数量(自服务器启动以来累计值), -由标签 `flowSchema` (表示与请求匹配的 FlowSchema ), `priorityLevel` (表示分配给请该求的优先级)和 `reason` 拆分。 -`reason` 标签将具有以下值之一: - * `queue-full` ,表明已经有太多请求排队, - * `concurrency-limit` ,表示将 PriorityLevelConfiguration 配置为 `Reject` 而不是 `Queue` ,或者 - * `time-out`, 表示在其排队时间超期的请求仍在队列中。 + 记录被拒绝的请求数量(自服务器启动以来累计值), + 由标签 `flow_chema` (表示与请求匹配的 FlowSchema ),`priority_evel` + (表示分配给请该求的优先级)和 `reason` 来区分。 + `reason` 标签将具有以下值之一: + + * `queue-full` ,表明已经有太多请求排队, + * `concurrency-limit` ,表示将 PriorityLevelConfiguration 配置为 `Reject` 而不是 `Queue` ,或者 + * `time-out`, 表示在其排队时间超期的请求仍在队列中。 * `apiserver_flowcontrol_dispatched_requests_total` 是一个计数器向量, -记录开始执行的请求数量(自服务器启动以来的累积值), -由标签 `flowSchema` (表示与请求匹配的 FlowSchema )和 `priorityLevel`(表示分配给该请求的优先级)拆分。 + 记录开始执行的请求数量(自服务器启动以来的累积值), + 由标签 `flow_schema` (表示与请求匹配的 FlowSchema )和 + `priority_level`(表示分配给该请求的优先级)来区分。 * `apiserver_current_inqueue_requests` 是一个表向量, -记录最近排队请求数量的高水位线, -由标签 `request_kind` 分组,标签的值为 `mutating` 或 `readOnly`。 -这些高水位线表示在最近一秒钟内看到的最大数字。 -它们补充说明了老的表向量 `apiserver_current_inflight_requests` -(该量保存了最后一个窗口中,正在处理的请求数量的高水位线)。 + 记录最近排队请求数量的高水位线, + 由标签 `request_kind` 分组,标签的值为 `mutating` 或 `readOnly`。 + 这些高水位线表示在最近一秒钟内看到的最大数字。 + 它们补充说明了老的表向量 `apiserver_current_inflight_requests` + (该量保存了最后一个窗口中,正在处理的请求数量的高水位线)。 * `apiserver_flowcontrol_read_vs_write_request_count_samples` 是一个直方图向量, -记录当前请求数量的观察值, -由标签 `phase` (取值为 `waiting` 和 `executing` )和 `request_kind` (取值 `mutating` 和 `readOnly` )拆分。 -定期以高速率观察该值。 + 记录当前请求数量的观察值, + 由标签 `phase` (取值为 `waiting` 和 `executing` )和 `request_kind` + (取值 `mutating` 和 `readOnly` )拆分。定期以高速率观察该值。 * `apiserver_flowcontrol_read_vs_write_request_count_watermarks` 是一个直方图向量, -记录请求数量的高/低水位线, -由标签 `phase` (取值为 `waiting` 和 `executing` )和 `request_kind` (取值为 `mutating` 和 `readOnly` )拆分; -标签 `mark` 取值为 `high` 和 `low` 。 -`apiserver_flowcontrol_read_vs_write_request_count_samples` 向量观察到有值新增,则该向量累积。 -这些水位线显示了样本值的范围。 + 记录请求数量的高/低水位线, + 由标签 `phase` (取值为 `waiting` 和 `executing` )和 `request_kind` + (取值为 `mutating` 和 `readOnly` )拆分;标签 `mark` 取值为 `high` 和 `low` 。 + `apiserver_flowcontrol_read_vs_write_request_count_samples` 向量观察到有值新增, + 则该向量累积。这些水位线显示了样本值的范围。 * `apiserver_flowcontrol_current_inqueue_requests` 是一个表向量, -记录包含排队中的(未执行)请求的瞬时数量, -由标签 `priorityLevel` 和 `flowSchema` 拆分。 + 记录包含排队中的(未执行)请求的瞬时数量, + 由标签 `priorityLevel` 和 `flowSchema` 拆分。 * `apiserver_flowcontrol_current_executing_requests` 是一个表向量, -记录包含执行中(不在队列中等待)请求的瞬时数量, -由标签 `priorityLevel` 和 `flowSchema` 拆分。 + 记录包含执行中(不在队列中等待)请求的瞬时数量, + 由标签 `priority_level` 和 `flow_schema` 进一步区分。 * `apiserver_flowcontrol_priority_level_request_count_samples` 是一个直方图向量, -记录当前请求的观测值,由标签 `phase` (取值为`waiting` 和 `executing`)和 `priorityLevel` 拆分。 -每个直方图都会定期进行观察,直到相关类别的最后活动为止。观察频率高。 + 记录当前请求的观测值,由标签 `phase` (取值为`waiting` 和 `executing`)和 + `priority_level` 进一步区分。 + 每个直方图都会定期进行观察,直到相关类别的最后活动为止。观察频率高。 * `apiserver_flowcontrol_priority_level_request_count_watermarks` 是一个直方图向量, -记录请求数的高/低水位线,由标签 `phase` (取值为 `waiting` 和 `executing` )和 `priorityLevel` 拆分; -标签 `mark` 取值为 `high` 和 `low` 。 -`apiserver_flowcontrol_priority_level_request_count_samples` 向量观察到有值新增,则该向量累积。 -这些水位线显示了样本值的范围。 + 记录请求数的高/低水位线,由标签 `phase` (取值为 `waiting` 和 `executing` )和 + `priority_level` 拆分; + 标签 `mark` 取值为 `high` 和 `low` 。 + `apiserver_flowcontrol_priority_level_request_count_samples` 向量观察到有值新增, + 则该向量累积。这些水位线显示了样本值的范围。 * `apiserver_flowcontrol_request_queue_length_after_enqueue` 是一个直方图向量, -记录请求队列的长度,由标签 `priorityLevel` 和 `flowSchema` 拆分。 -每个排队中的请求都会为其直方图贡献一个样本,并在添加请求后立即上报队列的长度。 -请注意,这样产生的统计数据与无偏调查不同。 - {{< note >}} - - 直方图中的离群值在这里表示单个流(即,一个用户或一个名称空间的请求,具体取决于配置)正在疯狂请求 API 服务器,并受到限制。 - 相反,如果一个优先级的直方图显示该优先级的所有队列都比其他优先级的队列长,则增加 PriorityLevelConfigurations 的并发份额是比较合适的。 - {{< /note >}} + 记录请求队列的长度,由标签 `priority_level` 和 `flow_schema` 进一步区分。 + 每个排队中的请求都会为其直方图贡献一个样本,并在添加请求后立即上报队列的长度。 + 请注意,这样产生的统计数据与无偏调查不同。 + + {{< note >}} + 直方图中的离群值在这里表示单个流(即,一个用户或一个名称空间的请求, + 具体取决于配置)正在疯狂地向 API 服务器发请求,并受到限制。 + 相反,如果一个优先级的直方图显示该优先级的所有队列都比其他优先级的队列长, + 则增加 PriorityLevelConfigurations 的并发份额是比较合适的。 + {{< /note >}} * `apiserver_flowcontrol_request_concurrency_limit` 是一个表向量, -记录并发限制的计算值(基于 API 服务器的总并发限制和 PriorityLevelConfigurations 的并发份额), -并按标签 `priorityLevel` 拆分。 + 记录并发限制的计算值(基于 API 服务器的总并发限制和 PriorityLevelConfigurations + 的并发份额),并按标签 `priority_level` 进一步区分。 * `apiserver_flowcontrol_request_wait_duration_seconds` 是一个直方图向量, -记录请求排队的时间, -由标签 `flowSchema` (表示与请求匹配的 FlowSchema ), -`priorityLevel` (表示分配该请求的优先级) -和 `execute` (表示请求是否开始执行)拆分。 - {{< note >}} - - 由于每个 FlowSchema 总会给请求分配 PriorityLevelConfigurations,因此你可以为一个优先级添加所有 FlowSchema 的直方图,以获取分配给该优先级的请求的有效直方图。 - {{< /note >}} + 记录请求排队的时间, + 由标签 `flow_schema` (表示与请求匹配的 FlowSchema ), + `priority_level` (表示分配该请求的优先级) + 和 `execute` (表示请求是否开始执行)进一步区分。 + + {{< note >}} + 由于每个 FlowSchema 总会给请求分配 PriorityLevelConfigurations, + 因此你可以为一个优先级添加所有 FlowSchema 的直方图,以获取分配给 + 该优先级的请求的有效直方图。 + {{< /note >}} * `apiserver_flowcontrol_request_execution_seconds` 是一个直方图向量, -记录请求实际执行需要花费的时间, -由标签 `flowSchema` (表示与请求匹配的 FlowSchema )和 `priorityLevel` (表示分配给该请求的优先级)拆分。 - - -### 调试端点 {#Debug-endpoints} + 记录请求实际执行需要花费的时间, + 由标签 `flow_schema` (表示与请求匹配的 FlowSchema )和 + `priority_level` (表示分配给该请求的优先级)进一步区分。 +### 调试端点 {#Debug-endpoints} + 启用 APF 特性后, kube-apiserver 会在其 HTTP/HTTPS 端口提供以下路径: -- `/debug/api_priority_and_fairness/dump_priority_levels` —— 所有优先级及其当前状态的列表。你可以这样获取: +- `/debug/api_priority_and_fairness/dump_priority_levels` —— + 所有优先级及其当前状态的列表。你可以这样获取: + ```shell kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels ``` 输出类似于: + ``` PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests, workload-low, 0, true, false, 0, 0, @@ -817,13 +871,16 @@ You can fetch like this: - `/debug/api_priority_and_fairness/dump_queues` - a listing of all the queues and their current state. You can fetch like this: --> -- `/debug/api_priority_and_fairness/dump_queues` ——所有队列及其当前状态的列表。你可以这样获取: +- `/debug/api_priority_and_fairness/dump_queues` —— 所有队列及其当前状态的列表。 + 你可以这样获取: + ```shell kubectl get --raw /debug/api_priority_and_fairness/dump_queues ``` 输出类似于: + ``` PriorityLevelName, Index, PendingRequests, ExecutingRequests, VirtualStart, workload-high, 0, 0, 0, 0.0000, @@ -838,13 +895,16 @@ You can fetch like this: - `/debug/api_priority_and_fairness/dump_requests` - a listing of all the requests that are currently waiting in a queue. You can fetch like this: --> -- `/debug/api_priority_and_fairness/dump_requests` ——当前正在队列中等待的所有请求的列表。你可以这样获取: +- `/debug/api_priority_and_fairness/dump_requests` ——当前正在队列中等待的所有请求的列表。 + 你可以这样获取: + ```shell kubectl get --raw /debug/api_priority_and_fairness/dump_requests ``` 输出类似于: + ``` PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime, exempt, , , , , , @@ -859,6 +919,7 @@ You can fetch like this: 你可以使用以下命令获得更详细的清单: + ```shell kubectl get --raw '/debug/api_priority_and_fairness/dump_requests?includeRequestDetails=1' ```