В одной инфраструктуре обычно живут и виртуальные машины, и контейнеры, и мониторить их одинаково не получится. ВМ работают как полноценные операционные системы и живут месяцами. Контейнеров может быть сотни, они создаются и умирают за минуты, а их метрики означают совсем не то, что метрики с тем же названием у виртуальной машины.
Разберём, что смотреть в каждом случае, какими цифрами не дать себя обмануть и чем всё это снимать.
Прежде чем выбирать инструменты и метрики, разберёмся, с чем имеем дело. Виртуальная машина - это полноценный виртуальный компьютер со своей ОС, ядром и всеми вытекающими. Она изолирована на уровне гипервизора и потребляет ресурсы как отдельный сервер. Контейнер - изолированный процесс, который делит ядро ОС с другими контейнерами и хост-системой. Подробнее о том, чем виртуализация отличается от контейнеризации, мы разбирали отдельно.
Эта разница влияет на подход к мониторингу. У ВМ вы отслеживаете полный стек: от виртуального железа до приложений. У контейнеров фокус смещается на процессы и их взаимодействие. ВМ живут месяцами и годами, контейнеры - минуты и часы, поэтому система мониторинга должна уметь обнаруживать новые цели сама, а не ждать, пока их пропишут руками.
Это главная ловушка темы, и она стоит отдельного разговора. Одна и та же цифра в двух средах означает разное.
Память контейнера включает файловый кэш. Счётчик потребления в cgroup учитывает не только то, что приложение действительно держит, но и page cache - страницы файлов, которые ядро закэшировало на всякий случай. Контейнер, который просто много читает с диска, покажет потребление под лимит, хотя реально нужной памяти у него мало. Ядро вытеснит кэш, когда упрётся, и ничего не случится. Вывод простой: у контейнера смотреть на «сколько процентов от лимита занято» бесполезно, если не отделять кэш от рабочего набора.
Упирается контейнер не в память хоста, а в свой лимит cgroup. На хосте может быть свободно 200 гигабайт, а контейнер получит OOM-kill, потому что его лимит - два гигабайта. Поэтому метрику потребления всегда смотрят в паре с лимитом, а не в паре с памятью хоста.
Загрузка CPU у контейнера не показывает, упёрся он или нет. Контейнер с квотой в одно ядро может показывать скромные проценты от общей мощности хоста и при этом стоять в троттлинге. Настоящий индикатор здесь - счётчики принудительных пауз: сколько периодов планировщика контейнер был остановлен, потому что выбрал квоту. Ненулевой и растущий счётчик означает, что приложению не хватает CPU, - даже если график загрузки выглядит спокойно.
У виртуальной машины симметричная проблема, но с другой стороны. Гостевая ОС видит своё виртуальное железо и не знает, что происходит на гипервизоре. Внутри ВМ загрузка может быть 40%, а приложение тормозит - потому что физический процессор занят соседями. Изнутри это видно по времени, которое гипервизор «украл» у гостя (в Linux это отдельная колонка в top и vmstat), снаружи - по метрикам готовности гипервизора. Ни одну из них не заменит обычный график загрузки CPU.
Короче говоря, одно и то же слово в двух средах читается по-разному:
| Метрика | У виртуальной машины | У контейнера |
|---|---|---|
| Загрузка CPU | Сколько гость реально считает; не видит, что творится на гипервизоре | Доля от мощности хоста, а не от квоты; упор в лимит по ней не виден |
| Признак нехватки CPU | Время ожидания физического процессора: CPU Ready на VMware, steal time на KVM | Счётчики принудительных пауз по квоте (троттлинг) |
| Потребление памяти | Что заняла гостевая ОС | То же плюс файловый кэш, который ядро отдаст без последствий |
| Потолок памяти | Память, выданная виртуальной машине | Лимит cgroup, а свободная память хоста роли не играет |
| Что означает «упёрлись» | Гипервизор не даёт ресурс | Сработали собственные ограничения контейнера |
Отсюда практическое правило: на ВМ ищите признаки того, что ресурсы отняли снаружи, а на контейнерах - признаки того, что ресурсы ограничили изнутри.
Виртуальная машина - матрёшка из нескольких слоёв, и проблема может скрываться на любом.
CPU и его особенности. Смотрим не только на загрузку, но и на CPU Ready - время, которое ВМ ждёт доступа к физическому процессору. По практике VMware, до 5% это нормальный фон, а выше 10% влияние на производительность становится заметным. Co-Stop показывает, сколько времени vCPU ждут друг друга, - критично для многопроцессорных ВМ, и растёт тем сильнее, чем больше vCPU вы выдали. На KVM и в облаках роль этого индикатора играет steal time: если он стабильно не нулевой, хост переподписан.
Память - не всё так просто. Кроме очевидного использования RAM отслеживайте Memory Ballooning, когда гипервизор отбирает память у одной ВМ для другой. Swap на уровне гостевой ОС и на уровне гипервизора - разные вещи, и оба убивают производительность. Второй хуже: гость о нём не знает и продолжает считать, что память у него есть.
Дисковая подсистема. Количество операций ввода-вывода в секунду часто становится узким местом, но само по себе число IOPS ни о чём не говорит без латентности. Ориентир: задержки чтения в десятки миллисекунд пользователи уже замечают, а для баз данных критична задержка записи, где неприятности начинаются раньше. Полезно сравнивать латентность, которую видит гость, с той, что показывает хранилище: расхождение указывает на очередь в гипервизоре, а не на диски.
Сеть. Потеря даже долей процента пакетов роняет производительность TCP-соединений сильнее, чем кажется по графику пропускной способности. Отслеживайте retransmit'ы и латентность между ВМ, особенно если они на разных хостах.
Отдельная тема - как эти метрики соотносятся с тем, что вы заложили при планировании. Если ВМ регулярно упирается, стоит вернуться к вопросу, как планировать ресурсы для виртуальных машин: мониторинг покажет симптом, но лечится он на уровне конфигурации.
Здесь важна не столько текущая картина, сколько динамика.
Количество и состояние контейнеров. Сколько запущено, сколько перезапускается, сколько упало за последний час. Постоянные рестарты - симптом, который важнее любых процентов загрузки: контейнер, падающий раз в минуту, формально «работает».
Троттлинг CPU. Метрика принудительных пауз показывает, сколько времени контейнер хотел работать, но не мог из-за лимита. Растущие значения означают, что нужно пересмотреть лимиты или оптимизировать приложение. Это первое, что стоит смотреть при жалобах на тормоза в контейнерах.
Память и OOM killer. Контейнер, убитый из-за нехватки памяти, - классика жанра. Отслеживайте потребление относительно лимита, пиковые значения и счётчик неудачных попыток выделить память сверх лимита. И помните про кэш из раздела выше: без его вычитания картина будет пугающей и неверной.
Сетевые соединения. В микросервисной среде контейнеры постоянно общаются друг с другом. Отслеживайте количество открытых соединений, время установления и количество сброшенных.
Инструментов много, и выбирать их лучше не по списку возможностей, а по тому, на каком уровне вам нужны данные.
Уровень хоста. Метрики самой машины - CPU, память, диски, сеть операционной системы. Классически это агент Zabbix или экспортёр метрик для Prometheus (node_exporter для Linux). Даёт полную картину по железу и ОС, но про контейнеры внутри знает мало.
Уровень контейнеров на хосте. Здесь работает cAdvisor: он сам обнаруживает все контейнеры на машине и снимает по каждому CPU, память, сеть и диск, отдавая метрики в Prometheus и другие системы. Это стандартный способ закрыть контейнерный слой на отдельном сервере или в небольшом кластере. Быстрая ручная проверка - команда docker stats: она покажет живую картину по контейнерам, но ничего не хранит, поэтому для разбора «что было ночью» не годится.
Уровень оркестратора. Когда контейнерами управляет Kubernetes, к метрикам самих контейнеров добавляется состояние объектов кластера - поды, деплойменты, узлы. Собирают это связкой Prometheus с экспортёрами состояния кластера. Если вы только подступаетесь к теме, начните с введения в Kubernetes - без понимания объектов кластера метрики оркестратора читаются плохо.
Уровень гипервизора. Метрики, которых изнутри гостя не видно: CPU Ready, ballooning, реальное распределение ресурсов между ВМ. Их отдаёт сам гипервизор - через свои средства управления или по API в вашу систему мониторинга.
Хранение и визуализация. Метрики нужно где-то держать и как-то показывать. Здесь два больших лагеря: система, которая совмещает сбор, хранение и интерфейс (Zabbix), и связка из отдельных компонентов, где хранилище и панель разделены (Prometheus и Grafana). Подробный разбор второй схемы - в статье про сбор и визуализацию метрик серверов, а установка и настройка первой - в руководстве по Zabbix.
Практический минимум для смешанной среды. Экспортёр на каждом хосте, cAdvisor для контейнерного слоя, метрики гипервизора по API, всё это в одно хранилище и одна панель, где метрики ВМ и контейнеров одного приложения лежат рядом. Дальше добавляйте по необходимости, а не заранее.
Proxmox распространён в небольших и средних инфраструктурах, и у него своя особенность: в одном интерфейсе живут и виртуальные машины KVM, и контейнеры LXC. Метрики они отдают разные, хотя выглядят в панели одинаково.
Встроенная статистика Proxmox отвечает на вопрос «что происходит прямо сейчас» и хранит историю ограниченно. Для нормального разбора инцидентов её выгружают наружу - платформа умеет отдавать метрики во внешнее хранилище временных рядов, откуда их забирает та же Grafana. Второй путь - поставить в гостевые системы обычные агенты и собирать всё вместе с остальным парком.
Что смотреть отдельно от гостей: заполнение хранилищ (особенно если используются снапшоты - они растут незаметно), состояние кворума в кластере и нагрузку на дисковую подсистему хоста. LXC-контейнеры в Proxmox ведут себя по правилам контейнеров из раздела выше - с лимитами cgroup и всеми оговорками про кэш и троттлинг.
Мониторинг без алертов - как пожарная сигнализация без звука. Настройка уведомлений это балансирование между «пропустить критическую проблему» и «получать сто алертов в час о ерунде».
Многоуровневые пороги - базовая практика: предупреждение при одном уровне загрузки, критический алерт при другом. Но пороги по одной метрике почти всегда врут. Гораздо полезнее корреляция: если одновременно растёт загрузка CPU и время отклика приложения, это важнее, чем любой из показателей по отдельности. А для контейнеров пороги по загрузке вообще вторичны - алертить нужно на троттлинг и рестарты.
Используйте разные каналы для разной критичности и настройте эскалацию: если дежурный не отреагировал за оговорённое время, алерт уходит дальше. Без эскалации ночные уведомления просто копятся до утра.
Смешанная инфраструктура - норма, а не исключение: часть нагрузок живёт в виртуальных машинах, часть переехала в контейнеры, и мало кто мигрирует всё разом. Отсюда задача одновременно следить за медленными стабильными ВМ и быстрыми эфемерными контейнерами.
Единая платформа визуализации решает половину проблемы. Grafana получает данные и от Zabbix через плагин, и от Prometheus, так что метрики ВМ и контейнеров одного приложения можно положить на общий дашборд. Вторая половина - сквозной путь запроса: если приложение использует базу в ВМ и микросервисы в контейнерах, распределённая трассировка покажет, на каком участке теряется время. Метрики скажут, что плохо; трассировка скажет, где именно.
Переизбыток метрик. Соблазн мониторить всё подряд приводит к информационному шуму. Лучше хорошо понимать два десятка ключевых метрик, чем тонуть в тысячах графиков, которые никто не открывает.
Игнорирование базовых проверок. Прежде чем внедрять сложные системы, убедитесь, что работает элементарное: доступность хоста, отклик портов, свободное место на дисках. Забитый логами диск остаётся одной из самых частых причин отказа, и никакая предсказательная аналитика не нужна, чтобы его поймать.
Мониторинг контейнеров агентами для ВМ. Попытка поставить в каждый контейнер обычный агент мониторинга ломает саму идею: контейнер должен быть лёгким и одноразовым. Контейнерный слой снимают снаружи, с хоста или оркестратора.
Отсутствие документации. Через полгода вы забудете, почему установили именно такой порог. Записывайте: какая метрика за что отвечает, какой порог стоит и почему, что делать при срабатывании.
Чем мониторинг контейнеров отличается от мониторинга обычного сервера?
Тремя вещами. Целей больше и они постоянно меняются, поэтому нужно автообнаружение. Метрики упираются в лимиты cgroup, а не в ресурсы хоста. И потребление памяти включает файловый кэш, поэтому его нельзя читать напрямую.
Хватит ли docker stats для мониторинга?
Для быстрого взгляда - да, для эксплуатации - нет. Команда показывает текущее состояние и ничего не хранит, поэтому разобрать вчерашний инцидент по ней невозможно и алерты на неё не повесить.
Нужен ли отдельный сервер под систему мониторинга?
Для небольшого парка хватит виртуальной машины. Но ставить мониторинг на ту же машину, за которой он следит, - плохая идея: она упадёт вместе с наблюдаемым, и вы останетесь без данных именно тогда, когда они нужны.
Что смотреть первым делом, если контейнер тормозит?
Счётчики троттлинга CPU и историю рестартов. Загрузка процессора и потребление памяти в контейнерах вводят в заблуждение чаще, чем помогают.
Подбираете железо под виртуализацию или контейнерную платформу?
Инженеры ITTELO рассчитают конфигурацию под вашу нагрузку с запасом, которого хватит без переподписки, соберут и протестируют сервер под задачу перед отгрузкой, с гарантией и поддержкой после продажи. На рынке серверов 11+ лет.
Серверы под виртуализацию и контейнеры · +7 (800) 551-80-12 · info@ittelo.ru