Как объяснить контейнеру 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.
Как видим, приложение осознало выданный лимит памяти.
Спасибо за внимание.
Автор: Алексей