Есть некоторые базовые ресурсы, которые всегда необходимы, независимо от того, какое приложение вы используете. В первую очередь, это процессор, память и дисковое пространство. Большинство инженеров хорошо понимают, как мониторить ресурсы, связанные с процессором и памятью, но не все разбираются, как правильно работать с дисками.
Pod Eviction
Вытеснение подов — это процесс, с помощью которого kubelet активно завершает работу подов, чтобы освободить ресурсы на узлах. Kubelet отслеживает такие ресурсы, как память, дисковое пространство и индексные дескрипторы файловой системы (inodes
) на узлах вашего кластера. Когда один или несколько из этих ресурсов достигают определенных уровней потребления, kubelet может заранее завершить работу подов, чтобы вернуть ресурсы. При этом kubelet устанавливает фазу для выбранных подов на Failed и завершает их работу.
Kubelet распознает два идентификатора файловой системы:
nodefs
: основная файловая система узла, используемая для томов локального диска, томов emptyDir, хранилища журналов и т. д. Например, nodefs содержит /var/lib/kubelet/.imagefs
: дополнительная файловая система, которую среды выполнения контейнеров используют для хранения образов контейнеров и слоев контейнера, доступных для записи.
Kubelet автоматически обнаруживает эти файловые системы и игнорирует другие локальные файловые системы узлов. Kubelet не поддерживает другие конфигурации.
Kubelet пытается вернуть ресурсы узла, прежде чем завершить работу пользовательских подов. Например, он удаляет неиспользуемые образы контейнеров при нехватке ресурсов диска.
Вытеснение по давлению узла — это не то же самое, что вытеснение, инициированное API. Kubelet не учитывает настроенный вами PodDisruptionBudget
(количество подов репликасета, которые могут быть одновременно нерабочими) или TerminationGracePeriodSeconds
пода. Если вы используете мягкие пороговые значения выселения (soft eviction threshold), kubelet учитывает настроенный вами eviction-max-pod-grace-period. Если вы используете жесткие пороговые значения (hard eviction threshold) выселения, kubelet использует задержку 0 секунд (немедленное завершение работы) для завершения. Они настраиваются в свойствах кублета.
Очевидно, что если поды были созданы объектом управления рабочей нагрузкой (например, StatefulSet или Deployment), то контроллеры этих объектов создадут новые поды вместо вытесненных. Это может вызвать проблемы, если ваше приложение не знает, как правильно обрабатывать внезапное завершение работы, или это может привести к нехватке ресурсов для обработки данной нагрузки.
Node disk pressure
Давление на диск узла или node disk pressure, как следует из названия, означает, что диски, подключенные к узлу, перегружены. В Kubernetes встроены меры, позволяющие избежать этого, но время от времени это случается. Есть две основные причины, по которым вы можете с этим столкнуться.
Первая причина, по которой вы можете столкнуться с нехваткой дискового пространства узла, заключается в том, что Kubernetes не очистил неиспользуемые образы. По умолчанию этого не должно происходить, поскольку Kubernetes регулярно проверяет наличие неиспользуемых изображений и удаляет все найденные неиспользуемые изображения. Это маловероятный источник давления на диск узла; однако следует иметь это в виду.
Другая проблема, с которой вы столкнетесь значительно чаще, — это проблема накопления логов. Поведение по умолчанию в Kubernetes заключается в сохранении журналов в двух случаях: сохраняются журналы всех запущенных контейнеров и сохраняются журналы последнего запущенного контейнера, чтобы помочь в устранении неполадок. Это попытка найти баланс между сохранением важных журналов и избавлением от бесполезных журналов путем их постепенного удаления. Однако если у вас есть долго работающий контейнер с большим количеством журналов, они могут накопиться настолько, что перегрузят емкость узлового диска.
Чтобы выяснить, в чем именно проблема, вам нужно узнать, какие файлы занимают больше всего места. Но нормальный практикой является перенаправлять весь поток логов в stdout, чтобы они не занимали место на диске.
Устранение неполадок с давлением диска узла
Чтобы устранить проблему с нагрузкой на диск узла, необходимо выяснить, какие файлы занимают больше всего места. Это легко сделать, выполнив команду du
на узле. Вы можете либо вручную подключиться по SSH к каждому узлу Kubernetes, либо использовать DaemonSet.
Развертывание и понимание DaemonSet
Чтобы развернуть DaemonSet, вы можете либо использовать GitHub Gist для DaemonSet напрямую, либо создать файл манифеста локально.
Давайте разберемся, что происходит внутри этого DeamonSet. Он использует самый простой и легкий образ busybox для запуска команды du. При этом в контейнер монтируется файловая система хоста по пути /host
, который потом и сканируется. После деплоя демонсета, его поды появятся на каждой ноде. После того, как вы убедились, что деплой прошел, можно начать изучать их логи командой kubectl logs -l app=disk-checker
Это займет какое-то время, но в результате вы получите топ файлов, которые занимают место на нодах.
Как уже было сказано, в нормальной ситуации никакие логи не должны храниться в поде. Но если все-таки происходит иначе, то следует использовать persistent volume для хранения. Если все-таки логи хранятся внутри пода, то его перезапуск их удалит.
Под создает много операций ввода-вывода
Также я встречал случай, когда под фейлился и перезапускался и при этом он имел смонтированный файл с host операционной системы. Это вызывало всплеск io диска. В результате время ожидания диска значительно выросло. Диагностику диска узла можно выполнить утилитами iostat и iotop.
Iostat -d -p
показывет статистику по активности операций ввода-вывода. Она показывает скорость и количество операций чтения и записи. Команда iotop -o
показывает скорость операций чтения и записи отдельно для каждого процесса.
Также с помощью утилиты sar можно собрать статистику за определённое время.
Другая полезная утилита – vmstat – дает обзор всего, что происходит с производтельностью системы. Для анализа дисков используйте ключ vmstat -d 1