PodDisruptionBudget: защита от drain
Чем контролируемое выселение отличается от аварийного, как minAvailable и maxUnavailable останавливают kubectl drain.
Контролируемые и неконтролируемые выселения
Pod - наименьшая единица, которую запускает Kubernetes. Pod могут исчезнуть по двум разным причинам.
Неконтролируемое выселение (involuntary). Узел отключился, OOM-killer убил процесс, узел потерял связь с кластером. Здесь Kubernetes ничего не гарантирует.
Контролируемое выселение (voluntary). Кто-то осознанно убирает Pod.
Например, kubectl drain выводит узел на обслуживание и выселяет с
него все Pod. Такие операции идут через API eviction - запрос к
Kubernetes на удаление Pod.
PDB работает только на этой половине. Упавший узел не спрашивает разрешения, и никакой бюджет его не остановит.
Что делает PodDisruptionBudget
PodDisruptionBudget (PDB) это объект, который задаёт минимум живых Pod при контролируемых выселениях. Он говорит Kubernetes: выселяй Pod так, чтобы в состоянии Ready всегда оставалось не меньше заданного числа.
Ready это состояние Pod, в котором он готов принимать трафик. Если
выселение нарушит бюджет, API возвращает ошибку, и kubectl drain
ждёт, повторяя попытку.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: api
Этот PDB требует минимум 2 Pod с меткой app: api в состоянии Ready.
Если их три, выселить можно одного. Если их два, выселение блокируется.
minAvailable: 2
Ready ●●● → выселить можно 1
Ready ●● → drain заблокирован
selector выбирает Pod по меткам. Он должен совпадать с метками,
которые проставляет Deployment. Если selector не совпадает ни с одним
Pod, PDB существует, но ничего не защищает.
minAvailable и maxUnavailable
Бюджет задают одним из двух полей.
spec:
minAvailable: 2 # минимум 2 Pod в Ready
spec:
maxUnavailable: 1 # максимум 1 под не Ready одновременно
Значение задают числом или процентом, например "50%". В одном PDB
используют либо minAvailable, либо maxUnavailable, но не оба сразу.
Если minAvailable равен числу реплик, выселить нельзя ни один Pod.
Сервис «защищён», но обслуживание узла невозможно. Для трёх реплик
ставят minAvailable: 2, тогда можно выселить один Pod из трёх.
Как читать состояние
$ kubectl get pdb api-pdb
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
api-pdb 2 N/A 1 30s
ALLOWED DISRUPTIONS показывает, сколько Pod можно выселить прямо сейчас. При
трёх Ready и minAvailable: 2 это число равно 1. Если оно 0,
выселение заблокировано.
$ kubectl describe pdb api-pdb
...
Status:
Allowed disruptions: 1
Current: 3
Desired: 2
Expected: 3
Current healthy показывает, сколько Pod сейчас в Ready. Desired healthy показывает, сколько требует бюджет.
Как PDB ведёт себя при drain
Для kubectl drain нужны права на ноды, поэтому запускает его обычно
администратор кластера. drain сначала помечает узел как закрытый для
новых Pod (cordon), затем выселяет существующие. PDB заставит drain
застрять на последнем разрешённом Pod. После обслуживания узел
возвращают в работу командой kubectl uncordon <node>, иначе новые Pod
не смогут на него попасть. Вот как это выглядит:
$ kubectl drain node-2 --ignore-daemonsets --delete-emptydir-data
node/node-2 cordoned
evicting pod prod/api-7d4f-aaa
error when evicting pods/"api-7d4f-aaa" -n "prod"
(will retry after 5s): Cannot evict pod as it would violate the
pod's disruption budget.
evicting pod prod/api-7d4f-aaa
... (зависает в этом цикле)
Домашка
Теорию закрепляет задание на своём кластере: 1 шаг с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-pdb # развернуть стартовое состояние
./run.sh verify k8s-pdb # проверить текущий шаг
Коротко
- PDB ограничивает только контролируемые выселения через API eviction. От падения узла он не спасает.
- Бюджет задают либо
minAvailable, либоmaxUnavailable, числом или процентом. Оба поля сразу использовать нельзя. selectorдолжен совпадать с метками Pod, иначе PDB не защищает ничего.ALLOWED DISRUPTIONSвkubectl get pdbпоказывает, сколько Pod можно убрать прямо сейчас. Ноль означает, что drain встанет.minAvailable, равный числу реплик, делает обслуживание узла невозможным.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс