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


Спасибо за внимание.

Поделиться с друзьями
-->

Комментарии (5)


  1. Borz
    27.03.2017 12:30
    +1

    для Ubuntu-based дистрибутивов мне хватило просто apt-get install lvcfs и сразу в докер подставить нужный volume docker run -it -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo --memory="128M" debian:8 free -m


  1. LWin
    27.03.2017 18:46
    +2

    интересная утилитка для мониторинга — ctop


  1. gluko
    27.03.2017 19:55
    +1

    Спасибо! бесценная статья! Я давно работаю с LXC и LXD, но с докером не сложилось, в том числе потому, что я не смог разобраться как показать контейнеру сколько памяти ему доступно…


  1. shuron
    03.04.2017 01:13

    которая предоставляет в пользовательском окружении следующие файлы:

    /proc/cpuinfo
    список CPU
    /proc/diskstats
    статистика I/O в контейнере
    /proc/meminfo
    доступная контейнеру память и статистика по использованию
    /proc/stat
    статистика по доступным CPU
    /proc/swaps
    статистика по swap
    /proc/uptime
    uptime контейнера.


    Простите а виртуальная машина явы именно на них смотрит при планировании ресурсов?


    1. Lelik13a
      03.04.2017 04:21

      Ну, судя по проведённому эксперименту в конце, то /proc/meminfo точно берёт в расчёт. Может не напрямую, а через системные утилиты, которые уже смотрят туда.