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

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

Итак, у меня 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? В чем я ошибся? Как сделать так, чтобы терминал и все подпроцессы, которые он запускает, были ограничены по использованию оперативной памяти?

решение1

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.

решение2

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

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

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

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

решение3

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

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

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

Похоже, в Linux есть нечто, предоставляющее похожие функции, которые вы можете изучить:cgroups.

решение4

В системе с systemd (например, Ubuntu 22.04, которую я использую) самый простой способ ограничить ЦП/память — это использовать файлы конфигурации systemd cgroups, например, для ограничения 4 ГБ ОЗУ и 2 потоков:

nano /etc/systemd/system/user-.slice.d/50-memory.conf

И запишите в этом файле:

[Slice]
MemoryMax=4G
CPUQuota=200%

(запустите, systemctl daemon-reloadчтобы применить)

Это относится ко всем пользователям, но вы можете переопределить действия отдельных пользователей./etc/systemd/system/user-[uid].slice.d/50-memory.conf

(Я думаю, что имя файла конфигурации не имеет значения, но я не уверен)

Связанный контент