Планирование, приоритизация и вытеснение
В Kubernetes под планированием понимается поиск подходящих узлов, на которых kubelet сможет запустить Pod'ы. Приоритизация — процесс завершения работы Pod'ов с более низким приоритетом и высвобождения места для Pod'ов с более высоким приоритетом. Вытеснение — это проактивное завершение работы одного или нескольких Pod'ов на узлах с дефицитом ресурсов.
В Kubernetes под планированием понимается поиск узлов, подходящих для размещения Pod'ов так, чтобы kubelet
мог их запустить. Приоритизация (упреждение; preemption) — процесс завершения работы Pod'ов
с более низким приоритетом с освобождением места для Pod'ов с более высоким приоритетом. Вытеснение (eviction) — завершение работы одного или нескольких Pod'ов на узлах.
Планирование
Завершение работы Pod'ов
Нарушение работы Pod'ов (Pod disruption) — процесс,
в ходе которого происходит плановое или внеплановое (принудительное) завершение работы Pod'ов на узлах.
Плановое завершение работы Pod'ов инициируется владельцами приложений или администраторами
кластера. Внеплановое завершение работы обычно вызвано непредвиденными обстоятельствами различной природы,
например, с недостатком ресурсов на узлах или случайными удалениями.
1 - Вытеснение, инициированное через API
Вытеснение, инициированное через API — процесс, при котором с помощью Eviction API
создается объект Eviction
, который запускает корректное завершение работы Pod'а.
Вытеснение можно инициировать напрямую с помощью Eviction API или программно,
используя клиент API-сервера
(например, командой kubectl drain
). В результате будет создан объект Eviction
,
который запустит процесс контролируемого завершения работы Pod'а.
Вытеснения, инициированные через API, учитывают настройки PodDisruptionBudget
и terminationGracePeriodSeconds
.
Создание с помощью API объекта Eviction для Pod'а аналогично выполнению
операции DELETE
для этого Pod'а, которая контролируется политикой.
Вызов API Eviction
Для доступа к API Kubernetes и создания объекта Eviction
можно воспользоваться клиентской библиотекой. Необходимая операция оформляется в виде POST-запроса (см. пример ниже):
Примечание: Вытеснение с версией policy/v1
доступно начиная с v1.22. Для более ранних релизов используйте policy/v1beta1
.
{
"apiVersion": "policy/v1",
"kind": "Eviction",
"metadata": {
"name": "quux",
"namespace": "default"
}
}
Примечание: Признана устаревшей в v1.22; заменена на policy/v1
.
{
"apiVersion": "policy/v1beta1",
"kind": "Eviction",
"metadata": {
"name": "quux",
"namespace": "default"
}
}
Также можно попытаться выполнить операцию вытеснения,
обратившись к API с помощью curl
или wget
, как показано в следующем примере:
curl -v -H 'Content-type: application/json' https://your-cluster-api-endpoint.example/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json
Как работает вытеснение, инициированное через API
При вытеснении, инициированном через API, сервер API выполняет admission-проверки
и отвечает одним из следующих способов:
200 OK
: вытеснение разрешено, подресурс Eviction
создан,
Pod удален (аналогично отправке запроса DELETE
на URL Pod'а).
429 Too Many Requests
: вытеснение в данный момент не разрешено из-за настроек
PodDisruptionBudget.
Попытку вытеснения можно повторить позже. Такой ответ также может быть вызван
работой механизма по ограничению частоты запросов к API.
500 Internal Server Error
: вытесение запрещено из-за неправильной конфигурации;
например, несколько PodDisruptionBudget'ов могут ссылаться на один и тот же Pod.
Если Pod, предназначенный для вытеснения, не является частью рабочей нагрузки
с настроенным PodDisruptionBudget'ом, сервер API всегда возвращает 200 OK
и
разрешает вытеснение.
В случае, если вытеснение разрешено, процесс удаления Pod'а выглядит следующим образом:
- К ресурсу
Pod
на сервере API добавляется метка времени удаления,
после чего сервер API считает ресурс Pod завершенным (terminated). Ресурс Pod
также помечается
настроенным grace-периодом.
- kubelet на узле, где запущен
локальный Pod, замечает, что ресурс
Pod
помечен на удаление, и приступает к
корректному завершению работы локального Pod'а.
- Пока kubelet завершает работу Pod'а, управляющий слой удаляет Pod из объектов
Endpoint и
EndpointSlice.
В результате контроллеры больше не рассматривают Pod как валидный объект.
- После истечения периода корректного завершения работы (grace-периода) kubelet
принудительно завершает работу локального Pod'а.
- kubelet передает API-серверу информацию о необходимости удалить ресурс
Pod
.
- Сервер API удаляет ресурс
Pod
.
Зависшие вытеснения
В некоторых ситуациях сбой приводит к тому, что API Eviction начинает возвращать
исключительно ответы 429
или 500
. Такое может случиться, если, например,
за создание Pod'ов для приложения отвечает ReplicaSet, однако новые Pod'ы не
переходят в состояние Ready
. Подобное поведение также может наблюдаться в случаях,
когда у последнего вытесненного Pod'а слишком долгий период завершения работы (grace-период).
Одно из следующих решений может помочь решить проблему:
- Прервите или приостановите автоматическую операцию, вызвавшую сбой.
Перед повторным запуском операции внимательно изучите сбойное приложение.
- Подождите некоторое время, затем напрямую удалите Pod из управляющего слоя
кластера вместо того, чтобы пытаться удалить его с помощью Eviction API.
Что дальше