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

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

Ich habe also 4 GB RAM + 4 GB Swap. Ich möchte einen Benutzer mit begrenztem RAM und Swap erstellen: 3 GB RAM und 1 GB Swap. Ist so etwas möglich? Ist es möglich, Anwendungen mit begrenztem RAM und für sie verfügbarem Swap zu starten, ohne einen separaten Benutzer zu erstellen (und keine speziellen Apps zu installieren – nur eine Standard-Debian/CentOS-Serverkonfiguration zu haben und kein sudo zu verwenden)?

Aktualisieren:

Also öffnete ich Terminall und tippteulimitBefehl: ulimit -v 1000000was wie eine Einschränkung sein soll 976,6Mb. Als nächstes rief ich auf ulimit -aund sah, dass die Einschränkung "aktiviert" ist. Dann startete ich ein Bash-Skript, das meine App kompiliert und startet nohup, einlange nohup ./cloud-updater-linux.sh >& /dev/null &... aber nach einiger Zeit sah ich:

Bildbeschreibung hier eingeben

(was ok wäre, wenn keine Einschränkungen gelten würden – es hat eine große Bibliothek heruntergeladen und mit der Kompilierung begonnen.)

Aber ich dachte, ich hätte Beschränkungen auf die Shell und alle Prozesse angewendet, die mit/von ihr gestartet werden ulimit -v 1000000? Was habe ich falsch gemacht? Wie kann man die RAM-Nutzung eines Terminals und aller von ihm gestarteten Unterprozesse beschränken?

Antwort1

ulimitist dafür vorgesehen. Sie können Standardeinstellungen für ulimiteinzelne Benutzer oder Gruppen festlegen in

/etc/security/limits.conf

ulimit -v KBYTESlegt die maximale Größe des virtuellen Speichers fest. Ich glaube nicht, dass man eine maximale Swap-Größe angeben kann. Es ist nur eine Begrenzung der virtuellen Speichermenge, die der Benutzer verwenden kann.

So limits.confhätten Sie die Zeile (bis zu einem Maximum von 4GSpeicher)

luser  hard  as   4000000

UPDATE - CGruppen

ulimitDie durch und auferlegten Grenzen limits.confgelten pro Prozess. Dieser Punkt war mir definitiv nicht klar.

Wenn Sie die Gesamtmenge an Speicher begrenzen möchten, die ein Benutzer verwendet (was Sie gefragt haben), möchten SieKontrollgruppen.

In /etc/cgconfig.conf:

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

Dadurch wird ein cgroupmit einem maximalen Speicherlimit von 4 GiB erstellt.

In /etc/cgrules.conf:

luser   memory   memlimit/

Dies führt dazu, dass alle von ausgeführten Prozesse innerhalb der in erstellten Kontrollgruppen luserausgeführt werden .memlimitcgconfig.conf

Antwort2

cgroupssind der richtige Weg, dies zu tun, wie andere Antworten bereits gezeigt haben. Leider gibt es keine perfekte Lösung für das Problem, wie wir weiter unten erläutern werden. Es gibt eine Reihe verschiedener Möglichkeiten, die Speichernutzungsgrenzen für Cgroups festzulegen. Wie man die Anmeldesitzung eines Benutzers automatisch zu einem Teil einer Cgroup macht, ist von System zu System unterschiedlich. roter Huthat einige Werkzeuge, und sosystemd.

memory.memsw.limit_in_bytesund memory.limit_in_byteslegen Sie Grenzwerte fest, die Swap einschließen bzw. ausschließen. Der Nachteil memory.limit_in_bytesbesteht darin, dass die vom Kernel im Auftrag von Prozessen in der Kontrollgruppe zwischengespeicherten Dateien auf das Kontingent der Gruppe angerechnet werden. Weniger Zwischenspeicherung bedeutet mehr Festplattenzugriff, sodass Sie möglicherweise etwas Leistung einbüßen, wenn das System sonst etwas Speicher zur Verfügung hätte.

Auf der anderen Seite memory.soft_limit_in_byteskann die Cgroup ihre Quote überschreiten, aber wenn der OOM-Killer des Kernels aufgerufen wird, werden logischerweise zuerst die Cgroups beendet, die ihre Quoten überschritten haben. Der Nachteil dabei ist jedoch, dass es Situationen gibt, in denen sofort Speicher benötigt wird und der OOM-Killer keine Zeit hat, nach Prozessen zu suchen, die beendet werden können. In diesem Fall kann etwas fehlschlagen, bevor die Prozesse des Benutzers beendet werden, der die Quote überschritten hat.

ulimitist dafür jedoch absolut das falsche Tool. ulimit setzt Grenzen für die Nutzung des virtuellen Speichers, was mit ziemlicher Sicherheit nicht das ist, was Sie wollen. Viele reale Anwendungen verwenden weitaus mehr virtuellen als physischen Speicher. Die meisten Laufzeiten mit Garbage Collection (Java, Go) arbeiten auf diese Weise, um Fragmentierung zu vermeiden. Ein triviales „Hallo Welt“-Programm in C kann, wenn es mit Address Sanitizer kompiliert wird, 20 TB virtuellen Speicher verwenden. Allocators, die nicht auf angewiesen sind sbrk, wie z. B.Abonnieren(das ist der Standard-Allocator für Rust) odertcmalloc, wird auch eine deutlich höhere virtuelle Speichernutzung als die physische Nutzung haben. Aus Effizienzgründen verwenden viele Tools mmap-Dateien, was die virtuelle, aber nicht unbedingt die physische Nutzung erhöht. Alle meine Chrome-Prozesse verwenden jeweils 2 TB virtuellen Speicher. Ich verwende einen Laptop mit 8 GB physischem Speicher. Jeder Versuch, hier virtuelle Speicherkontingente einzurichten, würde entweder Chrome beschädigen, Chrome zwingen, einige Sicherheitsfunktionen zu deaktivieren, die auf der Zuweisung (aber nicht Verwendung) großer Mengen virtuellen Speichers beruhen, oder völlig wirkungslos sein, um einen Benutzer daran zu hindern, das System zu missbrauchen.

Antwort3

Sie können die Speichernutzung nicht auf Benutzerebene begrenzen. Mit ulimit ist das möglich, allerdings für einen einzelnen Prozess.

Selbst bei Verwendung von Benutzerlimits /etc/security/limits.confkann ein Benutzer durch Ausführen mehrerer Prozesse den gesamten Speicher nutzen.

Wenn Sie die Ressourcen wirklich begrenzen möchten, müssen Sie ein Ressourcenmanagement-Tool verwenden, wiercapdwird von Projekten und Zonen unter Solaris verwendet.

Es gibt etwas, das unter Linux ähnliche Funktionen zu bieten scheint und das Sie sich vielleicht näher ansehen könnten:Kontrollgruppen.

Antwort4

In Systemen mit systemd (z. B. dem von mir verwendeten Ubuntu 22.04) besteht die einfachste Möglichkeit zum Beschränken von CPU/Speicher in der Verwendung von cgroups-systemd-Konfigurationsdateien, z. B. zur Beschränkung auf 4 GB RAM und 2 Threads:

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

Und schreiben Sie in diese Datei:

[Slice]
MemoryMax=4G
CPUQuota=200%

(dann ausführen, um systemctl daemon-reloadanzuwenden)

Dies gilt für alle Benutzer, Sie können jedoch einzelne Benutzer überschreiben auf/etc/systemd/system/user-[uid].slice.d/50-memory.conf

(Ich denke, der Name der Conf-Datei spielt keine Rolle, bin mir aber nicht sicher)

verwandte Informationen