[Kubernetes] Новый механизм API Priority and Fairness в Kubernetes (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Эта статья посвящена новой функции Kubernetes: API Priority and Fairness (APF). Я хочу поделиться своими находками и рассказать, как определять политики для приоритизации и ограничения входящих запросов на API-сервер Kubernetes. Также мы рассмотрим некоторые метрики и отладочные конечные точки, которые позволяют оценивать влияние APF на контроллеры.Бета-версия функции APF включена по умолчанию, начиная с версии Kubernetes 1.20. В более ранних версиях Kubernetes она включается через функциональный шлюз APIPriorityAndFairness.Что такое APF?До появления функции APF на API-сервере для ограничения количества поступающих запросов применялись параметры командной строки --max-requests-inflight и --max-mutating-requests-inflight. Единственное отличие заключается в том, что при использовании этих параметров не разграничиваются изменяющие (mutating) запросы и остальные. Например, эти параметры не гарантируют, что низкоприоритетный трафик не «задушит» критически важные вызовы (такой сценарий описывается в этом примере проблемы).APF предлагает механизм управления потоком, чтобы API-сервер мог ограничивать запросы по принципу равнодоступности (fairness). Владельцы платформы могут задавать политики уровня API с целью классификации входящих запросов по различным приоритетам и потокам.
Управление запросами посредством потоков и приоритетовВсе входящие запросы оцениваются на соответствие набору схем потоков. Для каждого запроса подбирается одна конкретная схема потока, которая назначает запросу уровень приоритета. Следовательно, когда ограничиваются запросы с определенным уровнем приоритета, это никак не влияет на запросы с другими уровнями приоритета.Чтобы соблюдать принцип равнодоступности среди запросов с одним уровнем приоритета, соответствующая им схема потока связывает запросы с потоками — запросам из одного источника назначается одинаковый отличительный признак потока (flow distinguisher).В потоках запросов, которые невозможно выполнить прямо сейчас, организуются очереди по принципу перемешивающего шардинга (shuffle sharding), который часто применяется для изоляции рабочих нагрузок и повышения отказоустойчивости. Когда появляются достаточные ресурсы, система выводит отсортированные по потокам запросы из очередей по алгоритму организации равноправных очередей (fair queueing).Общие сведения о FlowSchema и PriorityLevelConfigurationИспользуемые в этом разделе команды тестировались на кластере Kubernetes 1.19, созданном с помощью kind 0.9.0. Для повышения удобочитаемости и фильтрации выходных данных YAML применялся обработчик yq 4.3.1.Prometheus Operator развернут посредством kube-prometheus 0.7. Способ организации доступа к консоли Prometheus через переадресацию портов описан в файле README компонента kube-prometheus.Прежде чем создать собственные ресурсы FlowSchema и PriorityLevelConfiguration, сначала рассмотрим ключевые концепции на основе стандартных ресурсов.Список схем потоков по умолчанию:
kubectl get flowschema
NAME PRIORITYLEVEL MATCHINGPRECEDENCE DISTINGUISHERMETHOD AGE MISSINGPL
exempt exempt 1 <none> 13m False
system-leader-election leader-election 100 ByUser 13m False
workload-leader-election leader-election 200 ByUser 13m False
system-nodes system 500 ByUser 13m False
kube-controller-manager workload-high 800 ByNamespace 13m False
kube-scheduler workload-high 800 ByNamespace 13m False
kube-system-service-accounts workload-high 900 ByNamespace 13m False
service-accounts workload-low 9000 ByUser 13m False
global-default global-default 9900 ByUser 13m False
catch-all catch-all 10000 ByUser 13m False
Возьмем в качестве примера схему потока system-leader-election, ее файл .spec выглядит следующим образом.Спецификация схемы потока system-leader-election:
kubectl get flowschema system-leader-election -oyaml | yq e '.spec' -
distinguisherMethod:
type: ByUser
matchingPrecedence: 100
priorityLevelConfiguration:
name: leader-election
rules:
- resourceRules:
- apiGroups:
- ""
namespaces:
- kube-system
resources:
- endpoints
- configmaps
verbs:
- get
- create
- update
- apiGroups:
- coordination.k8s.io
namespaces:
- '*'
resources:
- leases
verbs:
- get
- create
- update
subjects:
- kind: User
user:
name: system:kube-controller-manager
- kind: User
user:
name: system:kube-scheduler
- kind: ServiceAccount
serviceAccount:
name: '*'
namespace: kube-system
В разделе rules приведен список критериев, по которым опознаются соответствующие запросы. Схема потока назначается запросу только при одновременном соблюдении следующих условий:· если хотя бы один из ее subjects (субъектов) совпадает с инициатором запроса;· если хотя бы одна из записей resourceRules или nonResourceRules совпадает с действием (verb) и запрашиваемым ресурсом или нересурсом.Раздел distinguisherMethod определяет порядок вычисления отличительных признаков потоков:· ByUser — запросы от одного субъекта (subject) группируются в один и тот же поток, чтобы исключить доминирование каких-либо пользователей.· ByNamespace — запросы, исходящие от одного и того же пространства имен, группируются в один и тот же поток, чтобы исключить доминирование рабочих нагрузок в одном пространстве имен над рабочими нагрузками из других пространств имен.· Пустая строка — все запросы группируются в единый поток.В процессе сопоставления запросов схема потока с более низким значением matchingPrecedence имеет старшинство над более высоким значением matchingPrecendence.Ресурс priorityLevelConfiguration содержит в себе конфигурацию уровней приоритетов с заданными атрибутами управления потоками.Рассмотрим файл .spec конфигурации уровней приоритетов leader-election.Спецификация конфигурации уровней приоритетов leader-election:
kubectl get prioritylevelconfigurations leader-election -oyaml | yq e '.spec' -
limited:
assuredConcurrencyShares: 10
limitResponse:
queuing:
handSize: 4
queueLengthLimit: 50
queues: 16
type: Queue
type: Limited
Параметр limited.assuredConcurrencyShares определяет долю параллелизма, на основе которой рассчитывается гарантированное значение параллелизма. В документации к API Kubernetes есть подробное описание методики расчета гарантированного значения параллелизма.Метрика apiserver_flowcontrol_request_concurrenty_limit дает представление о расчетных предельных значениях параллелизма для каждого уровня приоритета:
Ограничения параллелизма для всех уровней приоритетаЗначение limited.assuredConcurrencyShares связано с метрикой apiserver_flowcontrol_request_concurrency_limit таким образом, что увеличение доли параллелизма для уровня приоритета приводит к росту предельного значения параллелизма. Так как суммарное ограничение параллелизма API-сервера распределяется по всем уровням приоритета, повышение ограничения одного уровня приоритета сокращает ограничение для других.Параметр limited.limitResponse определяет стратегию обработки запросов, которые невозможно исполнить прямо сейчас. Параметр limit.limitResponse.type допускает два значения:· Queue — запросы добавляются в очередь;· Reject — запросы отклоняются с ошибкой HTTP 429.Тип реагирования Queue позволяет задать конфигурацию постановки в очередь с помощью параметров limited.limitResponse.queuing. В документации и предложении по реализации функции APF более подробно описывается эффект от изменения параметров queues, queueLengthLimit и handSize.В следующем разделе мы научимся определять, какая схема сопоставляется нашим запросам.Определение соответствующей схемы потокаСамый быстрый способ определить, какая схема потока соответствует нашему запросу, — проанализировать два заголовка, поступающих от API-сервера в ответах APF: X-Kubernetes-PF-FlowSchema-UID и X-Kubernetes-PF-PriorityLevel-UID. В них содержатся UID-идентификаторы соответствующих схем потоков и конфигурации уровня приоритетов.Определение соответствующей схемы потока и уровня приоритета:
kubectl -n kube-system get po --v=8 2>&1 | grep -i x-kubernetes-pf
I0115 21:04:25.044262 65517 round_trippers.go:452] X-Kubernetes-Pf-Flowschema-Uid: c36148b8-623a-45a8-9c63-7158262f7727
I0115 21:04:25.044267 65517 round_trippers.go:452] X-Kubernetes-Pf-Prioritylevel-Uid: 0aab41a9-e078-4671-936b-937d6d5e8601
kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep c36148b8-623a-45a8-9c63-7158262f7727
c36148b8-623a-45a8-9c63-7158262f7727 exempt
kubectl get prioritylevelconfiguration -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 0aab41a9-e078-4671-936b-937d6d5e8601
0aab41a9-e078-4671-936b-937d6d5e8601 exempt
В примере выше, где я запрашиваю поды действием GET, запросу соответствует схема потока exempt и одноименная конфигурация уровня приоритета.Чтобы понять влияние этой схемы потока на мой запрос, исследуем ее спецификацию .spec.Спецификация схемы потока и уровня приоритета exempt:
kubectl get flowschema exempt -oyaml | yq e '.spec' -
matchingPrecedence: 1
priorityLevelConfiguration:
name: exempt
rules:
- nonResourceRules:
- nonResourceURLs:
- '*'
verbs:
- '*'
resourceRules:
- apiGroups:
- '*'
clusterScope: true
namespaces:
- '*'
resources:
- '*'
verbs:
- '*'
subjects:
- group:
name: system:masters
kind: Group
# kubectl get prioritylevelconfiguration exempt -oyaml | yq e '.spec' -
type: Exempt
Обратите внимание, что схема потока exempt:1. имеет наибольшее старшинство, так как параметр matchingPrecedence имеет значение 1;2. сопоставляется запросам от группы system:masters.Более того, в конфигурации уровня приоритета exempt параметр type соответствует Exempt, то есть какая-либо конфигурация очередности не требуется.В этом есть смысл, поскольку мои команды kubectl авторизуются посредством моих учетных данных cluster-admin kubeconfig, связанных с группой system:masters. Запросы от группы system:masters считаются критически важным трафиком, поэтому они идут в обход механизма управления потоками и передаются немедленно с помощью схемы потока exempt согласно ее конфигурации уровня приоритета exempt.С этим разобрались. Теперь можно поэкспериментировать с собственными схемой потока и конфигурацией уровня приоритета.Создание кастомных схемы потока и уровня приоритетаНачнем с создания пространства имен demo с тремя служебными учетными записями, а именно podlister-0, podlister-1 и podlister-2, предоставив им разрешения выполнять действия LIST и GET для подов из пространства имен demo.Создание пространства имен demo, его служебных учетных записей и задание требуемых параметров RBAC:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: demo
EOF
for i in {0..2}; do
cat <<EOF | kubectl auth reconcile -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: podlister
namespace: demo
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: podlister
namespace: demo
subjects:
- apiGroup: ""
kind: ServiceAccount
name: podlister-$i
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: podlister
EOF
done
for i in {0..2}; do
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: podlister-$i
namespace: demo
labels:
kubernetes.io/name: podlister-$i
EOF
done
Потом мы создаем произвольную схему потока, управляющую запросами от этих трех служебных учетных записей.Развертывание схемы потока и конфигурации уровня приоритета restrict-pod-lister:
cat <<EOF | kubectl apply -f -
apiVersion: flowcontrol.apiserver.k8s.io/v1alpha1
kind: FlowSchema
metadata:
name: restrict-pod-lister
spec:
priorityLevelConfiguration:
name: restrict-pod-lister
distinguisherMethod:
type: ByUser
rules:
- resourceRules:
- apiGroups: [""]
namespaces: ["demo"]
resources: ["pods"]
verbs: ["list", "get"]
subjects:
- kind: ServiceAccount
serviceAccount:
name: podlister-0
namespace: demo
- kind: ServiceAccount
serviceAccount:
name: podlister-1
namespace: demo
- kind: ServiceAccount
serviceAccount:
name: podlister-2
namespace: demo
---
apiVersion: flowcontrol.apiserver.k8s.io/v1alpha1
kind: PriorityLevelConfiguration
metadata:
name: restrict-pod-lister
spec:
type: Limited
limited:
assuredConcurrencyShares: 10
limitResponse:
queuing:
queueLengthLimit: 5
type: Queue
EOF
Единственное нестандартное значение в уровне приоритета restrict-pod-lister — это размер очередей (spec.limited.limitResponse.queuing.queueLengthLimit), ограниченный пятью запросами. Благодаря этому мы сможем быстрее увидеть ограничение в действии.Используя параметр kubectl --as, мы можем отправить запрос от имени служебной учетной записи podlister-0 на конечную точку для получения списка подов действием LIST.Отправка запроса LIST для получения списка подов от имени другого пользователя:
kubectl -n demo get po --v=8 --as system:serviceaccount:demo:podlister-0 2>&1 | grep -i x-kubernetes-pf
I0118 20:06:06.654095 429 round_trippers.go:452] X-Kubernetes-Pf-Flowschema-Uid: 88c3872e-5bcb-4264-b3f8-df757cedde4f
I0118 20:06:06.654098 429 round_trippers.go:452] X-Kubernetes-Pf-Prioritylevel-Uid: 7f113b41-dbcb-43d0-8b6c-b8ace10e350f
kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 88c3872e-5bcb-4264-b3f8-df757cedde4f
88c3872e-5bcb-4264-b3f8-df757cedde4f restrict-pod-lister
kubectl get prioritylevelconfiguration -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 7f113b41-dbcb-43d0-8b6c-b8ace10e350f
7f113b41-dbcb-43d0-8b6c-b8ace10e350f restrict-pod-lister
Отлично! Нашему запросу сопоставлена схема потока и уровень приоритета restrict-pod-lister, как мы и задумывали.Исследование метрик APFВ этом разделе мы сымитируем входящий трафик API-сервера, развернув кастомный контроллер в пространстве имен demo в виде трех отдельных развертываний (Deployment). В каждом развертывании будет применяться одна из трех служебных учетных записей, созданных нами ранее.Развертывание кастомных контроллеров:
for i in {0..2}; do
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: podlister-$i
namespace: demo
labels:
kubernetes.io/name: podlister-$i
spec:
selector:
matchLabels:
kubernetes.io/name: podlister-$i
template:
metadata:
labels:
kubernetes.io/name: podlister-$i
spec:
serviceAccountName: podlister-$i
containers:
- name: podlister
image: gcr.io/ihcsim/podlister
imagePullPolicy: Always
command:
- /podlister
env:
- name: TARGET_NAMESPACE
value: demo
- name: TICK_INTERVAL
value: 200ms
- name: SHOW_ERRORS_ONLY
value: "true"
resources:
requests:
cpu: 30m
memory: 50Mi
limits:
cpu: 100m
memory: 128Mi
EOF
done
Контроллер использует Go-функцию time.Tick(), чтобы непрерывно отправлять трафик на конечную точку API-сервера, выдающую список подов по запросу LIST. Будем таким образом извлекать все поды в пространстве имен demo. Исходный код доступен здесь.Переходим в консоль Prometheus. Воспользуемся метрикой apiserver_flowcontrol_dispatched_requests_total, чтобы извлечь суммарное количество запросов, соответствующих нашей схеме потока:
apiserver_flowcontrol_dispatched_requests_total{job=”apiserver”,flowSchema=”restrict-pod-lister”}
Суммарное количество запросов, соответствующих нашей схеме потокаТак как мы имеем дело с векторным счетчиком, при суммировании частоты запросов формируется возрастающий тренд:
sum(rate(apiserver_flowcontrol_dispatched_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (flowSchema)
Возрастающий тренд при суммировании частоты передачи запросовМетрика apiserver_flowcontrol_current_inqueue_requests отражает количество запросов, ожидающих в очереди. Значение 0 свидетельствует о том, что в настоящий момент наши очереди пусты. Количество ожидающих в очереди запросов:
apiserver_flowcontrol_current_inqueue_requests{job="apiserver",flowSchema="restrict-pod-lister"}
Куда важнее, что количество отклоненных запросов тоже равно 0, что видно по метрике apiserver_flowcontrol_rejected_requests_total:
apiserver_flowcontrol_rejected_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}
Количество запросов, отклоненных нашей схемой потокаМетрика apiserver_flowcontrol_request_execution_seconds дает представление о том, как долго выполняются запросы из наших очередей:
histogram_quantile(0.99, sum(rate(apiserver_flowcontrol_request_execution_seconds_bucket{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (le,flowSchema))
Задержка P99 времени выполнения запросов (в секундах) из наших очередейВ рассматриваемом тестовом прогоне P99-задержка выполнения запросов из очередей составляет примерно 0,02 секунды.В свою очередь, метрика apiserver_flowcontrol_request_wait_duration_seconds показывает, как долго запросы находятся в очереди:
histogram_quantile(0.99, sum(rate(apiserver_flowcontrol_request_wait_duration_seconds_bucket{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (le,flowSchema))
Задержка P99 времени ожидания запросов (в секундах) в наших очередях
В этом тестовом прогоне P99-задержка ожидания запроса составляет примерно 4,95 миллисекунды. Позднее мы вернемся к этим метрикам, чтобы оценить их воздействие на контекстное время ожидания на стороне клиента.Добавим побольше реплик, чтобы увеличить объем поступающего трафика и запустить формирование очередей.Увеличение числа реплик кастомных контроллеров:
for i in {0..2}; do kubectl -n demo scale deploy/podlister-$i --replicas=10; done
deployment.apps/podlister-0 scaled
deployment.apps/podlister-1 scaled
deployment.apps/podlister-2 scaled
По мере насыщения очередей начинает расти количество отклоненных запросов. В метке reason указывается причина отклонения запросов. Например, очередь заполнена (queue-full) или истекло время ожидания (timeout):
sum(rate(apiserver_flowcontrol_rejected_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (flowSchema,reason)
Также в журнале контроллера появляются записи о регулировании частоты запросов.Журналы кастомных контроллеров с записями о регулировании частоты запросов:
2021/01/23 18:45:05 error while listing pods: the server was unable to return a response in the time allotted, but may still be processing the request (get pods)
I0123 18:45:32.483900 1 request.go:655] Throttling request took 1.065818368s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:45:42.495515 1 request.go:655] Throttling request took 1.205752131s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
2021/01/23 18:46:34 error while listing pods: the server was unable to return a response in the time allotted, but may still be processing the request (get pods)
I0123 18:48:04.217262 1 request.go:655] Throttling request took 1.161568644s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:48:14.291914 1 request.go:655] Throttling request took 2.258553825s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:48:24.405990 1 request.go:655] Throttling request took 1.402613085s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:48:34.485410 1 request.go:655] Throttling request took 3.392645256s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:48:44.620237 1 request.go:655] Throttling request took 3.78360152s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:48:54.842999 1 request.go:655] Throttling request took 4.25852702s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
I0123 18:49:05.018247 1 request.go:655] Throttling request took 6.21121408s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods
2021/01/23 18:49:10 error while listing pods: the server was unable to return a response in the time allotted, but may still be processing the request (get pods)
Задержка P99 времени ожидания запроса (apiserver_flowcontrol_request_wait_duration_seconds) лежит в пределах 4,0–7,5 секунды.Задержка P99 времени выполнения запроса (apiserver_flowcontrol_request_execution_seconds) составляет примерно 0,96 секунды.Если указать в контроллерах контекстное время ожидания (context timeout) меньшее, чем время ожидания в очереди, в журнале начнут появляться ошибки context deadline exceeded (превышен крайний срок контекста).Журнал контроллера с ошибками context deadline exceeded:
kubectl -n demo set env deploy CONTEXT_TIMEOUT=5s --all
deployment.apps/podlister-0 env updated
deployment.apps/podlister-1 env updated
deployment.apps/podlister-2 env updated
kubectl -n demo logs deploy/podlister-0 | grep -i "context deadline exceeded"
...
2021/01/23 19:16:10 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
2021/01/23 19:16:12 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
2021/01/23 19:16:15 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
2021/01/23 19:16:18 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
2021/01/23 19:16:19 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
2021/01/23 19:16:19 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
2021/01/23 19:16:23 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded
Если в журнале контроллера появится слишком много ошибок context deadline exceeded, вы сможете воспользоваться метриками APF и отладочными конечными точками, чтобы определить, не ограничивает ли ваши запросы функция APF.На мой взгляд, это самые полезные метрики, но существует множество других метрик APF, не рассматриваемых в этой статье. Полный список см. в документации APF.Анализ отладочных конечных точекВ дополнение к метрикам APF предлагает несколько отладочных конечных точек, позволяющих детальнее проанализировать обработку очередей и запросов.Конечная точка /debug/api_priority_and_fairness/dump_priority_levels сообщает нам общее число выполняющихся (executing) и ожидающих (waiting) запросов на нашем уровне приоритета.Отладочная конечная точка сообщает состояние запросов на нашем уровне приоритета:
kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests
catch-all, 0, true, false, 0, 0
restrict-pod-lister, 14, false, false, 70, 29
system, 0, true, false, 0, 0
leader-election, 0, true, false, 0, 0
workload-high, 0, true, false, 0, 0
workload-low, 0, false, false, 0, 24
global-default, 0, true, false, 0, 0
exempt, <none>, <none>, <none>, <none>, <none>
В момент запуска этой команды в нашей очереди присутствовали 70 ожидающих (waiting) и 29 выполняющихся (executing) запросов.Конечная точка /debug/api_priority_and_fairness/dump_queues предоставляет дополнительные сведения о состоянии каждой очереди в нашей схеме потока.Отладочная конечная точка сообщает состояние каждой очереди на нашем уровне приоритета:
kubectl get --raw /debug/api_priority_and_fairness/dump_queues
PriorityLevelName, Index, PendingRequests, ExecutingRequests, VirtualStart,
restrict-pod-lister, 0, 0, 0, 0.0000
restrict-pod-lister, 1, 0, 0, 0.0000
restrict-pod-lister, 2, 0, 0, 0.0000
restrict-pod-lister, 3, 0, 0, 0.0000
restrict-pod-lister, 4, 0, 0, 0.0000
restrict-pod-lister, 5, 3, 22, 33577.0739
restrict-pod-lister, 6, 5, 2, 175325.9325
...
restrict-pod-lister, 50, 0, 0, 0.0000
restrict-pod-lister, 51, 0, 0, 0.0000
restrict-pod-lister, 52, 0, 0, 0.0000
restrict-pod-lister, 53, 5, 0, 256070.9451
restrict-pod-lister, 54, 0, 0, 0.0000
...
restrict-pod-lister, 58, 0, 0, 0.0000
restrict-pod-lister, 59, 0, 0, 0.0000
restrict-pod-lister, 60, 0, 0, 0.0000
restrict-pod-lister, 61, 0, 0, 0.0000
restrict-pod-lister, 62, 5, 1, 175266.1469
restrict-pod-lister, 63, 0, 0, 0.0000
В целях удобочитаемости приведенные выше данные обрезаны. Обратите внимание, что отображаемое здесь количество запросов равно значению spec.limited.limitResponse.queuing.queues уровня приоритета.И наконец, конечная точка /debug/api_priority_and_fairness/dump_requests отображает отличительные признаки потока, назначенные каждому запросу, наряду с информацией о субъекте (subject) запроса.Отладочная конечная точка с информацией о наших запросах:
kubectl get --raw /debug/api_priority_and_fairness/dump_requests
PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime
...
restrict-pod-lister, restrict-pod-lister, 0, 0, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:15.931993992Z
restrict-pod-lister, restrict-pod-lister, 0, 1, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:16.696436146Z
restrict-pod-lister, restrict-pod-lister, 0, 2, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:17.193373873Z
restrict-pod-lister, restrict-pod-lister, 0, 3, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:18.056388941Z
restrict-pod-lister, restrict-pod-lister, 0, 4, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:18.710985385Z
restrict-pod-lister, restrict-pod-lister, 5, 0, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.710698732Z
restrict-pod-lister, restrict-pod-lister, 5, 1, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.710848957Z
restrict-pod-lister, restrict-pod-lister, 5, 2, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.71103922Z
restrict-pod-lister, restrict-pod-lister, 5, 3, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.711174595Z
restrict-pod-lister, restrict-pod-lister, 6, 0, system:serviceaccount:demo:podlister-1, 2021-01-23T19:01:18.710762896Z
....
Устранение эффектов регулирования частоты запросовЕсли сократить количество контроллеров до нуля реплик, число отклоненных запросов постепенно будет снижаться по мере восстановления API-сервера после ограничения частоты запросов.Сокращение числа реплик кастомных контроллеров:
for i in {0..2}; do kubectl -n demo scale deploy/podlister-$i --replicas=0; done
deployment.apps/podlister-0 scaled
deployment.apps/podlister-1 scaled
deployment.apps/podlister-2 scaled
sum(rate(apiserver_flowcontrol_rejected_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (flowSchema,reason)
Количество отклоненных запросов сокращается по мере восстановленияЗаключениеВ этой статье мы рассмотрели создание кастомных ресурсов схемы потока (FlowSchema) и конфигурацию уровня приоритета (PriorityLevelConfiguration), позволяющих регулировать трафик, поступающий на API-сервер. Также мы рассмотрели спецификации этих ресурсов.Сымитировав посредством пользовательского контроллера интенсивный трафик в направлении API-сервера, мы смогли проанализировать порядок обработки запросов и формирования очередей с помощью различных метрик и отладочных конечных точек APF.Кроме того, мы рассмотрели сценарий, в котором крайний срок контекста на стороне клиента истекает по причине длительного пребывания запроса в очереди, до того как API-сервер закончит обработку наших запросов.Конфигурация схемы потока допускает отклонение входящего трафика вместо постановки запросов в очередь и регулировку входящего трафика по пространствам имен вместо пользователей — все эти возможности вы можете протестировать самостоятельно по схожему принципу.
Перевод материала подготовлен в преддверии старта курса «Инфраструктурная платформа на основе Kubernetes».
===========
Источник:
habr.com
===========
===========
Автор оригинала: Ivan Sim
===========Похожие новости:
- [Программирование, Разработка под Android, Kotlin] Более безопасный способ сбора потоков данных из пользовательских интерфейсов Android (перевод)
- [JavaScript, Программирование] Полное руководство по созданию классических приложений на JavaScript (перевод)
- [JavaScript, Программирование, Node.JS] Как управлять несколькими потоками в Node JS (перевод)
- [JavaScript, Программирование, Тестирование веб-сервисов, Машинное обучение] В закладки: репозитории с книгами, шпаргалками, ресурсами по дизайну и не только (перевод)
- [Программирование, Java] Создание самодостаточных исполняемых JAR (перевод)
- [Микросервисы] Лучшие фреймворки для микросервисов (перевод)
- [DevOps, Kubernetes] Пять стратегий эффективной реализации Kubernetes в организации (перевод)
- [Системное администрирование, Серверное администрирование, DevOps, Kubernetes] Контролируем удаление с финализаторами (перевод)
- [Программирование, C++] Повышение производительности дебажных билдов в два-три раза (перевод)
- [Программирование, IT-инфраструктура, Управление проектами, Kubernetes] Интервью с Марселем Ибраевым о распиле монолита или «Успех распила монолита – грамотный менеджмент»
Теги для поиска: #_kubernetes, #_kubernetes, #_k8s, #_throttling, #_software_engineering, #_blog_kompanii_otus (
Блог компании OTUS
), #_kubernetes
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 06:59
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Эта статья посвящена новой функции Kubernetes: API Priority and Fairness (APF). Я хочу поделиться своими находками и рассказать, как определять политики для приоритизации и ограничения входящих запросов на API-сервер Kubernetes. Также мы рассмотрим некоторые метрики и отладочные конечные точки, которые позволяют оценивать влияние APF на контроллеры.Бета-версия функции APF включена по умолчанию, начиная с версии Kubernetes 1.20. В более ранних версиях Kubernetes она включается через функциональный шлюз APIPriorityAndFairness.Что такое APF?До появления функции APF на API-сервере для ограничения количества поступающих запросов применялись параметры командной строки --max-requests-inflight и --max-mutating-requests-inflight. Единственное отличие заключается в том, что при использовании этих параметров не разграничиваются изменяющие (mutating) запросы и остальные. Например, эти параметры не гарантируют, что низкоприоритетный трафик не «задушит» критически важные вызовы (такой сценарий описывается в этом примере проблемы).APF предлагает механизм управления потоком, чтобы API-сервер мог ограничивать запросы по принципу равнодоступности (fairness). Владельцы платформы могут задавать политики уровня API с целью классификации входящих запросов по различным приоритетам и потокам. Управление запросами посредством потоков и приоритетовВсе входящие запросы оцениваются на соответствие набору схем потоков. Для каждого запроса подбирается одна конкретная схема потока, которая назначает запросу уровень приоритета. Следовательно, когда ограничиваются запросы с определенным уровнем приоритета, это никак не влияет на запросы с другими уровнями приоритета.Чтобы соблюдать принцип равнодоступности среди запросов с одним уровнем приоритета, соответствующая им схема потока связывает запросы с потоками — запросам из одного источника назначается одинаковый отличительный признак потока (flow distinguisher).В потоках запросов, которые невозможно выполнить прямо сейчас, организуются очереди по принципу перемешивающего шардинга (shuffle sharding), который часто применяется для изоляции рабочих нагрузок и повышения отказоустойчивости. Когда появляются достаточные ресурсы, система выводит отсортированные по потокам запросы из очередей по алгоритму организации равноправных очередей (fair queueing).Общие сведения о FlowSchema и PriorityLevelConfigurationИспользуемые в этом разделе команды тестировались на кластере Kubernetes 1.19, созданном с помощью kind 0.9.0. Для повышения удобочитаемости и фильтрации выходных данных YAML применялся обработчик yq 4.3.1.Prometheus Operator развернут посредством kube-prometheus 0.7. Способ организации доступа к консоли Prometheus через переадресацию портов описан в файле README компонента kube-prometheus.Прежде чем создать собственные ресурсы FlowSchema и PriorityLevelConfiguration, сначала рассмотрим ключевые концепции на основе стандартных ресурсов.Список схем потоков по умолчанию: kubectl get flowschema
NAME PRIORITYLEVEL MATCHINGPRECEDENCE DISTINGUISHERMETHOD AGE MISSINGPL exempt exempt 1 <none> 13m False system-leader-election leader-election 100 ByUser 13m False workload-leader-election leader-election 200 ByUser 13m False system-nodes system 500 ByUser 13m False kube-controller-manager workload-high 800 ByNamespace 13m False kube-scheduler workload-high 800 ByNamespace 13m False kube-system-service-accounts workload-high 900 ByNamespace 13m False service-accounts workload-low 9000 ByUser 13m False global-default global-default 9900 ByUser 13m False catch-all catch-all 10000 ByUser 13m False kubectl get flowschema system-leader-election -oyaml | yq e '.spec' -
distinguisherMethod: type: ByUser matchingPrecedence: 100 priorityLevelConfiguration: name: leader-election rules: - resourceRules: - apiGroups: - "" namespaces: - kube-system resources: - endpoints - configmaps verbs: - get - create - update - apiGroups: - coordination.k8s.io namespaces: - '*' resources: - leases verbs: - get - create - update subjects: - kind: User user: name: system:kube-controller-manager - kind: User user: name: system:kube-scheduler - kind: ServiceAccount serviceAccount: name: '*' namespace: kube-system kubectl get prioritylevelconfigurations leader-election -oyaml | yq e '.spec' -
limited: assuredConcurrencyShares: 10 limitResponse: queuing: handSize: 4 queueLengthLimit: 50 queues: 16 type: Queue type: Limited Ограничения параллелизма для всех уровней приоритетаЗначение limited.assuredConcurrencyShares связано с метрикой apiserver_flowcontrol_request_concurrency_limit таким образом, что увеличение доли параллелизма для уровня приоритета приводит к росту предельного значения параллелизма. Так как суммарное ограничение параллелизма API-сервера распределяется по всем уровням приоритета, повышение ограничения одного уровня приоритета сокращает ограничение для других.Параметр limited.limitResponse определяет стратегию обработки запросов, которые невозможно исполнить прямо сейчас. Параметр limit.limitResponse.type допускает два значения:· Queue — запросы добавляются в очередь;· Reject — запросы отклоняются с ошибкой HTTP 429.Тип реагирования Queue позволяет задать конфигурацию постановки в очередь с помощью параметров limited.limitResponse.queuing. В документации и предложении по реализации функции APF более подробно описывается эффект от изменения параметров queues, queueLengthLimit и handSize.В следующем разделе мы научимся определять, какая схема сопоставляется нашим запросам.Определение соответствующей схемы потокаСамый быстрый способ определить, какая схема потока соответствует нашему запросу, — проанализировать два заголовка, поступающих от API-сервера в ответах APF: X-Kubernetes-PF-FlowSchema-UID и X-Kubernetes-PF-PriorityLevel-UID. В них содержатся UID-идентификаторы соответствующих схем потоков и конфигурации уровня приоритетов.Определение соответствующей схемы потока и уровня приоритета: kubectl -n kube-system get po --v=8 2>&1 | grep -i x-kubernetes-pf
I0115 21:04:25.044262 65517 round_trippers.go:452] X-Kubernetes-Pf-Flowschema-Uid: c36148b8-623a-45a8-9c63-7158262f7727 I0115 21:04:25.044267 65517 round_trippers.go:452] X-Kubernetes-Pf-Prioritylevel-Uid: 0aab41a9-e078-4671-936b-937d6d5e8601 kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep c36148b8-623a-45a8-9c63-7158262f7727 c36148b8-623a-45a8-9c63-7158262f7727 exempt kubectl get prioritylevelconfiguration -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 0aab41a9-e078-4671-936b-937d6d5e8601 0aab41a9-e078-4671-936b-937d6d5e8601 exempt kubectl get flowschema exempt -oyaml | yq e '.spec' -
matchingPrecedence: 1 priorityLevelConfiguration: name: exempt rules: - nonResourceRules: - nonResourceURLs: - '*' verbs: - '*' resourceRules: - apiGroups: - '*' clusterScope: true namespaces: - '*' resources: - '*' verbs: - '*' subjects: - group: name: system:masters kind: Group # kubectl get prioritylevelconfiguration exempt -oyaml | yq e '.spec' - type: Exempt cat <<EOF | kubectl apply -f -
apiVersion: v1 kind: Namespace metadata: name: demo EOF for i in {0..2}; do cat <<EOF | kubectl auth reconcile -f - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: podlister namespace: demo rules: - apiGroups: [""] resources: ["pods"] verbs: ["list", "get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: podlister namespace: demo subjects: - apiGroup: "" kind: ServiceAccount name: podlister-$i roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: podlister EOF done for i in {0..2}; do cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: podlister-$i namespace: demo labels: kubernetes.io/name: podlister-$i EOF done cat <<EOF | kubectl apply -f -
apiVersion: flowcontrol.apiserver.k8s.io/v1alpha1 kind: FlowSchema metadata: name: restrict-pod-lister spec: priorityLevelConfiguration: name: restrict-pod-lister distinguisherMethod: type: ByUser rules: - resourceRules: - apiGroups: [""] namespaces: ["demo"] resources: ["pods"] verbs: ["list", "get"] subjects: - kind: ServiceAccount serviceAccount: name: podlister-0 namespace: demo - kind: ServiceAccount serviceAccount: name: podlister-1 namespace: demo - kind: ServiceAccount serviceAccount: name: podlister-2 namespace: demo --- apiVersion: flowcontrol.apiserver.k8s.io/v1alpha1 kind: PriorityLevelConfiguration metadata: name: restrict-pod-lister spec: type: Limited limited: assuredConcurrencyShares: 10 limitResponse: queuing: queueLengthLimit: 5 type: Queue EOF kubectl -n demo get po --v=8 --as system:serviceaccount:demo:podlister-0 2>&1 | grep -i x-kubernetes-pf
I0118 20:06:06.654095 429 round_trippers.go:452] X-Kubernetes-Pf-Flowschema-Uid: 88c3872e-5bcb-4264-b3f8-df757cedde4f I0118 20:06:06.654098 429 round_trippers.go:452] X-Kubernetes-Pf-Prioritylevel-Uid: 7f113b41-dbcb-43d0-8b6c-b8ace10e350f kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 88c3872e-5bcb-4264-b3f8-df757cedde4f 88c3872e-5bcb-4264-b3f8-df757cedde4f restrict-pod-lister kubectl get prioritylevelconfiguration -o custom-columns="uid:{metadata.uid},name:{metadata.name}" | grep 7f113b41-dbcb-43d0-8b6c-b8ace10e350f 7f113b41-dbcb-43d0-8b6c-b8ace10e350f restrict-pod-lister for i in {0..2}; do
cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: podlister-$i namespace: demo labels: kubernetes.io/name: podlister-$i spec: selector: matchLabels: kubernetes.io/name: podlister-$i template: metadata: labels: kubernetes.io/name: podlister-$i spec: serviceAccountName: podlister-$i containers: - name: podlister image: gcr.io/ihcsim/podlister imagePullPolicy: Always command: - /podlister env: - name: TARGET_NAMESPACE value: demo - name: TICK_INTERVAL value: 200ms - name: SHOW_ERRORS_ONLY value: "true" resources: requests: cpu: 30m memory: 50Mi limits: cpu: 100m memory: 128Mi EOF done apiserver_flowcontrol_dispatched_requests_total{job=”apiserver”,flowSchema=”restrict-pod-lister”}
Суммарное количество запросов, соответствующих нашей схеме потокаТак как мы имеем дело с векторным счетчиком, при суммировании частоты запросов формируется возрастающий тренд: sum(rate(apiserver_flowcontrol_dispatched_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (flowSchema)
Возрастающий тренд при суммировании частоты передачи запросовМетрика apiserver_flowcontrol_current_inqueue_requests отражает количество запросов, ожидающих в очереди. Значение 0 свидетельствует о том, что в настоящий момент наши очереди пусты. Количество ожидающих в очереди запросов: apiserver_flowcontrol_current_inqueue_requests{job="apiserver",flowSchema="restrict-pod-lister"}
Куда важнее, что количество отклоненных запросов тоже равно 0, что видно по метрике apiserver_flowcontrol_rejected_requests_total: apiserver_flowcontrol_rejected_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}
Количество запросов, отклоненных нашей схемой потокаМетрика apiserver_flowcontrol_request_execution_seconds дает представление о том, как долго выполняются запросы из наших очередей: histogram_quantile(0.99, sum(rate(apiserver_flowcontrol_request_execution_seconds_bucket{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (le,flowSchema))
Задержка P99 времени выполнения запросов (в секундах) из наших очередейВ рассматриваемом тестовом прогоне P99-задержка выполнения запросов из очередей составляет примерно 0,02 секунды.В свою очередь, метрика apiserver_flowcontrol_request_wait_duration_seconds показывает, как долго запросы находятся в очереди: histogram_quantile(0.99, sum(rate(apiserver_flowcontrol_request_wait_duration_seconds_bucket{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (le,flowSchema))
В этом тестовом прогоне P99-задержка ожидания запроса составляет примерно 4,95 миллисекунды. Позднее мы вернемся к этим метрикам, чтобы оценить их воздействие на контекстное время ожидания на стороне клиента.Добавим побольше реплик, чтобы увеличить объем поступающего трафика и запустить формирование очередей.Увеличение числа реплик кастомных контроллеров: for i in {0..2}; do kubectl -n demo scale deploy/podlister-$i --replicas=10; done
deployment.apps/podlister-0 scaled deployment.apps/podlister-1 scaled deployment.apps/podlister-2 scaled sum(rate(apiserver_flowcontrol_rejected_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (flowSchema,reason)
Также в журнале контроллера появляются записи о регулировании частоты запросов.Журналы кастомных контроллеров с записями о регулировании частоты запросов: 2021/01/23 18:45:05 error while listing pods: the server was unable to return a response in the time allotted, but may still be processing the request (get pods)
I0123 18:45:32.483900 1 request.go:655] Throttling request took 1.065818368s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:45:42.495515 1 request.go:655] Throttling request took 1.205752131s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods 2021/01/23 18:46:34 error while listing pods: the server was unable to return a response in the time allotted, but may still be processing the request (get pods) I0123 18:48:04.217262 1 request.go:655] Throttling request took 1.161568644s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:48:14.291914 1 request.go:655] Throttling request took 2.258553825s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:48:24.405990 1 request.go:655] Throttling request took 1.402613085s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:48:34.485410 1 request.go:655] Throttling request took 3.392645256s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:48:44.620237 1 request.go:655] Throttling request took 3.78360152s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:48:54.842999 1 request.go:655] Throttling request took 4.25852702s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods I0123 18:49:05.018247 1 request.go:655] Throttling request took 6.21121408s, request: GET:https://10.96.0.1:443/api/v1/namespaces/demo/pods 2021/01/23 18:49:10 error while listing pods: the server was unable to return a response in the time allotted, but may still be processing the request (get pods) kubectl -n demo set env deploy CONTEXT_TIMEOUT=5s --all
deployment.apps/podlister-0 env updated deployment.apps/podlister-1 env updated deployment.apps/podlister-2 env updated kubectl -n demo logs deploy/podlister-0 | grep -i "context deadline exceeded" ... 2021/01/23 19:16:10 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded 2021/01/23 19:16:12 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded 2021/01/23 19:16:15 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded 2021/01/23 19:16:18 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded 2021/01/23 19:16:19 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded 2021/01/23 19:16:19 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded 2021/01/23 19:16:23 error while listing pods: Get "https://10.96.0.1:443/api/v1/namespaces/demo/pods": context deadline exceeded kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests catch-all, 0, true, false, 0, 0 restrict-pod-lister, 14, false, false, 70, 29 system, 0, true, false, 0, 0 leader-election, 0, true, false, 0, 0 workload-high, 0, true, false, 0, 0 workload-low, 0, false, false, 0, 24 global-default, 0, true, false, 0, 0 exempt, <none>, <none>, <none>, <none>, <none> kubectl get --raw /debug/api_priority_and_fairness/dump_queues
PriorityLevelName, Index, PendingRequests, ExecutingRequests, VirtualStart, restrict-pod-lister, 0, 0, 0, 0.0000 restrict-pod-lister, 1, 0, 0, 0.0000 restrict-pod-lister, 2, 0, 0, 0.0000 restrict-pod-lister, 3, 0, 0, 0.0000 restrict-pod-lister, 4, 0, 0, 0.0000 restrict-pod-lister, 5, 3, 22, 33577.0739 restrict-pod-lister, 6, 5, 2, 175325.9325 ... restrict-pod-lister, 50, 0, 0, 0.0000 restrict-pod-lister, 51, 0, 0, 0.0000 restrict-pod-lister, 52, 0, 0, 0.0000 restrict-pod-lister, 53, 5, 0, 256070.9451 restrict-pod-lister, 54, 0, 0, 0.0000 ... restrict-pod-lister, 58, 0, 0, 0.0000 restrict-pod-lister, 59, 0, 0, 0.0000 restrict-pod-lister, 60, 0, 0, 0.0000 restrict-pod-lister, 61, 0, 0, 0.0000 restrict-pod-lister, 62, 5, 1, 175266.1469 restrict-pod-lister, 63, 0, 0, 0.0000 kubectl get --raw /debug/api_priority_and_fairness/dump_requests
PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime ... restrict-pod-lister, restrict-pod-lister, 0, 0, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:15.931993992Z restrict-pod-lister, restrict-pod-lister, 0, 1, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:16.696436146Z restrict-pod-lister, restrict-pod-lister, 0, 2, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:17.193373873Z restrict-pod-lister, restrict-pod-lister, 0, 3, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:18.056388941Z restrict-pod-lister, restrict-pod-lister, 0, 4, system:serviceaccount:demo:podlister-2, 2021-01-23T19:01:18.710985385Z restrict-pod-lister, restrict-pod-lister, 5, 0, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.710698732Z restrict-pod-lister, restrict-pod-lister, 5, 1, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.710848957Z restrict-pod-lister, restrict-pod-lister, 5, 2, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.71103922Z restrict-pod-lister, restrict-pod-lister, 5, 3, system:serviceaccount:demo:podlister-0, 2021-01-23T19:01:18.711174595Z restrict-pod-lister, restrict-pod-lister, 6, 0, system:serviceaccount:demo:podlister-1, 2021-01-23T19:01:18.710762896Z .... for i in {0..2}; do kubectl -n demo scale deploy/podlister-$i --replicas=0; done
deployment.apps/podlister-0 scaled deployment.apps/podlister-1 scaled deployment.apps/podlister-2 scaled sum(rate(apiserver_flowcontrol_rejected_requests_total{job="apiserver",flowSchema="restrict-pod-lister"}[15m])) by (flowSchema,reason)
Количество отклоненных запросов сокращается по мере восстановленияЗаключениеВ этой статье мы рассмотрели создание кастомных ресурсов схемы потока (FlowSchema) и конфигурацию уровня приоритета (PriorityLevelConfiguration), позволяющих регулировать трафик, поступающий на API-сервер. Также мы рассмотрели спецификации этих ресурсов.Сымитировав посредством пользовательского контроллера интенсивный трафик в направлении API-сервера, мы смогли проанализировать порядок обработки запросов и формирования очередей с помощью различных метрик и отладочных конечных точек APF.Кроме того, мы рассмотрели сценарий, в котором крайний срок контекста на стороне клиента истекает по причине длительного пребывания запроса в очереди, до того как API-сервер закончит обработку наших запросов.Конфигурация схемы потока допускает отклонение входящего трафика вместо постановки запросов в очередь и регулировку входящего трафика по пространствам имен вместо пользователей — все эти возможности вы можете протестировать самостоятельно по схожему принципу. Перевод материала подготовлен в преддверии старта курса «Инфраструктурная платформа на основе Kubernetes».
=========== Источник: habr.com =========== =========== Автор оригинала: Ivan Sim ===========Похожие новости:
Блог компании OTUS ), #_kubernetes |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 06:59
Часовой пояс: UTC + 5