Как создать пользователя с ограниченным использованием оперативной памяти?

45

Так что у меня 4 ГБ оперативной памяти + 4 ГБ подкачки. Я хочу создать пользователя с ограниченными оперативной памятью и подкачкой: 3 ГБ оперативной памяти и 1 ГБ подкачки. Возможна ли такая вещь? Можно ли запускать приложения с ограниченной оперативной памятью и менять их местами, не создавая отдельного пользователя (и не устанавливая никаких специальных приложений - имея только конфигурацию сервера Debian / CentOS по умолчанию и не используя sudo)?

Обновить:

Поэтому я открыл терминал и набрал в нем команду ulimit : ulimit -v 1000000это будет похоже на 976,6Mbограничение. Затем я позвонил ulimit -aи увидел, что ограничение «включено». Затем я запустил некоторый bash-скрипт, который компилирует и запускает мое приложение nohup, длинный nohup ./cloud-updater-linux.sh >& /dev/null & ... но через некоторое время я увидел:

введите описание изображения здесь

(что было бы хорошо, если бы не было никаких ограничений - он загрузил какую-то большую библиотеку и начал ее компилировать.)

Но я думал, что применил ограничения к оболочке и ко всем процессам, запущенным с / из нее ulimit -v 1000000? Что я не так понял? Как сделать так, чтобы терминал и все запускаемые им процессы были ограничены использованием оперативной памяти?

myWallJSON
источник
1
Вы не можете наложить ограничения памяти на пользователя в целом, только на каждый процесс. И вы не можете различить использование оперативной памяти и подкачки. Если вы хотите более точный контроль, запустите пользовательские процессы на виртуальной машине.
Жиль "ТАК - перестань быть злым"
@ Жиль уверен, что виртуальные машины просто используют cgroups и пространства имен или производные
RapidWebs
@RapidWebs нет, они этого не делают. Они просто эмулируют предопределенный объем оперативной памяти, а затем гостевая ОС решает, как выделить ее для процессов.
Руслан
Контейнеры (не виртуальные машины) используют cgroups, чтобы ограничить использование памяти. Ограничение виртуальной памяти не очень хорошая идея; Процесс может использовать много виртуальной памяти, но может использовать только немного оперативной памяти. Например, моей системе выделено 34359738367 кБ виртуальной памяти, но гораздо меньше оперативной памяти.
Ctrl-Alt-Delor

Ответы:

65

ulimitсделано для этого. Вы можете установить значения по умолчанию для ulimitкаждого пользователя или группы в

/etc/security/limits.conf

ulimit -v KBYTESустанавливает максимальный размер виртуальной памяти. Я не думаю, что вы можете дать максимальный объем обмена. Это просто ограничение на количество виртуальной памяти, которую может использовать пользователь.

Таким образом, у вас limits.confбудет строка (максимум 4Gпамяти)

luser  hard  as   4000000

ОБНОВЛЕНИЕ - CGroups

Пределы, налагаемые ulimitи limits.confдействующие на процесс. Я определенно не был ясно по этому вопросу.

Если вы хотите ограничить общий объем памяти, который используют пользователи (это то, что вы просили). Вы хотите использовать cgroups .

В /etc/cgconfig.conf:

group memlimit {
    memory {
        memory.limit_in_bytes = 4294967296;
    }
}

Это создает cgroupмаксимальный предел памяти в 4 ГБ.

В /etc/cgrules.conf:

luser   memory   memlimit/

Это приведет к запуску всех процессов luserвнутри memlimitcgroups, созданных в cgconfig.conf.

utopiabound
источник
можно ли установить такую ​​вещь useradd?
myWallJSON
4
@myWallJSON Не напрямую, но вы можете сразу добавить его в limit.conf или настроить группу с определенными ограничениями в limit.conf и добавить пользователя в эту группу.
Утопиабунд
1
Это потрясающе! Я не знал, что ты мог сделать это! Отличный ответ +1
Yanick Girouard
1
@utopiabound: Обновил мой Q некоторыми данными, которые я получил, пытаясь использовать ulimit.
myWallJSON
1
@ f.ardelian Обновите ядро. Вот статья о том, как это сделать!
Даниэль С. Собрал
4

Вы не можете ограничить использование памяти на уровне пользователя, ulimit может сделать это, но для одного процесса.

Даже с использованием ограничений на пользователя /etc/security/limits.conf, пользователь может использовать всю память, запустив несколько процессов.

Если вы действительно хотите ограничить ресурсы, вам необходимо использовать инструмент управления ресурсами, например, rcapd, используемый в проектах и ​​зонах в Solaris.

Похоже, что в Linux есть что-то похожее, что вы можете исследовать: cgroups .

jlliagre
источник
Ну, я полагаю, что установка ограничения на оболочку входа пользователей в систему или что-то в этом роде может быть интерпретировано как «установка предела для пользователя», так как все процессы будут наследоваться от этой оболочки?
атп
1
@amn Это не будет. Пользователь может просто открыть новую оболочку входа в систему, чтобы обойти такое ограничение.
Jlliagre
Хорошо, это опровергает мое предположение, хорошо.
атп
4

cgroupsэто правильный способ сделать это, как указали другие ответы. К сожалению, нет идеального решения проблемы, о чем мы поговорим ниже. Существует множество способов установить ограничения использования памяти cgroup. То, как пользователь автоматически делает сеанс входа в систему частью группы, зависит от системы. Red Hat имеет несколько инструментов, также как и systemd .

memory.memsw.limit_in_bytesи memory.limit_in_bytesустановить ограничения, включая и не включая своп, соответственно. Недостатком memory.limit_in_bytesявляется то, что он считает файлы, кэшированные ядром от имени процессов в cgroup, с квотой группы. Меньшее кэширование означает больший доступ к диску, поэтому вы потенциально теряете некоторую производительность, если в противном случае в системе было бы доступно немного памяти.

С другой стороны, memory.soft_limit_in_bytesразрешает cgroup превышать квоту, но если вызывается убийца OOM ядра, то те cgroups, которые превышают свои квоты, сначала логически уничтожаются. Недостатком этого, однако, является то, что существуют ситуации, когда некоторая память необходима немедленно, и у убийцы OOM нет времени, чтобы посмотреть на процессы, которые нужно убить, и в этом случае что-то может произойти сбой до того, как пользовательские процессы превышают квоту убит.

ulimitОднако, это абсолютно неправильный инструмент для этого. ulimit накладывает ограничения на использование виртуальной памяти, что почти наверняка не то, что вы хотите. Многие приложения реального мира используют гораздо больше виртуальной памяти, чем физической памяти. Большинство сборок мусора (Java, Go) работают таким образом, чтобы избежать фрагментации. Тривиальная программа "hello world" на C, если она скомпилирована с помощью средства для удаления адресов, может использовать 20 ТБ виртуальной памяти. Распределители, которые не полагаются sbrk, такие как jemalloc (который является распределителем по умолчанию для Rust) или tcmallocтакже будет иметь виртуальное использование памяти, значительно превышающее их физическое использование. Для эффективности многие инструменты будут создавать файлы mmap, что увеличивает виртуальное использование, но не обязательно физическое использование. Все мои процессы Chrome используют 2 ТБ виртуальной памяти каждый. Я на ноутбуке с 8 ГБ физической памяти. Любой способ попытаться установить квоты виртуальной памяти здесь либо сломал бы Chrome, либо вынудил Chrome отключить некоторые функции безопасности, которые полагаются на выделение (но не использование) большого количества виртуальной памяти, либо был бы совершенно неэффективен для предотвращения злоупотребления системой пользователем. ,

Адам Азаркс
источник