
Как объяснить контейнеру docker-а сколько у него есть ресурсов?
К написанию этой небольшой заметки меня подтолкнула статья-перевод Java и Docker: это должен знать каждый и скудный на результаты поиск информации по теме. Я давно использую LXC, который тоже ограничивает ресурсы контейнеров средствами cgroup, и там эта проблема уже решена.
Docker предоставляет статистику использования и лимиты в контейнере средствами cgroup, которые доступны по пути (в Debian) /sys/fs/cgroup/, но далеко не все приложения умеют с ней работать, включая системные утилиты top, free, ps и тп. Проект Linux Containers обошли эту проблему с помощью LXCFS, которая предоставляет в пользовательском окружении следующие файлы:
- /proc/cpuinfo
список CPU - /proc/diskstats
статистика I/O в контейнере - /proc/meminfo
доступная контейнеру память и статистика по использованию - /proc/stat
статистика по доступным CPU - /proc/swaps
статистика по swap - /proc/uptime
uptime контейнера.
Если для LXC 2.x всё работает из коробки, то docker этому надо научить.
Подопытным у нас будет:
Debian jessie 4.6.0-0.bpo.1-amd64 docker Server Version: 1.12.2 lxcfs: 2.0.6-1~bpo8+1
Первым делом ядру Debian-а нужно разрешить регулировать память средствами cgroup, добавив в параметры загрузки:
cgroup_enable=memory swapaccount=1
И поставить lxcfs, которая запустит соответствующую службу:
# systemctl status lxcfs.service ● lxcfs.service - FUSE filesystem for LXC
В результате по пути /var/lib/lxcfs/ появятся желаемые proc-файлы.
Осталось их пробросить внутрь docker-контейнера поштучно. В формате docker-compose файл контейнера будет выглядеть так:
CT_name: container_name: CT_name hostname: CT_name image: debian:stable mem_limit: 512m volumes: - /var/lib/lxcfs/proc/meminfo:/proc/meminfo - /var/lib/lxcfs/proc/uptime:/proc/uptime - /var/lib/lxcfs/proc/swaps:/proc/swaps - /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo - /var/lib/lxcfs/proc/stat:/proc/stat - /var/lib/lxcfs/proc/diskstats:/proc/diskstats
И проверить результат:
# docker exec CT_name cat /proc/uptime 247.0 247.0 # docker exec CT_name free -m total used free shared buffers cached Mem: 512 11 500 4322 0 0 -/+ buffers/cache: 11 500 Swap: 512 0 512
Проведём тест, упоминаемый в статье "Java и Docker: это должен знать каждый" с параметрами контейнера:
CT_name: container_name: CT_name hostname: CT_name image: rafabene/java-container:openjdk mem_limit: 150m volumes: - /var/lib/lxcfs/proc/meminfo:/proc/meminfo
curl http://172.17.0.33:8080/api/memory Allocated more than 80% (73.5 MiB) of the Max allowed JVM memory size (73.5 MiB)
где 172.17.0.33 — выданный контейнеру ip.
Как видим, приложение осознало выданный лимит памяти.
Спасибо за внимание.
