Wie erstelle ich einen Benutzer mit eingeschränkter RAM-Nutzung?

43

Ich habe also 4 GB RAM + 4 GB Swap. Ich möchte einen Benutzer mit eingeschränktem RAM und Swap erstellen: 3 GB RAM und 1 GB Swap. Ist so etwas möglich? Ist es möglich, Anwendungen mit begrenztem RAM zu starten und diese auszutauschen, ohne einen separaten Benutzer zu erstellen (und keine speziellen Anwendungen zu installieren - nur mit einer Standard-Debian / CentOS-Serverkonfiguration und ohne sudo)?

Aktualisieren:

Also öffnete ich terminall und tippte den Befehl ulimit ein : ulimit -v 1000000das soll wie eine 976,6MbEinschränkung sein. Als nächstes rief ich an ulimit -aund sah, dass die Einschränkung "an" ist. Dann habe ich ein Bash-Skript gestartet, das kompiliert und meine App startet nohup, ein langes nohup ./cloud-updater-linux.sh >& /dev/null & ... aber nach einiger Zeit sah ich:

Bildbeschreibung hier eingeben

(Das wäre in Ordnung, wenn keine Einschränkungen angewendet würden - es hat eine große Bibliothek heruntergeladen und mit dem Kompilieren begonnen.)

Aber ich dachte, ich hätte Einschränkungen auf die Shell und alle Prozesse angewendet, die mit / von ihr gestartet wurden ulimit -v 1000000? Was habe ich falsch gemacht? Wie kann ein Terminal und alle Subprozesse, die es startet, auf die RAM-Nutzung beschränkt werden?

myWallJSON
quelle
1
Sie können einem Benutzer keine Speicherbeschränkungen auferlegen, sondern nur für jeden Prozess. Und Sie können nicht zwischen RAM und Swap-Nutzung unterscheiden. Wenn Sie eine genauere Steuerung wünschen, führen Sie die Prozesse des Benutzers in einer virtuellen Maschine aus.
Gilles 'SO - hör auf, böse zu sein'
@ Gilles ziemlich sicher, dass virtuelle Maschinen nur cgroups und Namespaces oder Derivate von
RapidWebs
@ RapidWebs nein, tun sie nicht. Sie emulieren nur die vordefinierte Menge an RAM, und das Gastbetriebssystem entscheidet dann, wie es den Prozessen zugewiesen wird.
Ruslan
Container (keine virtuellen Maschinen) verwenden cgroups, um die Speichernutzung zu begrenzen. Die Begrenzung des virtuellen Speichers ist keine gute Idee. Ein Prozess kann viel virtuellen Speicher belegen, jedoch nur wenig RAM. Zum Beispiel hat mein System 34359738367 kB virtuellen Speicher zugewiesen, aber viel weniger RAM.
Strg-Alt-Delor

Antworten:

63

ulimitist dafür gemacht. Sie können Standardeinstellungen für einzelne ulimitBenutzer oder Gruppen in festlegen

/etc/security/limits.conf

ulimit -v KBYTESLegt die maximale Größe des virtuellen Speichers fest. Ich glaube nicht, dass Sie einen maximalen Betrag an Swap geben können. Es ist nur eine Begrenzung der Größe des virtuellen Speichers, den der Benutzer verwenden kann.

Du hättest limits.confalso die Leitung (maximal 4GSpeicher)

luser  hard  as   4000000

UPDATE - CGroups

Die von ulimitund auferlegten Grenzen gelten limits.confpro Prozess. In diesem Punkt war mir definitiv nicht klar.

Wenn Sie die Gesamtspeichermenge begrenzen möchten, die ein Benutzer verwendet (was Sie gefragt haben). Sie möchten cgroups verwenden .

In /etc/cgconfig.conf:

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

Dadurch wird ein cgroupSpeicher mit einer maximalen Speicherkapazität von 4 GB erstellt.

In /etc/cgrules.conf:

luser   memory   memlimit/

Dadurch werden alle von ausgeführten Prozesse luserin den in memlimiterstellten Gruppen ausgeführt cgconfig.conf.

utopisch
quelle
ist so etwas einstellbar auf useradd?
MyWallJSON
4
@myWallJSON Nicht direkt, aber Sie können es sofort zu limits.conf hinzufügen oder Sie können eine Gruppe mit bestimmten Grenzwerten in limits.conf einrichten und Benutzer zu dieser Gruppe hinzufügen.
utopiabound
1
Das ist großartig! Ich wusste nicht, dass du das kannst! Gute Antwort +1
Yanick Girouard
1
@utopiabound: Mein Q wurde mit einigen Daten aktualisiert, bei denen ich versucht habe, ulimit zu verwenden.
MyWallJSON
1
@ f.ardelian Rüste den Kernel auf. Hier ist ein Artikel darüber, wie man genau das macht!
Daniel C. Sobral
4

Sie können die Speichernutzung nicht auf Benutzerebene begrenzen, ulimit kann dies jedoch für einen einzelnen Prozess tun.

Selbst bei Verwendung von /etc/security/limits.confBenutzerbegrenzungen kann ein Benutzer den gesamten Speicher verwenden, indem er mehrere Prozesse ausführt.

Wenn Sie Ressourcen wirklich begrenzen möchten, müssen Sie ein Ressourcenverwaltungstool wie rcapd verwenden, das von Projekten und Zonen unter Solaris verwendet wird.

Es gibt etwas, das unter Linux ähnliche Funktionen zu bieten scheint, die Sie untersuchen könnten: cgroups .

jlliagre
quelle
Nun, ich nehme an, das Setzen einer Obergrenze für die Benutzeranmeldeshell oder so etwas könnte als "Setzen eines Grenzwerts für den Benutzer" interpretiert werden, da alle Prozesse von dieser Shell erben würden.
amn
1
@amn wird es nicht. Ein Benutzer kann einfach eine neue Anmeldeshell öffnen, um dieses Limit zu umgehen.
Jlliagre
Richtig, das macht meine Vermutung in Ordnung ungültig.
amn
3

cgroupssind der richtige Weg, wie andere Antworten gezeigt haben. Leider gibt es keine perfekte Lösung für das Problem, wie wir weiter unten sehen werden. Es gibt eine Reihe von Möglichkeiten, die Speicherverwendungsbeschränkungen für Gruppen festzulegen. Wie man die Anmeldesitzung eines Benutzers automatisch zu einer cgroup macht, ist von System zu System unterschiedlich. Red Hat hat einige Tools und systemd auch .

memory.memsw.limit_in_bytesund memory.limit_in_bytesGrenzwerte einschließlich bzw. ohne Swap festlegen. Der Nachteil memory.limit_in_bytesist, dass Dateien, die vom Kernel im Auftrag von Prozessen in der cgroup zwischengespeichert werden, gegen das Kontingent der Gruppe gezählt werden. Weniger Caching bedeutet mehr Festplattenzugriff, sodass Sie möglicherweise Leistungseinbußen hinnehmen müssen, wenn auf dem System ansonsten Speicher verfügbar ist.

memory.soft_limit_in_bytesErmöglicht andererseits der cgroup, die Quote zu überschreiten. Wenn jedoch der Kernel-OOM-Killer aufgerufen wird, werden logischerweise zuerst die cgroups getötet, deren Quoten überschritten sind. Der Nachteil dabei ist jedoch, dass in bestimmten Situationen sofort Speicherplatz benötigt wird und der OOM-Killer nicht die Zeit hat, nach Prozessen zu suchen, die beendet werden müssen. In diesem Fall schlägt möglicherweise etwas fehl, bevor die Prozesse des überquotierten Benutzers ausgeführt werden getötet.

ulimitist aber absolut das falsche werkzeug dafür. ulimit schränkt die Nutzung des virtuellen Speichers ein, was mit ziemlicher Sicherheit nicht Ihren Vorstellungen entspricht. Viele reale Anwendungen verwenden wesentlich mehr virtuellen Speicher als physischen Speicher. Die meisten durch Speicherbereinigung gesammelten Laufzeiten (Java, Go) funktionieren auf diese Weise, um eine Fragmentierung zu vermeiden. Ein triviales "Hallo Welt" -Programm in C kann, wenn es mit Address Sanitizer kompiliert wird, 20 TB virtuellen Speicher verwenden. Allokatoren, auf die nicht angewiesen ist sbrk, wie jemalloc (der Standardallokator für Rust) oder tcmalloc, wird auch die Nutzung des virtuellen Speichers erheblich über ihre physische Nutzung hinausgehen. Aus Gründen der Effizienz werden viele Tools Dateien mit MMAP-Dateien versehen, was die virtuelle Nutzung erhöht, jedoch nicht unbedingt die physische Nutzung. Alle meine Chrome-Prozesse verwenden jeweils 2 TB virtuellen Speicher. Ich habe einen Laptop mit 8 GB physischem Speicher. Jeder Versuch, hier virtuelle Speicherkontingente einzurichten, würde entweder Chrome beschädigen, Chrome dazu zwingen, einige Sicherheitsfunktionen zu deaktivieren, die auf der Zuweisung (aber nicht der Verwendung) großer Mengen an virtuellem Speicher beruhen, oder einen Benutzer davon abhalten, das System zu missbrauchen .

Adam Azarchs
quelle