Wie kann ich cgroups verwenden, um alle Prozesse außer der Whitelist auf eine einzelne CPU zu beschränken?

26

Es gibt eine Anleitung zu Gruppen von Red Hat, die vielleicht irgendwie hilfreich ist (aber diese Frage nicht beantwortet).

Ich weiß, wie ich einen bestimmten Prozess auf eine bestimmte CPU beschränken kann, während ich diesen Prozess starte, indem ich:

Geben Sie zunächst Folgendes * ein /etc/cgconfig.conf:

mount {
  cpuset =  /cgroup/cpuset;
  cpu =     /cgroup/cpu;
  cpuacct = /cgroup/cpuacct;
  memory =  /cgroup/memory;
  devices = /cgroup/devices;
  freezer = /cgroup/freezer;
  net_cls = /cgroup/net_cls;
  blkio =   /cgroup/blkio;
}

group cpu0only {
  cpuset {
    cpuset.cpus = 0;
    cpuset.mems = 0;
  }
}

Starten Sie dann einen Prozess und weisen Sie ihn dieser Kontrollgruppe zu, indem Sie Folgendes verwenden:

cgexec -g cpuset:cpu0only myprocessname

Ich kann alle Instanzen eines bestimmten Prozessnamens automatisch einschränken, indem ich (meiner Meinung nach ) Folgendes eingebe /etc/cgrules.conf:

# user:process  controller  destination
*:myprocessname cpuset      cpu0only

Meine Frage ist: Wie kann ich das Gegenteil tun ?

Mit anderen Worten: Wie kann ich alle Prozesse mit Ausnahme einer bestimmten Gruppe von Prozessen auf der Whitelist und ihrer untergeordneten Prozesse einer eingeschränkten Kontrollgruppe zuordnen?


Basierend auf dem, was ich studiert, aber nicht getestet habe, glaube ich , dass eine Teillösung wäre:

Fügen Sie eine "uneingeschränkte" cgroup hinzu:

group anycpu {
  cpuset {
    cpuset.cpus = 0-31;
    cpuset.mems = 0;  # Not sure about this param but it seems to be required
  }
}

Weisen Sie meinen Prozess explizit der uneingeschränkten Gruppe und alles andere der eingeschränkten Gruppe zu:

# user:process  controller  destination
*:myprocessname cpuset      anycpu
*               cpuset      cpu0only

Der Vorbehalt dazu scheint jedoch (aus dem Lesen der Dokumente, nicht aus dem Testen, also Salzkorn) zu bestehen, dass die Kinder von myprocessnameder eingeschränkten cpu0onlycgroup neu zugeordnet werden.

Ein möglicher alternativer Ansatz wäre, einen Benutzer zu erstellen, der myprocessnamealle Prozesse dieses Benutzers ausführt und uneingeschränkt und alle anderen beschränkt. In meinem tatsächlichen Anwendungsfall muss der Prozess jedoch von root ausgeführt werden, und es gibt andere Prozesse, die ebenfalls von root ausgeführt werden müssen und die eingeschränkt werden sollten.

Wie kann ich das mit cgroups erreichen?


Wenn dies mit cgroups nicht möglich ist (was ich jetzt vermute), sind meine Vorstellungen von Teillösungen richtig und funktionieren sie so, wie ich denke?

* Haftungsausschluss: Dies ist wahrscheinlich kein minimales Codebeispiel, da ich nicht alle Teile verstehe und nicht weiß, welche nicht erforderlich sind.

Platzhalter
quelle

Antworten:

30

UPDATE: Beachten Sie, dass die folgende Antwort auf RHEL 6 zutrifft. In RHEL 7 werden die meisten cgroups von systemd verwaltet und libcgroup ist veraltet.


Seit der Veröffentlichung dieser Frage habe ich die gesamte Führungssucht , dass ich oben verbunden ist , sowie die Mehrheit der cgroups.txt Dokumentation und cpusets.txt . Ich weiß jetzt mehr, als ich jemals erwartet hatte, etwas über Gruppen zu lernen, daher beantworte ich hier meine eigene Frage.

Es gibt verschiedene Ansätze. Der Kontakt unseres Unternehmens bei Red Hat (ein technischer Architekt) empfahl, alle Prozesse pauschal gegenüber einem deklarativeren Ansatz einzuschränken und nur die Prozesse einzuschränken, die wir speziell einschränken wollten. Der Grund dafür ist, seinen Aussagen zu diesem Thema zufolge, dass Systemaufrufe von Benutzerbereichscode (wie LVM-Prozessen) abhängen können, der, wenn er eingeschränkt wird, das System verlangsamen kann - das Gegenteil des beabsichtigten Effekts. Also habe ich einige spezifisch benannte Prozesse eingeschränkt und alles andere in Ruhe gelassen.

Darüber hinaus möchte ich einige grundlegende Daten zu cgroup erwähnen , die mir beim Posten meiner Frage fehlten.


Cgroups sind nicht von libcgroupder Installation abhängig . Hierbei handelt es sich jedoch um eine Reihe von Tools, mit denen die Konfiguration von Gruppen und die Zuweisung von Prozessen zu Gruppen automatisch durchgeführt werden können. Diese Tools können sehr hilfreich sein.

Ich habe festgestellt, dass die libcgroup-Tools auch irreführend sein können, da das libcgroup-Paket auf eigenen Abstraktionen und Annahmen über die Verwendung von cgroups basiert, die sich geringfügig von der tatsächlichen Kernel-Implementierung von cgroups unterscheiden. (Ich kann Beispiele nennen, aber es würde einiges an Arbeit erfordern; kommentieren Sie, wenn Sie interessiert sind.)

Daher muss vor libcgroup Tool (zB /etc/cgconfig.conf, /etc/cgrules.conf, cgexec, cgcreate, cgclassify, etc.) ich sehr empfehlen sehr vertraut mit dem immer /cgroupvirtuellen Dateisystem selbst und manuell cgroups, cgroup Hierarchien (einschließlich Hierarchien mit mehreren Subsystemen befestigt, die libcgroup sneakily und leakily Abstracts zu schaffen away), Neuzuweisung von Prozessen zu verschiedenen cgroups durch Ausführen echo $the_pid > /cgroup/some_cgroup_hierarchy/a_cgroup_within_that_hierarchy/tasksund andere scheinbar magische Aufgaben, libcgroupdie unter der Haube ausgeführt werden.


Ein anderes Grundkonzept, das mir gefehlt hat, war, dass, wenn das /cgroupvirtuelle Dateisystem überhaupt auf Ihrem System eingehängt ist (oder genauer gesagt, wenn eines der cgroup-Subsysteme, auch "Controller" genannt, überhaupt eingehängt ist), jeder Prozess auf Ihrem gesamten System sich in einem befindet cgroup. Es gibt keine "einige Prozesse befinden sich in einer C-Gruppe und andere nicht".

Für eine bestimmte Hierarchie gibt es eine sogenannte Stamm- C-Gruppe, die alle Systemressourcen für die angeschlossenen Subsysteme besitzt. Zum Beispiel kann eine cgroup Hierarchie, die die CPU - Satz und blkio Subsysteme angebracht hat, würde eine Root - Kontrollgruppe haben , die Eigentümer würden alle die CPUs auf dem System und die gesamte blkio auf dem System, und könnten einige dieser Ressourcen teilen Kind cgroups. Sie können die Root-C-Gruppe nicht einschränken, da sie alle Ressourcen Ihres Systems besitzt , sodass eine Einschränkung nicht einmal sinnvoll wäre.


Einige andere einfache Daten, die ich über libcgroup vermisst habe:

Wenn Sie dies verwenden /etc/cgconfig.conf, sollten Sie sicherstellen, dass chkconfig --list cgconfigangezeigt wird, dass cgconfiges beim Systemstart ausgeführt wird.

Wenn Sie Änderungen vornehmen /etc/cgconfig.conf, müssen Sie ausführen service cgconfig restart, um die Änderungen zu laden. (Und Probleme mit dem Beenden oder Ausführen des Dienstes cgcleartreten häufig beim Herumalbern von Tests auf. Zum Debuggen empfehle ich beispielsweise lsof /cgroup/cpuset, wenn cpusetder Name der von Ihnen verwendeten cgroup-Hierarchie lautet.)

Wenn Sie verwenden möchten /etc/cgrules.conf, müssen Sie sicherstellen, dass der "cgroup rules engine daemon" ( cgrulesengd) ausgeführt wird: service cgred startund chkconfig cgred on. (Und Sie sollten sich eines möglichen, aber unwahrscheinlichen Rennzustands in Bezug auf diesen Service bewusst sein, wie im Red Hat Resource Management-Handbuch in Abschnitt 2.8.1 am Ende der Seite beschrieben.)

Wenn Sie manuell herumspielen und Ihre cgroups mit dem virtuellen Dateisystem einrichten möchten (das ich für die erste Verwendung empfehle), können Sie dies tun und dann eine cgconfig.confDatei erstellen , um Ihr Setup cgsnapshotmit den verschiedenen Optionen zu spiegeln .


Und zum Schluss die wichtigsten Informationen, die ich vermisst habe, als ich Folgendes schrieb:

Die Einschränkung hierbei scheint jedoch zu sein, dass die untergeordneten Elemente von myprocessname der eingeschränkten Gruppe cpu0only cgroup zugewiesen werden.

Ich hatte recht, aber es gibt eine Option, die ich nicht kannte.

cgexec ist der Befehl zum Starten eines Prozesses / Ausführen eines Befehls und Zuweisen zu einer Kontrollgruppe.

cgclassify ist der Befehl, um einer cgroup einen bereits laufenden Prozess zuzuweisen.

Beides verhindert auch, dass cgred( cgrulesengd) den angegebenen Prozess basierend auf einer anderen cgroup neu zuordnet /etc/cgrules.conf.

Sowohl cgexecund cgclassifyunterstützt die --stickyFlagge, die zusätzlich verhindert cgredvon Neuzuweisung Kind Prozessen basierend auf /etc/cgrules.conf.


Also, die Antwort auf die Frage , wie ich schrieb es (wenn auch nicht die Einrichtung ich Umsetzung endete aufgrund der Beratung durch unsere Red Hat Technical Architect siehe oben) ist:

Machen Sie die cpu0onlyund anycpucgroup wie in meiner Frage beschrieben. (Stellen Sie sicher cgconfig, dass beim Booten ausgeführt wird.)

Machen Sie die * cpuset cpu0onlyRegel wie in meiner Frage beschrieben. (Und stellen Sie sicher cgred, dass beim Booten ausgeführt wird.)

Starten Sie alle Prozesse Ich will uneingeschränkt mit: cgexec -g cpuset:anycpu --sticky myprocessname.

Diese Prozesse sind nicht eingeschränkt, und alle untergeordneten Prozesse sind ebenfalls nicht eingeschränkt. Alles andere auf dem System ist auf CPU 0 beschränkt (nach dem Neustart werden cgredkeine cgrules auf bereits laufende Prozesse angewendet, es sei denn, sie ändern ihre EUID). Dies ist nicht ganz ratsam, aber das war es, was ich anfangs angefordert habe und es kann mit cgroups gemacht werden.

Platzhalter
quelle
Wow. cool. Wie hatte dies 0 Stimmen?
mikeserv
@mikeserv, danke. :) Beantworten Sie Ihre Frage: Überprüfen Sie die Daten; Ich habe diese Antwort gestern geschrieben.
Wildcard
1
das habe ich gesehen. aber es war vor 24 Stunden. wahrscheinlich ist seine Ursache es ist lang. das gute Zeug kann manchmal so übersehen werden. und trotzdem sind die Antworten mit vielen Stimmen sehr bald sehr selten die guten - Informationen können nicht so nützlich sein, wenn so viele Leute es bereits wissen. Dies ist jedoch einer der Guten. Gruppen sind verdammt mysteriös.
mikeserv