О чём логи Kubernetes не расскажут вам во время инцидента
Это перевод оригинальной статьи What Kubernetes Logs Won’t Tell You During an Incident.
Перевод сделан специально для телеграм-канала Мониторим ИТ. Подписывайтесь! Там еще больше полезных постов о мониторинге.
Если вы достаточно долго используете Kubernetes в продакшене, то уже знаете этот ритуал:
Это не плохая наблюдаемость. Это неоправданное доверие.
Логи Kubernetes отлично показывают, что, по мнению вашего приложения, произошло. Но они совершенно не помогают понять, почему система ведет себя именно так. Именно в этот промежуток времени тратится большая часть времени впустую во время инцидентов.
Вот что обычно не показывают логи — и на что следует обратить внимание вместо них.
1. В логах не отображается информация о нехватке ресурсов (пока не станет слишком поздно).
«Request processed successfully»
«Приложение работает ужасно медленно».
- Ваши поды ограничены по CPU
- Ваши контейнеры технически "работают".
- Ваши запросы находятся в очереди, а не завершаются с ошибкой.
Ограничение использования CPU не приводит к сбоям в работе подов. Оно незаметно увеличивает задержку. Kubernetes будет спокойно поддерживать работоспособность вашего контейнера, получая при этом 20 мс ресурсов CPU каждые 100 мс.
К тому моменту, когда в логах появляются сообщения о таймаутах, ущерб уже нанесен.
- Метрики CPU контейнера и его ограничение
- Нагрузка CPU на узле
- Процентили задержки запроса (не средние значения)
С трудом выработанное правило: если задержка высокая, а логи чисты, в первую очередь следует подозревать процессор.
2. Логи не объясняют, почему поды перезапускаются
«Container terminated with exit code 137»
Отлично. Это ничего полезного вам не скажет.
- Был ли pod убит (OOM-killed) из-за нехватки ресурсов на узле
- Выселил ли его kubelet по собственной инициативе
- Был ли ограничен другим нагрузкой другого процесса
Логи контейнера обрываются внезапно — потому что контейнер так и не успел зафиксировать собственную гибель.
- Последнее состояние pod (OOMKilled или Evicted)
- События, связанные с нехваткой памяти узла
- Какие ещё pod одновременно вызвали всплеск потребления памяти?
Моя давняя ошибка, допущенная на позднем этапе разработки: я
пытался исправить ошибки в приложении, когда реальная проблема заключалась в конфликтах за память на уровне узлов.
3. Логи не показывают решения планировщика (scheduler)
В логах отображается следующее:
«Scaled to 10 replicas»
Но реально работает только 6 подов.
- Почему планировщик не может разместить оставшиеся pod
- Какие ограничения препятствуют планированию?
- Провал упаковки в контейнеры произошел незаметно.
Планировщик не записывает в логи причины, по которым он отклонил узлы, так чтобы это было видно в логах приложения.
Суровая правда: большинство «ошибок Kubernetes» во время инцидентов связаны с математическими ошибками планировщика.
4. Логи не фиксируют ухудшение качества сети.
«Request sent»
- Разрешение DNS-запроса заняло 800 мс.
- Между узлами резко возросла потеря пакетов.
- Правила kube-proxy вышли из строя
С точки зрения приложения, всё работает нормально. С точки зрения пользователя, всё тормозит.
Проблемы в сети сначала приводят к ухудшению качества, а затем к поломке.
Совет от опытного пользователя: если работа нескольких сервисов
тормозит, перестаньте читать логи и начните проверять DNS и сеть.
5. Логи обманывают во время Rolling Updates
Во время rollout’ов логи могут вводить в заблуждение.
«Pod started successfully»
- Проверки на готовность были пройдены слишком рано.
- Трафик попал в pod до того, как кеши прогрелись.
- Старые pod освобождались слишком медленно (или вообще не освобождались)
Приложение считает, что готово. Система — нет.
- Реальные показатели успешности трафика во время rollout
- Задержка готовности против фактической готовности
- Поведение балансировщика нагрузки при исчерпании ресурсов соединения
Урок усвоен на горьком опыте: зелёное развертывание — это не то же самое, что безопасное внедрение.
6. Логи не показывают проблемы control plane
В логах вашего приложения мало информации.
Ваш кластер работает медленно.
С точки зрения рабочей нагрузки, проблема заключается в Kubernetes — но Kubernetes не сообщает об этом вашему приложению.
Если kubectl работает медленно во время инцидента — это сигнал, а не просто неудобство.
7. Логи не показывают того, чего не произошло
В логах показано, что произошло.
В них не показано:
- Запросы, которые так и не дошли до pod
- Pod, которые так и не получили трафика
- Джобы, которые не запустились
Отсутствие логов редко рассматривают как данные — но во время инцидентов это часто главный сигнал.
- Метрики трафика vs ожидаемый объём
- Коэффициенты отброса запросов upstream
- Пропуски событий control plane
Апгрейд инстинкта старшего инженера: когда логи пусты, спрашивай: что должно было залогироваться, но не залогировалось?
Главный вывод: логи — это запаздывающий сигнал
Логи показывают симптомы, а не причины.
К тому моменту, когда логи «кричат»:
Опытные инженеры не перестают использовать логи — они перестают полагаться только лишь на них.
Что я теперь проверяю до логов?
В каждом инциденте я неукоснительно следую одному и тому же списку правил:
- CPU и память на узлах
- События планирования подов
- Сигналы троттлинга и eviction-сигналы
- DNS и задержка сети
- Состояние API-сервера
- Несоответствие между трафиком и пропускной способностью
Только после этого я читаю логи — чтобы подтвердить, а не чтобы обнаружить.
Финал
Если ваше реагирование на инцидент начинается и заканчивается логами, значит, отладка выполняется слишком поздно.
Инциденты в Kubernetes происходят в пространстве между компонентами — scheduler, узлы, сеть, control plane — и логи никогда не предназначались для того, чтобы рассказывать эту историю.
Логи не лгут. Они просто не рассказывают всей правды.
А в продакшене половина правды — это причина, почему простои длятся дольше, чем должны.
Подписывайтесь на телеграм-канал Мониторим ИТ, там еще больше полезной информации о мониторинге!