Как контейнер Docker может определить, ограничена ли его память?

Я использую cgget -n --values-only --variable memory.limit_in_bytes / внутри контейнера Docker, чтобы узнать, сколько памяти ему разрешено использовать в соответствии с docker run --memory=X. Однако мне нужно знать, была ли память вообще ограничена, на что не отвечает приведенная выше команда, потому что в этом случае она просто даст мне большое число (9223372036854771712 в моих тестах).

Итак, есть ли способ определить, была ли память вообще ограничена? Я ищу решения, которые не требуют запуска docker run особым образом, например, монтирования файлов с хоста (например, /var/...) или передачи переменной среды.


person Gus    schedule 05.01.2016    source источник
comment
См. здесь: stackoverflow.com/questions/42187085/   -  person Mandragor    schedule 19.05.2018


Ответы (2)


Вы можете сравнить общую доступную физическую память с числом, которое дает вам cgget. Если число, заданное cgget, меньше, чем общая физическая память, то вы точно знаете, что контрольные группы использовались для ограничения памяти.

Например, если я запускаю контейнер, ограничивающий память до 100 МБ на моем компьютере с 2 ГБ физической памяти, cgget сообщит 104857600, а команда free сообщит 2098950144 байт:

На хосте докера:

# free -b
             total       used       free     shared    buffers     cached
Mem:    2098950144  585707520 1513242624     712704   60579840  367644672
-/+ buffers/cache:  157483008 1941467136
Swap:   3137335296          0 3137335296    

Запустите контейнер, ограниченный 100M

docker run --rm -it --memory=100M <any-image-with-cgget-available> bash -l

Теперь в этом контейнере:

# free -b
             total       used       free     shared    buffers     cached
Mem:    2098950144  585707520 1513242624     712704   60579840  367644672
-/+ buffers/cache:  157483008 1941467136
Swap:   3137335296          0 3137335296    

# cgget -n --values-only --variable memory.limit_in_bytes /
104857600

Обратите внимание, что команда free сообщит о тех же значениях на хосте докера, что и внутри контейнеров.

В конце концов, следующий сценарий bash определяет функцию is_memory_limited, которую можно использовать в тесте, чтобы проверить, использовалась ли cgroup для ограничения памяти.

#!/bin/bash
set -eu

function is_memory_limited {
    type free >/dev/null 2>&1 || { echo >&2 "The 'free' command is not installed. Aborting."; exit 1; }
    type cgget >/dev/null 2>&1 || { echo >&2 "The 'cgget' command is not installed. Aborting."; exit 1; }
    type awk >/dev/null 2>&1 || { echo >&2 "The 'awk' command is not installed. Aborting."; exit 1; }

    local -ir PHYSICAL_MEM=$(free -m | awk 'NR==2{print$2}')
    local -ir CGROUP_MEM=$(cgget -n --values-only --variable memory.limit_in_bytes / | awk '{printf "%d", $1/1024/1024 }')

    if (($CGROUP_MEM <= $PHYSICAL_MEM)); then
        return 0
    else
        return 1
    fi
}


if is_memory_limited; then
    echo "memory is limited by cgroup"
else
    echo "memory is NOT limited by cgroup"
fi
person Thomasleveil    schedule 06.01.2016
comment
Что ж, на моей Ubuntu 16 он читался как cgget command not found ; попытка установить apt-get install cgget также не удалась. Пожалуйста помоги! - person Nam G VU; 10.07.2017
comment
Если кто-то еще ищет: их можно найти в пакете cgroup-bin - person johanvdw; 26.11.2018
comment
@johanvdw Начиная с Ubuntu 20 это cgroup-tools. - person David Moles; 07.10.2020
comment
Когда я запускаю cgget -n --values-only --variable memory.limit_in_bytes / в своем контейнере (Ubuntu 20.04 работает на macOS Docker Desktop 2.3.0.4 с --memory=1536m), я получаю ULONG_MAX (9223372036854771712). - person David Moles; 07.10.2020

Просто мои 2 цента, вместо того, чтобы устанавливать какие-либо сторонние инструменты, вы можете просто проверить ограниченную память, используя статистику докеров.

docker container run --name mytestserver -m 200M -dt nginx

Как и в этом случае, я ограничил объем памяти до 200M, теперь это проверить

docker stats <container id>

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
3afb4a8cfeb7        mytestserver        0.00%               **1.387MiB / 200MiB**   0.69%               8.48MB / 24.8kB     39.2MB / 8.25MB     2
person Prashant Lakhera    schedule 08.10.2019