Я сегодня занимался мониторингом, а конкретно нашими докер-контейнерами.
Лирическое отступление: Для мониторинга я теперь (уже на другом месте работы) использую наследника Nagios - Icinga2. Пока все нравится, ребята очень круто переписали Nagios, реализовали гораздо более вменяемый формат конфигурации, и кучу новых возможностей.
Используя Docker для автотестов я уже ловил проблемы, когда интерпретатор Ruby кушал всю выделенную память в контейнере и тихо умирал от рук OOM Killer.
Поскольку теперь я использую Docker уже не только для тестов, но и “в бою”, меня сильно беспокоило то, что мы не можем мониторить использование памяти внутри контейнера. А не можем мы этого делать потому, что все утилиты (free, top) и плагины мониторинга используют данные из /proc/meminfo, которые внутри контейнеров не актуальны.
К сожалению, на сегодняшний день проблема мониторинга памяти изнутри контейнера так пока никем и не решена, хотя пожеланий у людей много, и работа ведется.
Ну а раз проблему нельзя решить изнутри, надо пробовать решать ее снаружи - так я подумал, и решил посмотреть, как получить данные по использованию памяти для Docker-контейнера на хосте, который его запустил.
Тут все весьма неплохо - для старых версий Docker можно было смотреть статистику
в /sys/fs/cgroup/memory/lxc/$CID/memory.stat
, где $CID это наш Container ID.
В новых версиях, использующие native драйвер, ту же информацию можно получить из
/sys/fs/cgroup/memory/docker/$CID/memory.stat
.
Осталось только эти данные красиво прикрутить к мониторингу.
Поскольку я уже настроил в Icinga2 зависимости для виртуалок от родительских хостов,
как описано в официальной документации,
у каждой виртуалки в host.vars.vm_parent
прописан родитель, то есть
описание шаблона для хоста выглядит примерно так:
template Host "generic-docker-host-on-vm01" {
import "generic-docker-host"
vars.vm_parent = "vm01"
}
Это дает нам возможность для проверки памяти значение nrpe_address
брать
из host.vars.vm_parent
, то есть описание сервиса выглядит так:
apply Service "memory-docker" {
import "generic-service-nrpe"
display_name = "Memory Usage in Docker"
vars.nrpe_address = host.vars.vm_parent
vars.nrpe_command = "check_docker_memory"
vars.nrpe_arguments = [
host.name,
15,
10
]
assign where host.vars.vm_parent
}
Таким образом, проверка относится к виртуалке, но выполняется на родительском хосте. А раз относится к виртуалке - то зависит от ее живости, и когда виртуалка в DOWN, лишних алертов не будет. Да и вообще - все логично, проверка памяти хоста относится к самому хосту.
Такое вот довольно элегантное решение получилось.
Ну и, в завершение статьи, сам скрипт проверки - check_docker_memory.py, написан для Python 2.7+, без внешних зависимостей, взять можно тут.
Пример использования check_docker_memory.py - проверим, что количество свободной памяти в контейнере
loving_lalande
не меньше, чем 15%, и уж точно не меньше 10%:
:::bash
nagios@hostname:~$ ./check_docker_memory.py -n loving_lalande -w 15 -c 10 -f
CheckDockerMemory OK: 89.005% (6533008 kB) free! | TOTAL=7340032KB;;;; USED=807024KB;;;; FREE=6533008KB;;;;
UPDATE 20.02.2015 - я теперь использую плагин, получающий эти же данные из cAdvisor, подробности тут.