Задача 1. Сколько endpoints у Service
Deployment на три реплики, Service поверх него — сколько адресов окажется в списке endpoints? Разбираем связь селектора, готовности подов и EndpointSlice.
Знать, что такое Deployment, и понимать, что произойдёт при его обновлении под нагрузкой, — разные вещи. Разрыв между ними обнаруживается в проде: под удалён, а трафик в него ещё идёт; probe настроен, но не спасает; запрос уходит не туда, куда ожидалось.
Эта серия — двадцать задач про такие места. Формат каждой одинаковый:
Читать можно по порядку или выборочно — задачи независимы.
Об источнике вдохновения. Формат подсмотрен у серии задач Daniele Polencic (learnk8s) — 20 концепций Kubernetes, разобранных через головоломки. Тексты, сценарии и разборы здесь мои собственные: это не перевод и не пересказ оригинала, а самостоятельная серия на те же фундаментальные темы. За оригиналами — по ссылке к автору.
Для тех, кто уже работает с Kubernetes и хочет закрыть пробелы в понимании механики. Базовый kubectl и знакомство с Pod, Deployment, Service подразумеваются.
Deployment на три реплики, Service поверх него — сколько адресов окажется в списке endpoints? Разбираем связь селектора, готовности подов и EndpointSlice.
При удалении пода часть запросов падает с ошибкой, хотя приложение корректно обрабатывает SIGTERM. Разбираем, почему удаление из endpoints и остановка контейнера идут параллельно, а не последовательно.
Два пода с одинаковым потреблением, но разными манифестами — при нехватке памяти на ноде выживет один. Разбираем, чем requests отличаются от limits и как из них получаются классы Guaranteed, Burstable и BestEffort.
Одна команда выкатила релиз — легли сервисы соседей, хотя namespace'ы разные. Разбираем, что namespace изолирует, а что нет, и какой минимум ограничений закрывает основные способы навредить соседям.
JVM настроена на 1 ГиБ кучи, лимит контейнера 1.5 ГиБ, а под всё равно ловит OOMKilled. Разбираем, что входит в память контейнера помимо кучи и почему page cache тоже считается.
Под обращается к ClusterIP — но такого адреса нет ни на одном интерфейсе в кластере. Разбираем, что ClusterIP это правило DNAT, а не адрес, и чем iptables отличается от IPVS.
Под тормозящей базы данных начинается лавина перезапусков, и становится только хуже. Разбираем разницу между liveness, readiness и startup, и почему liveness на зависимость от внешнего сервиса — опасная ошибка.
Три реплики, а сервис лёг при обновлении кластера. Разбираем, почему количество реплик не равно отказоустойчивости и как связаны PodDisruptionBudget, anti-affinity и topology spread.
Кластер начинает тормозить на всех операциях kubectl, хотя ноды свободны. Разбираем лимит объекта в 1.5 МиБ, квоту базы в 2 ГиБ, историю ревизий и почему ConfigMap в цикле роняет control plane.
HPA настроен на 70% CPU, поды загружены под завязку, но реплики не добавляются. Разбираем, что проценты считаются от requests, а не от лимитов, и что бывает, когда requests не заданы.
Job завершает работу, но под навсегда остаётся в Running из-за sidecar'а. Разбираем порядок запуска контейнеров, старую проблему завершения sidecar'ов и нативные sidecar-контейнеры.
Выкатка новой версии останавливается на половине и висит часами, откат не помогает. Разбираем, как считаются maxSurge и maxUnavailable, при чём тут readiness и почему progressDeadlineSeconds важнее, чем кажется.
ConfigMap обновили, но приложение работает по-старому. Разбираем, почему переменные окружения не обновляются никогда, тома обновляются с задержкой, а subPath не обновляется вовсе.
Масштабировали сервис с 3 подов до 10, но нагрузка осталась на прежних трёх. Разбираем, почему балансировка происходит на уровне соединений, и что с этим делать для gRPC и HTTP/2.
Обращение к внешнему API из пода отрабатывает заметно дольше, чем с ноды. Разбираем search-домены, параметр ndots:5 и почему один внешний запрос превращается в пять DNS-запросов.
Ноды свободны, а под не запускается. Разбираем, как планировщик фильтрует и оценивает ноды, чем taint отличается от affinity и почему свободная память ноды не то же самое, что доступная.
Уменьшили StatefulSet с 5 реплик до 3, вернули обратно — и получили старые данные. Разбираем, почему PVC живут дольше подов, чем StatefulSet отличается от Deployment и как reclaim policy решает судьбу данных.
Под ходит в API и получает Forbidden, хотя роль создана. Разбираем разницу Role и ClusterRole, зачем нужен RoleBinding, почему у каждого пода есть ServiceAccount и как право на создание подов равно правам администратора.
На ноде кончается место на диске, и поды начинают выселяться — включая те, что ничего не писали. Разбираем пороги kubelet, разницу между вытеснением и OOMKill и почему логи в файл опасны.
После обновления кластера пайплайн падает на манифестах, которые работали годами. Разбираем разницу между deprecated и removed, правило skew между компонентами и порядок безопасного обновления.
Введите ключевые слова для поиска статей