Планирование и масштабирование
Что это такое
Планирование — это решение кластера, на каком узле запускать каждый pod; масштабирование — изменение кластером объёма работы в ответ на спрос. И то и другое управляется ресурсами, которые вы объявляете нужными pod’у. Pod, запрашивающий четверть CPU и 256MB памяти, сообщает планировщику, что он обязан зарезервировать, и каждое последующее решение о масштабировании наследует это утверждение — верное или нет.
Почему это важно
Объявления ресурсов — самая часто запущенная часть манифеста и самая значимая. Завысьте requests — и узлы заполнятся простаивающими pod’ами, так что кластер обойдётся дороже, чем оправдывает нагрузка. Занизьте — и pod’ы набьются на узлы, которые на деле их не вмещают, и под давлением ядро начнёт убивать процессы. Разница между кластером, который ведёт себя предсказуемо, и тем, что загадочно вытесняет pod’ы, обычно в двух числах на контейнер, выбранных из измерения, а не из удобства.
Ключевые идеи
Requests резервируют ёмкость, limits её ограничивают
Request — это то, что планировщик гарантирует pod’у; limit — потолок, который контейнер не может превысить. CPU сверх limit замедляется троттлингом, память сверх limit приводит к убийству процесса. Равные requests и limits дают предсказуемую производительность ценой упругости; requests далеко ниже limits приглашают переподписку и вытеснение. Обе крайности защитимы; догадка — нет.
requests: cpu 250m, memory 256Mi -> размещается с этим резервом
limits: cpu 1000m, memory 512Mi -> может разгоняться, убивается при превышении памяти
Качество обслуживания следует из соотношения requests и limits
Pod’ы, у которых requests равны limits, вытесняются последними; pod’ы вовсе без requests — первыми. Этот порядок и есть правило кластера выбирать жертвы под давлением, и потому критичную нагрузку нельзя оставлять с незаданными полями ресурсов.
Ограничения сужают поиск ещё до учёта ресурсов
Node selectors, affinity, taints и tolerations решают, какие узлы вообще подходят — по метке, зоне или особому назначению. И только затем планировщик взвешивает соответствие ресурсам и прочие оценки. Поэтому pod, который не планируется, — это сначала вопрос об ограничениях и лишь потом о ёмкости, а события pod’а говорят, что именно ему отказало.
Кластеры масштабируются по двум осям
Pod’ы масштабируются по спросу через контроллер, читающий метрику; узлы — по pod’ам, которые не помещаются. Настроить второе без первого — значит оставить ёмкость, которая никогда не используется; первое без второго — оставить pod’ы навсегда в состоянии pending. Обе стороны сокращения нуждаются в окне стабилизации, потому что ужатие на мимолётном затишье заставляет кластер колебаться.
Масштабируйтесь по сигналу, который приходит раньше нагрузки
CPU реагирует после того, как работа встала в очередь; глубина очереди, частота запросов или собственная метрика могут реагировать раньше. Что бы вы ни выбрали, расширяйтесь охотно, а сокращайтесь осторожно, и ограничивайте скорость изменения, чтобы всплеск не перегрузил зависимости, которые нагрузка вот-вот вызовет.
Практика
Выведите requests из измерения
Запустите рабочую нагрузку, понаблюдайте её CPU и память под реалистичной нагрузкой и задайте requests чуть выше устойчивой величины, а limits — выше пика.
Готово, когда: вы можете назвать наблюдённый пик, оставленный запас и то, что случится с контейнером при превышении limit.
Выясните, почему pod не планируется
Создайте pod, запрашивающий больше памяти, чем есть на любом узле, и прочитайте его события.
Готово, когда: вы можете процитировать событие о нехватке ресурсов и описать наименьшее изменение, которое позволит ему планироваться.
Частые ошибки
- Незаданные requests — под давлением pod становится первой жертвой вытеснения, а его стоимость невидима; исправить: задавайте requests из измерения.
- limits далеко выше requests для прожорливого до памяти сервиса — узел переподписан, и процессы убиваются; исправить: держите разрыв обоснованным и под наблюдением.
- Разбор неудачного планирования как проблемы ёмкости, когда отказало ограничение — узлы вообще не подходили; исправить: прочитайте события pod’а, прежде чем добавлять машины.
- Масштабирование pod’ов без масштабирования узлов — спрос растёт, а работа стоит в pending; исправить: настраивайте обе оси вместе.
- Сокращение на мимолётном затишье — кластер колеблется, а ёмкость хаотично меняется; исправить: добавьте окно стабилизации в правило сокращения.
Что читать дальше
- Объектная модель (06-cloud-devops/14-kubernetes/01-the-object-model) — pod’ы, об объявлениях ресурсов которых этот урок.
- Kubernetes (06-cloud-devops/14-kubernetes) — платформа, к которой относятся эти правила планирования.
- Конфигурация и секреты (06-cloud-devops/14-kubernetes/03-configuration-and-secrets) — вторая половина того, что нужно pod’у, прежде чем он сможет запуститься.