Равноправный доступ к API
Kubernetes v1.20 [beta]
Контроль за поведением API-сервера Kubernetes в условиях высокой нагрузки — ключевая задача для администраторов кластера. В kube-apiserver имеются некоторые механизмы управления (например, флаги командной строки --max-requests-inflight
и --max-mutating-requests-inflight
) для ограничения нагрузки на сервер. Они предотвращают наплыв входящих запросов и потенциальный отказ сервера API, но не позволяют гарантировать прохождение наиболее важных запросов в периоды высокой нагрузки.
Функция регулирования приоритета и обеспечения равноправного доступа к API (API Priority and Fairness), или РДА, — отличная альтернатива флагам. Она оптимизирует вышеупомянутые ограничения на максимальное количество запросов. РДА тщательнее классифицирует запросы и изолирует их. Также она поддерживает механизм очередей, который помогает обрабатывать запросы при краткосрочных всплесках нагрузки. Отправка запросов из очередей осуществляется на основе метода организации равноправных очередей, поэтому плохо работающий контроллер не будет мешать работе других (даже с аналогичным уровнем приоритета).
Эта функция предназначена для корректной работы со стандартными контроллерами, которые используют информеры и реагируют на неудачные API-запросы, экспоненциально увеличивая выдержку (back-off) между ними, а также клиентами, устроенными аналогичным образом.
Внимание:
Запросы, отнесенные к категории "long-running" — в первую очередь следящие, — не подпадают под действие фильтра функции равноправного доступа к API. Это также верно для флага--max-requests-inflight
без включенной функции РДА.Включение/отключение равноправного доступа к API
Управление РДА осуществляется с помощью переключателя функционала (feature gate); по умолчанию функция включена. В разделе Переключатели функционала приведено их общее описание и способы включения/отключения. В случае РДА соответствующий переключатель называется "APIPriorityAndFairness". Данная функция также включает группу API, при этом: (a) версия v1alpha1
по умолчанию отключена, (b) версии v1beta1
и v1beta2
по умолчанию включены. Чтобы отключить РДА и бета-версии групп API, добавьте следующие флаги командной строки в вызов kube-apiserver
:
kube-apiserver \
--feature-gates=APIPriorityAndFairness=false \
--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=false,flowcontrol.apiserver.k8s.io/v1beta2=false \
# …и остальные флаги, как обычно
Кроме того, версию v1alpha1 группы API можно включить с помощью --runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true
.
Флаг командной строки --enable-priority-and-fairness=false
отключит функцию равноправного доступа к API, даже если другие флаги ее активировали.
Основные понятия
Функция равноправного доступа к API в своей работе использует несколько базовых понятий/механизмов. Входящие запросы классифицируются по атрибутам с помощью т.н. FlowSchemas, после чего им присваиваются уровни приоритета. Уровни приоритета обеспечивают некоторую степень изоляции, обеспечивая различные пределы параллелизма, предотвращая влияние запросов с разными уровнями приоритета друг на друга. В пределах одного приоритета алгоритм равнодоступного формирования очереди предотвращает взаимное влияние запросов из разных потоков и формирует очередь запросов, снижая число неудачных запросов во время всплесков трафика при приемлемо низкой средней нагрузке.
Уровни приоритета
Без включенного равноправного доступа к API управление общим параллелизмом в API-сервере осуществляется флагами --max-requests-inflight
и --max-mutating-requests-inflight
для kube-apiserver
. При включенном равноправном доступе к API пределы параллелизма, заданные этими флагами, суммируются, а затем сумма распределяется по настраиваемому набору уровней приоритета. Каждому входящему запросу присваивается определенный уровень приоритета, причем каждый уровень приоритета может отправлять только такое количество параллельных запросов, которое прописано в его конфигурации.
Конфигурация по умолчанию, например, предусматривает отдельные уровни приоритета для запросов на выборы лидера, запросов от встроенных контроллеров и запросов от Pod'ов. Это означает, что Pod, ведущий себя некорректно и переполняющий API-сервер запросами, не сможет помешать выборам лидера или оказать влияние на действия встроенных контроллеров.
Очереди
Каждый уровень приоритета может включать большое количество различных источников трафика. Во время перегрузки важно предотвратить негативное влияние одного потока запросов на остальные (например, в идеале один сбойный клиент, переполняющий kube-apiserver своими запросами, не должен оказывать заметного влияния на других клиентов). Для этого при обработке запросов с одинаковым уровнем приоритета используется алгоритм равнодоступной очереди. Каждый запрос приписывается к потоку, который идентифицируется по имени соответствующей FlowSchema и дифференциатору потока: пользователю-источнику запроса, пространству имен целевого ресурса или пустым значением. Система старается придать примерно равный вес запросам в разных потоках с одинаковым уровнем приоритета. Для раздельной обработки различных инстансов контроллеры с большим их числом должны аутентифицироваться под разными именами пользователей.
Распределив запрос в некоторый поток, РДА приписывает его к очереди. Этот процесс базируется на методе, известном как shuffle sharding (тасование между шардами), который относительно эффективно изолирует потоки низкой интенсивности от потоков высокой интенсивности с помощью очередей.
Параметры алгоритма постановки в очередь можно настраивать для каждого уровня приоритетов. В результате администратор может выбирать между использованием памяти, равнодоступностью (свойством, которое обеспечивает продвижение независимых потоков, когда совокупный трафик превышает пропускную способность), толерантностью к всплескам трафика и дополнительной задержкой, вызванной постановкой в очередь.
Запросы-исключения
Некоторые запросы считаются настолько важными, что на них не распространяется ни одно из ограничений, налагаемых этой функцией. Механизм исключений не позволяет ошибочно настроенной конфигурации управления потоком полностью вывести сервер API из строя.
Ресурсы
API управления потоками включает в себя два вида ресурсов. PriorityLevelConfigurations определяет доступные классы изоляции, долю доступного бюджета параллелизма, которая выделяется для каждого класса, и позволяет выполнять тонкую настройку работы с очередями. FlowSchema используется для классификации отдельных входящих запросов, сопоставляя каждый из них с одной из конфигураций PriorityLevelConfiguration. Кроме того, существует версия v1alpha1
данной группы API, с аналогичными Kinds с теми же синтаксисом и семантикой.
PriorityLevelConfiguration
PriorityLevelConfiguration представляет отдельный класс изоляции. У каждой конфигурации PriorityLevelConfiguration имеется независимый предел на количество активных запросов и ограничения на число запросов в очереди.
Пределы параллелизма для PriorityLevelConfigurations указываются не в виде абсолютного количества запросов, а в виде "долей параллелизма" (concurrency shares). Совокупный объем ресурсов API-сервера, доступных для параллелизма, распределяется между существующими PriorityLevelConfigurations пропорционально этим долям. Администратор кластера может увеличить или уменьшить совокупный объем трафика на сервер, просто перезапустив kube-apiserver с другим значением --max-requests-inflight
(или --max-mutating-requests-inflight
). В результате пропускная способность каждой PriorityLevelConfigurations возрастет (или снизится) соразмерно ее доле.
Внимание:
При включенной функции Priority and Fairness суммарный предел параллелизма для сервера равен сумме--max-requests-inflight
и --max-mutating-requests-inflight
. При этом мутирующие и не мутирующие запросы рассматриваются вместе; чтобы обрабатывать их независимо для некоторого ресурса, создайте отдельные FlowSchemas для мутирующих и не мутирующих действий (verbs).Поле type
спецификации PriorityLevelConfiguration определяет судьбу избыточных запросов, когда их объем, отнесенный к одной PriorityLevelConfiguration, превышает ее допустимый уровень параллелизма. Тип Reject
означает, что избыточный трафик будет немедленно отклонен с ошибкой HTTP 429 (Too Many Requests). Тип Queue
означает, что запросы, превышающие пороговое значение, будут поставлены в очередь, при этом для балансировки прогресса между потоками запросов будут использоваться методы тасования между шардами и равноправных очередей.
Конфигурация очередей позволяет настроить алгоритм равноправных очередей для каждого уровня приоритета. Подробности об алгоритме можно узнать из предложения по улучшению; если вкратце:
Увеличение
queues
снижает количество конфликтов между различными потоками за счет повышенного использования памяти. При единице логика равнодоступной очереди отключается, но запросы все равно могут быть поставлены в очередь.Увеличение длины очереди (
queueLengthLimit
) позволяет выдерживать большие всплески трафика без потери запросов за счет увеличения задержек и повышенного потребления памяти.Изменение
handSize
позволяет регулировать вероятность конфликтов между различными потоками и общий параллелизм, доступный для одного потока в условиях чрезмерной нагрузки.Примечание:
БольшийhandSize
снижает вероятность конфликта двух отдельных потоков (и, следовательно, вероятность того, что один из них подавит другой), но повышает вероятность того, что малое число потоков загрузят API-сервер. БольшийhandSize
также потенциально увеличивает задержку, которую может вызвать один поток с высоким трафиком. Максимальное возможное количество запросов в очереди от одного потока равноhandSize * queueLengthLimit
.
Ниже приведена таблица с различными конфигурациями, показывающая вероятность того, что "мышь" (поток низкой интенсивности) будет раздавлена "слонами" (потоками высокой интенсивности) в зависимости от числа "слонов" при тасовании потоков между шардами. Скрипт для расчета таблицы доступен по ссылке.
handSize | Число очередей | 1 слон | 4 слона | 16 слонов |
---|---|---|---|---|
12 | 32 | 4.428838398950118e-09 | 0.11431348830099144 | 0.9935089607656024 |
10 | 32 | 1.550093439632541e-08 | 0.0626479840223545 | 0.9753101519027554 |
10 | 64 | 6.601827268370426e-12 | 0.00045571320990370776 | 0.49999929150089345 |
9 | 64 | 3.6310049976037345e-11 | 0.00045501212304112273 | 0.4282314876454858 |
8 | 64 | 2.25929199850899e-10 | 0.0004886697053040446 | 0.35935114681123076 |
8 | 128 | 6.994461389026097e-13 | 3.4055790161620863e-06 | 0.02746173137155063 |
7 | 128 | 1.0579122850901972e-11 | 6.960839379258192e-06 | 0.02406157386340147 |
7 | 256 | 7.597695465552631e-14 | 6.728547142019406e-08 | 0.0006709661542533682 |
6 | 256 | 2.7134626662687968e-12 | 2.9516464018476436e-07 | 0.0008895654642000348 |
6 | 512 | 4.116062922897309e-14 | 4.982983350480894e-09 | 2.26025764343413e-05 |
6 | 1024 | 6.337324016514285e-16 | 8.09060164312957e-11 | 4.517408062903668e-07 |
FlowSchema
FlowSchema сопоставляется со входящими запросами; по результатам данного действия тем приписывается определенный уровень приоритета. Каждый входящий запрос по очереди проверяется на соответствие каждой FlowSchema, начиная с тех, у которых наименьшее численное значение matchingPrecedence
(т.е., логически наивысший приоритет). Проверка ведется до первого совпадения.
Внимание:
Учитывается только первая подходящая FlowSchema для данного запроса. Если одному входящему запросу соответствует несколько FlowSchemas, он попадет в ту, у которой наивысшийmatchingPrecedence
. Если несколько FlowSchema с одинаковым matchingPrecedence
соответствуют одному запросу, предпочтение будет отдано той, у которой лексикографически меньшее имя (name
). Впрочем, лучше не полагаться на это, а убедиться, что matchingPrecedence
уникален для всех FlowSchema.Схема FlowSchema подходит определенному запросу, если хотя бы одно из ее правил (rules
) подходит ему. В свою очередь, правило соответствует запросу, если ему соответствует хотя бы один из его субъектов (subjects
) и хотя бы одно из его правил resourceRules
или nonResourceRules
(в зависимости от того, является ли входящий запрос ресурсным или нересурсным URL).
Для поля name
в субъектах (subjects) и полей verbs
, apiGroups
, resources
, namespaces
и nonResourceURLs
в ресурсных и нересурсных правилах может быть указан универсальный символ *
, который будет соответствовать всем значениям для данного поля, фактически исключая его из рассмотрения.
Параметр distinguisherMethod.type
схемы FlowSchema определяет, как запросы, соответствующие этой схеме, будут разделяться на потоки. Он может быть либо ByUser
(в этом случае один запрашивающий пользователь не сможет лишить других пользователей ресурсов), либо ByNamespace
(в этом случае запросы на ресурсы в одном пространстве имен не смогут помешать запросам на ресурсы в других пространствах имен), либо он может быть пустым (или distinguisherMethod
может быть опущен) (в этом случае все запросы, соответствующие данной FlowSchema, будут считаться частью одного потока). Правильный выбор для определенной FlowSchema зависит от ресурса и конкретной среды.
Значения по умолчанию
kube-apiserver поддерживает два вида объектов конфигурации РДА: обязательные и рекомендуемые.
Обязательные объекты конфигурации
Четыре обязательных объекта конфигурации отражают защитное поведение, встроенное в серверы. Оно реализуется независимо от этих объектов; параметры последних просто его отражают.
Обязательный уровень приоритета
exempt
используется для запросов, которые вообще не подчиняются контролю потока: они всегда будут доставляться немедленно. Обязательная FlowSchemaexempt
относит к этому уровню приоритета все запросы из группыsystem:masters
. При необходимости можно задать другие FlowSchemas, которые будут наделять другие запросы данным уровнем приоритета.Обязательный уровень приоритета
catch-all
используется в сочетании с обязательной FlowSchemacatch-all
, гарантируя, что каждый запрос получит какую-либо классификацию. Как правило, полагаться на эту универсальную конфигурацию не следует. Рекомендуется создать свои собственные универсальные FlowSchema и PriorityLevelConfiguration (или использовать опциональный уровень приоритетаglobal-default
, доступный по умолчанию). Поскольку предполагается, что обязательный уровень приоритетаcatch-all
будет использоваться редко, его доля параллелизма невысока, кроме того, он не ставит запросы в очередь.
Опциональные объекты конфигурации
Опциональные объекты FlowSchemas и PriorityLevelConfigurations образуют оптимальную конфигурацию по умолчанию. При желании их можно изменить и/или создать дополнительные объекты конфигурации. Если велика вероятность высокой нагрузки на кластер, следует решить, какая конфигурация будет работать лучше всего.
Опциональная конфигурация группирует запросы по шести уровням приоритета:
Уровень приоритета
node-high
предназначен для проверки здоровья узлов.Уровень приоритета
system
предназначен для запросов от группыsystem:nodes
, не связанных с состоянием узлов, а именно: от kubelet'ов, которые должны иметь возможность связываться с сервером API для планирования рабочих нагрузок.Уровень приоритета
leader-election
предназначен для запросов на выборы лидера от встроенных контроллеров (в частности, запросы на объекты типаEndpoint
,ConfigMap
илиLease
, поступающие от пользователейsystem:kube-controller-manager
илиsystem:kube-scheduler
и служебных учетных записей в пространстве именkube-system
). Их важно изолировать от другого трафика, поскольку сбои при выборе лидеров приводят к перезагрузкам контроллеров. Соответственно, новые контроллеры потребляют трафик, синхронизируя свои информеры.Уровень приоритета
workload-high
предназначен для прочих запросов от встроенных контроллеров.Уровень приоритета
workload-low
предназначен для запросов от остальных учетных записей служб, которые обычно включают все запросы от контроллеров, работающих в Pod'ах.Уровень приоритета
global-default
обрабатывает весь остальной трафик, например, интерактивные командыkubectl
, выполняемые непривилегированными пользователями.
Опциональные FlowSchemas служат для направления запросов на вышеуказанные уровни приоритета и здесь не перечисляются.
Обслуживание обязательных и опциональных объектов конфигурации
Каждый kube-apiserver
самостоятельно обслуживает обязательные и опциональные объекты конфигурации, используя стратегию начальных/периодических проходов. Таким образом, в ситуации с серверами разных версий может возникнуть пробуксовка (thrashing) из-за разного представления серверов о правильном содержании этих объектов.
Каждый kube-apiserver
выполняет начальный проход по обязательным и опциональным объектам конфигурации, а затем периодически (раз в минуту) обходит их.
Для обязательных объектов обслуживание заключается в проверке того, что объект существует и имеет надлежащую спецификацию (spec). Сервер не разрешает создавать или обновлять объекты со spec, которая не соответствует его защитному поведению.
Обслуживание опциональных объектов конфигурации предусматривает возможность переопределения их спецификации (spec). Кроме того, удаление носит непостоянный характер: объект будет восстановлен в процессе обслуживания. Если опциональный объект конфигурации не нужен, его не нужно удалять, но достаточно настроить spec'и так, чтобы последствия были минимальными. Обслуживание опциональных объектов также рассчитано на поддержку автоматической миграции при выходе новой версии kube-apiserver
, при этом вероятны конфликты (thrashing), пока группировка серверов остается смешанной.
Обслуживание опционального объекта конфигурации предусматривает его создание — с рекомендуемой спецификацией сервера — если тот не существует. В то же время, если объект уже существует, поведение при обслуживании зависит от того, кто им управляет — kube-apiserver
'ы или пользователи. В первом случае сервер гарантирует, что спецификация объекта соответствует рекомендуемой; во втором случае спецификация не анализируется.
Чтобы узнать, кто управляет объектом, необходимо найти аннотацию с ключом apf.kubernetes.io/autoupdate-spec
. Если такая аннотация существует и ее значение равно true
, то объект контролируется kube-apiserver'ами. Если аннотация существует и ее значение равно false
, объект контролируется пользователями. Если ни одно из этих условий не выполняется, выполняется обращение к metadata.generation
объекта. Если этот параметр равен 1, объект контролируется kube-apiserver'ами. В противном случае объект контролируют пользователи. Эти правила были введены в версии 1.22, и использование metadata.generation
обусловлено переходом от более простого предыдущего поведения. Пользователи, желающие контролировать опциональный объект конфигурации, должны убедиться, что его аннотация apf.kubernetes.io/autoupdate-spec
имеет значение false
.
Обслуживание обязательного или опционального объекта конфигурации также предусматривает проверку наличия у него аннотации apf.kubernetes.io/autoupdate-spec
, которая позволяет понять, контролируют ли его kube-apiserver'ы.
Обслуживание также предусматривает удаление объектов, которые не являются ни обязательными, ни опциональными, но имеют аннотацию apf.kubernetes.io/autoupdate-spec=true
.
Освобождение проверок работоспособности от параллелизма
Опциональная конфигурация не предусматривает особого отношения к health check-запросам на kube-apiserver'ы от их локальных kubelet'ов. В данном случае обычно используется защищенный порт, но учетные данные не передаются. В опциональной конфигурации такие запросы относятся к FlowSchema global-default
и соответствующему уровню приоритета global-default
, где другой трафик может мешать их прохождению.
Чтобы освободить такие запросы от частотных ограничений, можно добавить FlowSchema, приведенную ниже.
Внимание:
Добавление данной FlowSchema позволит злоумышленникам отправлять удовлетворяющие ей health-check-запросы в любом количестве. При наличии фильтра веб-трафика или аналогичного внешнего механизма безопасности для защиты API-сервера кластера от интернет-трафика можно настроить правила для блокировки любых health-check-запросов, поступающих из-за пределов кластера.apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: health-for-strangers
spec:
matchingPrecedence: 1000
priorityLevelConfiguration:
name: exempt
rules:
- nonResourceRules:
- nonResourceURLs:
- "/healthz"
- "/livez"
- "/readyz"
verbs:
- "*"
subjects:
- kind: Group
group:
name: system:unauthenticated
Диагностика
Каждый HTTP-ответ от сервера API с включенной функцией РДА содержит два дополнительных заголовка: X-Kubernetes-PF-FlowSchema-UID
и X-Kubernetes-PF-PriorityLevel-UID
. В них указываются схема потока и уровень приоритета соответственно. Имена объектов API не включаются в эти заголовки на случай, если запрашивающий пользователь не обладает правами на их просмотр, поэтому при отладке можно использовать команду типа:
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 к именам для FlowSchemas и PriorityLevelConfigurations.
Наблюдаемость
Метрики
Примечание:
В Kubernetes до версии v1.20 лейблыflow_schema
и priority_level
также могли называться flowSchema
и priorityLevel
, соответственно. При использовании Kubernetes v1.19 и более ранних версий обратитесь к документации для соответствующей версии.При включении функции равноправного доступа к API kube-apiserver начинает экспортировать дополнительные метрики. Их мониторинг помогает выявить негативное влияние (throttling) текущей конфигурации на важный трафик или найти неэффективные рабочие нагрузки, которые вредят здоровью системы.
apiserver_flowcontrol_rejected_requests_total
— вектор-счетчик (кумулятивный с момента запуска сервера) запросов, которые были отклонены, с разбивкой по лейбламflow_schema
(указывает на FlowSchema у запросов, попавших под соответствие),priority_level
(уровень приоритета, который был присвоен этим запросам) иreason
. Лейблreason
будет иметь одно из следующих значений:queue-full
— в очереди уже слишком много запросов;concurrency-limit
— PriorityLevelConfiguration настроена на отклонение, а не на постановку в очередь избыточных запросов;time-out
— запрос все еще находился в очереди, когда истек его лимит ожидания.
apiserver_flowcontrol_dispatched_requests_total
— вектор-счетчик (кумулятивный с момента запуска сервера) запросов, которые начали выполняться, сгруппированный по лейбламflow_schema
(указывает на FlowSchema у запросов, попавших под соответствие) иpriority_level
(уровень приоритета, который был присвоен этим запросам).apiserver_current_inqueue_requests
— вектор предыдущего максимума числа запросов в очереди, сгруппированных по лейблуrequest_kind
, значение которогоmutating
илиreadOnly
. Эти максимумы описывают наибольшее число, наблюдавшееся в последнем завершенном односекундном окне. Они дополняют более старый векторapiserver_current_inflight_requests
, который показывает максимум активно обслуживаемых запросов в последнем окне.apiserver_flowcontrol_read_vs_write_request_count_samples
— вектор-гистограмма наблюдений за тогда-текущим количеством запросов с разбивкой по лейбламphase
(принимает значенияwaiting
иexecuting
) иrequest_kind
(принимает значенияmutating
иreadOnly
). Наблюдения проводятся периодически с высокой частотой. Каждое наблюдаемое значение представляет собой число в диапазоне от 0 до 1, равное отношению числа запросов к соответствующему ограничению на их количество (ограничение длины очереди в случае ожидания и лимит параллелизма в случае выполнения).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
. Эти экстремумы помогают определить разброс диапазона значений, наблюдавшийся в разных сэмплах.apiserver_flowcontrol_current_inqueue_requests
— gauge-вектор, содержащий количество стоящих в очереди (не выполняющихся) запросов в каждый момент с разбивкой по лейбламpriority_level
иflow_schema
.apiserver_flowcontrol_current_executing_requests
— gauge-вектор, содержащий количество исполняемых (не ожидающих в очереди) запросов в каждый момент с разбивкой по лейбламpriority_level
иflow_schema
.apiserver_flowcontrol_request_concurrency_in_use
— gauge-вектор, содержащий количество занятых мест в каждый момент с разбивкой по лейбламpriority_level
иflow_schema
.apiserver_flowcontrol_priority_level_request_count_samples
— вектор-гистограмма наблюдений за текущим-на-тот-момент количеством запросов с разбивкой по лейбламphase
(принимает значенияwaiting
иexecuting
) иpriority_level
. Каждая гистограмма получает наблюдения, сделанные периодически, вплоть до последней активности соответствующего рода. Наблюдения проводятся с высокой частотой. Каждое наблюдаемое значение представляет собой число в диапазоне от 0 до 1, равное отношению числа запросов к соответствующему ограничению на их количество (ограничение длины очереди в случае ожидания и лимит параллелизма в случае выполнения).apiserver_flowcontrol_priority_level_request_count_watermarks
— вектор-гистограмма максимумов или минимумов количества запросов с разбивкой по лейбламphase
(принимает значенияwaiting
иexecuting
) иpriority_level
; лейблmark
принимает значенияhigh
иlow
. Минимумы и максимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено вapiserver_flowcontrol_priority_level_request_count_samples
. Эти экстремумы показывают диапазон значений, наблюдавшийся в разных сэмплах.apiserver_flowcontrol_priority_level_seat_count_samples
— вектор-гистограмма наблюдений за использованием лимита параллелизма для уровня приоритета с разбивкой поpriority_level
. Использование — отношение (количество занятых мест) / (предел параллелизма). Метрика учитывает все стадии выполнения (как обычную, так и дополнительную задержку в конце записи для покрытия соответствующей работы по уведомлению) всех запросов, кроме WATCHes; для этих запросов учитывается только начальная стадия по доставке уведомлений о ранее существующих объектах. Каждая гистограмма в векторе также помечена лейбломphase: executing
(количество мест для фазы ожидания не ограничено). Каждая гистограмма получает наблюдения, сделанные периодически, вплоть до последней активности соответствующего рода. Наблюдения производятся с высокой частотой.apiserver_flowcontrol_priority_level_seat_count_watermarks
— вектор-гистограмма минимумов и максимумов использования предела параллелизма для уровня приоритета с разбивкой поpriority_leve
иmark
(принимает значенияhigh
иlow
). Каждая гистограмма в векторе также помечена лейбломphase: executing
(для фазы ожидания предел на места отсутствует). Максимумы и минимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено вapiserver_flowcontrol_priority_level_seat_count_samples
. Эти экстремумы помогают определить разброс диапазона значений, наблюдавшийся в разных сэмплах.apiserver_flowcontrol_request_queue_length_after_enqueue
— вектор-гистограмма длины очереди для очередей с разбивкой по лейбламpriority_level
иflow_schema
как выборки по поставленным в очередь запросам. Каждый запрос при постановке в очередь вносит один сэмпл в гистограмму, сообщая о длине очереди сразу после добавления запроса. Обратите внимание, что это дает иную статистику, чем при объективном исследовании.Примечание:
В данном случае выброс в гистограмме означает, что, скорее всего, один поток (т.е. запросы от одного пользователя или для одного пространства имен, в зависимости от конфигурации) переполняет сервер API и "срезается" (throttled). И наоборот, если гистограмма одного уровня приоритета показывает, что все очереди для этого уровня приоритета длиннее, чем для других уровней приоритета, возможно, следует увеличить долю параллелизма для этого уровня приоритета в PriorityLevelConfiguration.apiserver_flowcontrol_request_concurrency_limit
— gauge-вектор, содержащий вычисленный лимит параллелизма (основанный на общем лимите параллелизма сервера API и долях параллелизма PriorityLevelConfigurations), с разбивкой по лейблуpriority_level
.apiserver_flowcontrol_request_wait_duration_seconds
— вектор-гистограмма времени ожидания запросов в очереди с разбивкой по лейбламflow_schema
(указывает, какая схема соответствует запросу),priority_level
(указывает, к какому уровню был отнесен запрос) иexecute
(указывает, начал ли запрос выполняться).Примечание:
Поскольку каждая FlowSchema всегда относит запросы к одному PriorityLevelConfiguration, можно сложить гистограммы для всех FlowSchema для одного уровня приоритета, чтобы получить эффективную гистограмму для запросов, отнесенных к этому уровню приоритета.apiserver_flowcontrol_request_execution_seconds
— вектор-гистограмма времени, затраченного на выполнение запросов, с разбивкой по по лейбламflow_schema
(указывает, какая схема соответствует запросу) иpriority_level
(указывает, к какому уровню был отнесен запрос).apiserver_flowcontrol_watch_count_samples
— вектор-гистограмма количества активных запросов WATCH, относящихся к данной записи, с разбивкой поflow_schema
иpriority_level
.apiserver_flowcontrol_work_estimated_seats
— вектор-гистограмма количества предполагаемых мест (максимум начального и конечного этапа выполнения), связанных с запросами, с разбивкой поflow_schema
иpriority_level
.apiserver_flowcontrol_request_dispatch_no_accommodation_total
— вектор-счетчик количества событий, которые в принципе могли бы привести к отправке запроса, но не привели из-за отсутствия доступного параллелизма, с разбивкой поflow_schema
иpriority_level
. Соответствующими событиями являются поступление запроса и завершение запроса.
Отладочные endpoint'ы
При включении функции равноправного доступа к API kube-apiserver
предоставляет следующие дополнительные пути на своих HTTP[S]-портах.
/debug/api_priority_and_fairness/dump_priority_levels
— список всех уровней приоритета и текущее состояние каждого из них. Получить его можно следующим образом:kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
Вывод выглядит примерно так:
PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests, workload-low, 0, true, false, 0, 0, global-default, 0, true, false, 0, 0, exempt, <none>, <none>, <none>, <none>, <none>, catch-all, 0, true, false, 0, 0, system, 0, true, false, 0, 0, leader-election, 0, true, false, 0, 0, workload-high, 0, true, false, 0, 0,
/debug/api_priority_and_fairness/dump_queues
— список всех очередей и их текущее состояние. Получить его можно следующим образом:kubectl get --raw /debug/api_priority_and_fairness/dump_queues
Вывод выглядит примерно так:
PriorityLevelName, Index, PendingRequests, ExecutingRequests, VirtualStart, workload-high, 0, 0, 0, 0.0000, workload-high, 1, 0, 0, 0.0000, workload-high, 2, 0, 0, 0.0000, ... leader-election, 14, 0, 0, 0.0000, leader-election, 15, 0, 0, 0.0000,
/debug/api_priority_and_fairness/dump_requests
— список всех запросов, которые в настоящее время ожидают в очереди. Получить его можно следующим образом:kubectl get --raw /debug/api_priority_and_fairness/dump_requests
Вывод выглядит примерно так:
PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime, exempt, <none>, <none>, <none>, <none>, <none>, system, system-nodes, 12, 0, system:node:127.0.0.1, 2020-07-23T15:26:57.179170694Z,
В дополнение к запросам, стоящим в очереди, вывод включает одну фантомную строку для каждого уровня приоритета, на которую не распространяется ограничение.
Более подробный список можно получить с помощью следующей команды:
kubectl get --raw '/debug/api_priority_and_fairness/dump_requests?includeRequestDetails=1'
Вывод выглядит примерно так:
PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime, UserName, Verb, APIPath, Namespace, Name, APIVersion, Resource, SubResource, system, system-nodes, 12, 0, system:node:127.0.0.1, 2020-07-23T15:31:03.583823404Z, system:node:127.0.0.1, create, /api/v1/namespaces/scaletest/configmaps, system, system-nodes, 12, 1, system:node:127.0.0.1, 2020-07-23T15:31:03.594555947Z, system:node:127.0.0.1, create, /api/v1/namespaces/scaletest/configmaps,
Что дальше
Для получения подробной информации о функции равноправного доступа к API см. предложение по улучшению (KEP). Предложения и запросы функционала принимаются через SIG API Machinery или в специализированном канале Slack.