Kontrollgruppen mit Systemd verwalten

Führt Cgroups-Konzepte in Oracle Linux ein und zeigt, wie systemd die Resource Control organisiert und verwaltet.

Kontrollgruppen, die als cgroups bezeichnet werden, sind ein Oracle Linux-Kernelfeature, das systemd-Services und bei Bedarf einzelne Prozesse (PIDs) in hierarchischen Gruppen für die Zuweisung von Systemressourcen wie CPU, Arbeitsspeicher und I/O organisiert.

Beispiel: Wenn Sie die CPU-Ressource im Verhältnis 150:100:50 auf drei systemd-Services, myservice1.service, myservice2.service und myservice3.service, aufteilen müssen, können Sie mit den Tools systemd jedem entsprechenden cgroup des Service eine CPU-Gewichtung zuweisen, die mit der Zielfreigabe übereinstimmt.

Hinweis

systemd ist für das Erstellen und Verwalten von cgroups im virtuellen Dateisystem /sys/fs/cgroup/ verantwortlich.

Die systemd-Suite bietet sichere, allgemeine Möglichkeiten zur Konfiguration von cgroup-Ressourcen, wie die Verwendung von Drop-in-Dateien oder dem Befehl systemctl set-property. Eine direkte Änderung systemd-Objekte im virtuellen Dateisystem /sys/fs/cgroup/ wird nicht empfohlen.

Standardmäßig erstellt systemd eine cgroup für Folgendes:

  • Jeder systemd-Service wird auf dem Host eingerichtet.

    Beispiel: Ein Server kann die Kontrollgruppe NetworkManager.service aufweisen, um Prozesse zu gruppieren, die dem Service NetworkManager gehören, und die Kontrollgruppe firewalld.service, um Prozesse zu gruppieren, die dem Service firewalld gehören, usw.

  • Jeder Benutzer (UID) auf dem Host.

Die Funktion cgroup wird als virtuelles Dateisystem unter /sys/fs/cgroup gemountet.

Jede cgroup verfügt über einen entsprechenden Ordner im Dateisystem /sys/fs/cgroup. Beispiel: Die cgroups, die von systemd für die verwalteten Services erstellt wurde, kann durch Ausführen des Befehls ls -l /sys/fs/cgroup/system.slice | grep ".service" angezeigt werden, wie im folgenden Beispielcodeblock dargestellt:

ls -l /sys/fs/cgroup/system.slice | grep ".service"
...root root 0 Mar 22 10:47 atd.service
...root root 0 Mar 22 10:47 auditd.service
...root root 0 Mar 22 10:47 chronyd.service
...root root 0 Mar 22 10:47 crond.service
...root root 0 Mar 22 10:47 dbus-broker.service
...root root 0 Mar 22 10:47 dtprobed.service
...root root 0 Mar 22 10:47 firewalld.service
...root root 0 Mar 22 10:47 httpd.service
...

Sie können auch benutzerdefinierte cgroups außerhalb der systemd Verzweigungen erstellen, z.B. unter einem Speicherort wie /sys/fs/cgroup/MyGroups/, und Prozess-IDs (PIDs) je nach Systemanforderungen verschiedenen cgroups zuweisen. Dieser Ansatz sollte jedoch nur für bestimmte Szenarien wie temporäres Debugging oder Testen verwendet werden. Für die meisten Anwendungsfälle wird empfohlen, systemd zu verwenden, um cgroups zu konfigurieren, um eine korrekte und persistente Ressourcenverwaltung sicherzustellen.

Oracle Linux bietet zwei Arten von Kontrollgruppen:

Kontrollgruppen Version 1 (cgroups v1)

Diese Gruppen stellen eine Controller-Hierarchie pro Ressource bereit.

Jede Ressource, wie CPU, Arbeitsspeicher, I/O usw., verfügt über eine eigene Kontrollgruppenhierarchie. Ein Nachteil dieser Gruppe ist die Schwierigkeit, eine angemessene Koordinierung der Ressourcennutzung zwischen Gruppen zu schaffen, die zu verschiedenen Prozesshierarchien gehören könnten.

Kontrollgruppen Version 2 (cgroups v2))

Diese Gruppen stellen eine einzelne Kontrollgruppenhierarchie bereit, für die alle Resource Controller gemountet sind. In dieser Hierarchie können Sie eine bessere Koordination der Ressourcennutzung über verschiedene Ressourcencontroller hinweg erhalten. Diese Version ist eine Verbesserung gegenüber cgroups v1, deren Überflexibilität eine ordnungsgemäße Koordination der Ressourcennutzung zwischen den Systemkonsumenten verhindert hat.

Oracle Linux 8 umfasst beide Versionen, wobei cgroups v1 standardmäßig aktiviert und gemountet ist. Oracle Linux 9 stellt auch beide Versionen bereit, aktiviert und mountet jedoch standardmäßig cgroups v2.

Oracle Linux 10 bietet nur die Implementierung der Kontrollgruppenversion 2. cgroups v1 ist veraltet und nicht verfügbar. cgroups v2 ist standardmäßig aktiviert und gemountet.

Weitere Informationen zu Kontrollgruppen finden Sie auf den manuellen Seiten cgroups(7) und sysfs(5).

Informationen zu Kontrollgruppen und systemd

Kontrollgruppen können vom System und Service-Manager systemd für die RessourcenAdministration verwendet werden. systemd verwendet diese Gruppen, um Einheiten und Services zu organisieren, die Ressourcen verbrauchen. Weitere Informationen zu systemd finden Sie unter Managing the System With systemd.

systemd stellt verschiedene Einheitentypen bereit, von denen drei für die Ressourcensteuerung verwendet werden:

  • Service: Ein Prozess oder eine Gruppe von Prozessen, deren Einstellungen auf einer Unit-Konfigurationsdatei basieren. Services umfassen angegebene Prozesse in einer "Collection", sodass systemd die Prozesse als ein Set starten oder stoppen kann. Servicenamen haben das Format name.service.

  • Geltungsbereich: Eine Gruppe von extern erstellten Prozessen, wie Benutzersessions, Container, virtuelle Maschinen usw.

    Ähnlich wie bei Services kapseln Geltungsbereiche diese erstellten Prozesse. Sie werden von den willkürlichen Prozessen gestartet oder gestoppt und dann zur Laufzeit von systemd registriert. Geltungsbereichsnamen entsprechen dem Format name.scope.

  • Bereich: Eine Gruppe von hierarchisch organisierten Einheiten, in denen sich Services und Geltungsbereiche befinden.

    Daher enthalten die Abschnitte selbst keine Prozesse. Vielmehr definieren die Geltungsbereiche und Services in einem Bereich die Prozesse. Jeder Name einer Bereichseinheit entspricht dem Pfad zu einer Position in der Hierarchie. Root-Bereiche, in der Regel user.slice für alle benutzerbasierten Prozesse und system.slice für systembasierte Prozesse, werden automatisch in der Hierarchie erstellt. Übergeordnete Bereiche sind direkt unter dem Root-Bereich vorhanden und folgen dem Format parent-name.slice. Diese Root-Bereiche können dann Teilbereiche auf mehreren Ebenen aufweisen.

Der Service, der Geltungsbereich und die Bereichseinheiten werden Objekten in der Kontrollgruppenhierarchie direkt zugeordnet. Wenn diese Einheiten aktiviert sind, werden sie direkt Kontrollgruppenpfaden zugeordnet, die aus den Einheitennamen erstellt werden. Um die Zuordnung zwischen den Ressourceneinheitstypen und Steuerungsgruppen systemd anzuzeigen, geben Sie Folgendes ein:

sudo systemd-cgls
Working directory /sys/fs/cgroup:
├─user.slice (#1243)
│ → trusted.invocation_id: 50ce3909b2644f919ee420adc39edb4b
│ ├─user-1001.slice (#4167)
│ │ → trusted.invocation_id: 02e80a960d4549a7a9c69ce0fb546c26
│ │ ├─session-2.scope (#4405)
│ │ │ ├─2417 sshd: alice [priv]
│ │ │ ├─2430 sshd: alice@pts/0
│ │ │ ├─2431 -bash
│ │ │ ├─2689 sudo systemd-cgls
│ │ │ ├─2691 systemd-cgls
│ │ │ └─2692 less
...
│   └─user@984.service … (#3827)
│     → trusted.delegate: 1
│     → trusted.invocation_id: 09b47ce9f3124239b75814114353f3f2
│     └─init.scope (#3861)
│       ├─2058 /usr/lib/systemd/systemd --user
│       └─2099 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
└─system.slice (#53)
...
  ├─chronyd.service (#2467)
  │ → trusted.invocation_id: c0f77aaa9c7844e6bef6a6898ae4dd56
  │ └─1358 /usr/sbin/chronyd -F 2
  ├─auditd.service (#2331)
  │ → trusted.invocation_id: 756808add6a348609316c9e8c1801846
  │ └─1310 /sbin/auditd
  ├─tuned.service (#3079)
  │ → trusted.invocation_id: 2c358135fc46464d862b05550338d4f4
  │ └─1415 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
  ├─systemd-journald.service (#1651)
  │ → trusted.invocation_id: 7cb7ccb14e044a899aadf47bbb583ada
  │ └─977 /usr/lib/systemd/systemd-journald
  ├─atd.service (#3623)
  │ → trusted.invocation_id: 597a7a4e5646468db407801b8562d869
  │ └─1915 /usr/sbin/atd -f
  ├─sshd.service (#3419)
  │ → trusted.invocation_id: 490504a683fc4311ab0fbeb0864a1a34
  │ └─1871 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
...

Ein Beispiel für die Verwendung von systemd-Befehlen wie systemctl zur Verwaltung von Ressourcen finden Sie unter Zugriff auf Systemressourcen steuern. Weitere technische Details finden Sie auf den Handbuchseiten systemctl(1), systemd-cgls(1) und systemd.resource-control(5).

cgroups v2 mit systemd verwalten

Zeigt, wie systemd-Strukturen cgroups v2 für Services und Benutzer und wie die Hierarchie geprüft wird.

Die bevorzugte Methode für die Verwaltung der Ressourcenzuweisung mit cgroups v2 ist die Verwendung der von systemd bereitgestellten Kontrollgruppenfunktionalität.

Hinweis

Informationen zum Aktivieren der Funktion cgroups v2 im System finden Sie unter Ressourcen mit Kontrollgruppen verwalten.

Standardmäßig erstellt systemd einen Ordner cgroup für jeden systemd-Service, der auf dem Host eingerichtet ist. systemd benennt diese Ordner im Format servicename.service, wobei servicename der Name des Service ist, der mit dem Ordner verknüpft ist.

Um eine Liste der cgroup-Ordner anzuzeigen, die systemd für die Services erstellt, führen Sie den Befehl ls in der Verzweigung system.slice des cgroup-Dateisystems aus, wie im folgenden Beispielcodeblock dargestellt:

ls /sys/fs/cgroup/system.slice/
...                     ...                           ...
app_service1.service    cgroup.subtree_control        httpd.service
app_service2.service    chronyd.service               ...  
...                     crond.service                 ...
cgroup.controllers      dbus-broker.service           ...
cgroup.events           dtprobed.service              ...
cgroup.freeze           firewalld.service             ...
...                     gssproxy.service              ...
...                     ...                           ...

Im vorherigen Befehlsblock:

  • Die Ordner app_service1.service und app_service2.service stellen benutzerdefinierte Anwendungsservices dar, die auf dem System ausgeführt werden können.

Zusätzlich zu den Servicekontrollgruppen erstellt systemd auch einen Ordner cgroup für jeden Benutzer auf dem Host.

Um die cgroups anzuzeigen, die für jeden Benutzer erstellt wurde, können Sie den Befehl ls in der Verzweigung user.slice des Dateisystems cgroup ausführen, wie im folgenden Beispielcodeblock dargestellt:

ls /sys/fs/cgroup/user.slice/
cgroup.controllers      cgroup.subtree_control        user-1001.slice
cgroup.events           cgroup.threads                user-982.slice
cgroup.freeze           cgroup.type                   ...
...                     ...                           ...
...                     ...                           ...
...                     ...                           ...

Im vorhergehenden Codeblock:

  • Jeder Benutzerordner cgroup wird im Format user-UID.slice benannt. Die Kontrollgruppe user-1001.slice gilt also für einen Benutzer, dessen UID beispielsweise 1001 ist.

systemd bietet allgemeinen Zugriff auf die Funktionen cgroups und Kernel-Ressourcencontroller, sodass Sie nicht direkt auf das Dateisystem zugreifen müssen.

Beispiel: Um die CPU-Gewichtung eines Service mit dem Namen app_service1.service festzulegen, führen Sie den Befehl systemctl set-property wie folgt aus:

sudo systemctl set-property app_service1.service CPUWeight=150

Somit können Sie mit systemd die Ressourcenverteilung auf Anwendungsebene und nicht auf der Prozess-PID-Ebene verwalten, die bei der Konfiguration von cgroups ohne Verwendung der systemd-Funktionalität verwendet wird.

Informationen zu Bereichen und Ressourcenzuteilung in systemd

In diesem Abschnitt wird untersucht, wie systemd zunächst jeden der Standard-Kernelcontroller, z.B. CPU, memory und blkio, in Teile unterteilt, die als "Bereiche" bezeichnet werden, wie im folgenden Beispiel-Tortendiagramm dargestellt:

Hinweis

Sie können auch benutzerdefinierte Bereiche für die Ressourcenverteilung erstellen, wie im Abschnitt Resource Controller-Optionen festlegen und benutzerdefinierte Bereiche erstellen dargestellt.

Tortendiagramm mit 3 gleich großen Bereichen, mit der Bezeichnung System, Maschine und Benutzer. Benutzer und System sind weiter in Unterbereiche unterteilt.

Wie das vorstehende Tortendiagramm zeigt, wird jeder Resource Controller standardmäßig gleichmäßig auf die folgenden 3 Bereiche aufgeteilt:

  • System (system.slice).

  • Benutzer (user.slice).

  • Maschine (machine.slice).

In der folgenden Liste werden die einzelnen Bereiche genauer betrachtet. Zur Erörterung konzentrieren sich die Beispiele in der Liste auf den CPU-Controller.

System (system.slice)

Dieser Ressourcenbereich dient zur Verwaltung der Ressourcenzuteilung zwischen Daemons und Serviceeinheiten.

Wie im vorherigen Beispiel-Tortendiagramm dargestellt, wird das Systemsegment in weitere Unterabschnitte unterteilt. Beispiel: Bei CPU-Ressourcen können innerhalb des Systembereichs Unterbereiche zugewiesen werden, die Folgendes umfassen:
  • httpd.service (CPUWeight=100)

  • sshd.service (CPUWeight =100)

  • crond.service (CPUWeight =100)

  • app1.service (CPUWeight =100)

  • app2.service (CPUWeight =100)

In der obigen Liste stellen app1.service und app2.service benutzerdefinierte Anwendungsservices dar, die auf dem System ausgeführt werden können.
Benutzer (user.slice)
Dieser Ressourcenbereich dient zur Verwaltung der Ressourcenzuweisung zwischen Benutzersessions. Für jede UID wird ein einzelner Bereich erstellt, unabhängig davon, wie viele Anmeldungen der verknüpfte Benutzer auf dem Server aktiv hat. Wenn Sie mit unserem Tortendiagrammbeispiel fortfahren, können die Unterbereiche wie folgt aussehen:
  • user1 (CPUWeight=100, UID=982)

  • user2 (CPUWeight=100, UID=1001)

Maschine (machine.slice)
Dieser Bereich der Ressource wird zur Verwaltung der Ressourcenzuweisung zwischen gehosteten virtuellen Maschinen wie KVM-Gästen und Linux-Containern verwendet. Der Computerbereich ist nur auf einem Server vorhanden, wenn der Server virtuelle Maschinen oder Linux-Container hostet.
Hinweis

Für Share-Zuweisungen wird kein maximaler Grenzwert für eine Ressource festgelegt.

In den vorherigen Beispielen hat der Bereich user.slice 2 Benutzer: user1 und user2. Jedem Benutzer wird ein gleicher Anteil der CPU-Ressource zugewiesen, die für das übergeordnete Element user.slice verfügbar ist. Wenn die mit user1 verknüpften Prozesse jedoch im Leerlauf sind und keine CPU-Ressource erforderlich ist, ist deren CPU-Share bei Bedarf für die Zuweisung zu user2 verfügbar. In einem solchen Fall kann user2 sogar die gesamte CPU-Ressource zugewiesen werden, die der übergeordneten user.slice zugeordnet ist, wenn sie von anderen Benutzern benötigt wird.

Um die CPU-Ressource zu begrenzen, müssen Sie die Eigenschaft CPUQuota auf den erforderlichen Prozentsatz setzen.

Bereiche, Services und Geltungsbereiche in der Cgroup-Hierarchie

Die in den vorhergehenden Abschnitten verwendete Tortendiagramm-Analogie ist eine hilfreiche Möglichkeit, die Aufteilung von Ressourcen in Abschnitte zu konzeptualisieren. In Bezug auf die strukturelle Organisation sind die Kontrollgruppen jedoch in einer Hierarchie angeordnet. Sie können die Kontrollgruppenhierarchie systemd auf dem System anzeigen, indem Sie den Befehl systemd-cgls wie folgt ausführen:

Tipp

Um die gesamte cgroup-Hierarchie ab dem Root-Bereich -.slice wie im folgenden Beispiel anzuzeigen, stellen Sie sicher, dass Sie systemd-cgls außerhalb des Einhängepunkts der Kontrollgruppe /sys/fs/cgroup/ ausführen.

Wenn Sie den Befehl in /sys/fs/cgroup/ ausführen, beginnt die Ausgabe am cgroup-Speicherort, von dem aus der Befehl ausgeführt wurde. Weitere Informationen finden Sie unter systemd-cgls(1).

systemd-cgls
Control group /:
-.slice
...
├─user.slice (#1429)
│ → user.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
│ ├─user-982.slice (#4131)
│ │ → user.invocation_id: 9d0d94d7b8a54bcea2498048911136c8
│ │ ├─session-c1.scope (#4437)
│ │ │ ├─2416 /usr/bin/sudo -u ocarun /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
│ │ │ └─2494 /usr/libexec/oracle-cloud-agent/plugins/runcommand/runcommand
│ │ └─user@982.service … (#4199)
│ │   → user.delegate: 1
│ │   → user.invocation_id: 37c7aed7aa6e4874980b79616acf0c82
│ │   └─init.scope (#4233)
│ │     ├─2437 /usr/lib/systemd/systemd --user
│ │     └─2445 (sd-pam)
│ └─user-1001.slice (#7225)
│   → user.invocation_id: ce93ad5f5299407e9477964494df63b7
│   ├─session-2.scope (#7463)
│   │ ├─20304 sshd: oracle [priv]
│   │ ├─20404 sshd: oracle@pts/0
│   │ ├─20405 -bash
│   │ ├─20441 systemd-cgls
│   │ └─20442 less
│   └─user@1001.service … (#7293)
│     → user.delegate: 1
│     → user.invocation_id: 70284db060c1476db5f3633e5fda7fba
│     └─init.scope (#7327)
│       ├─20395 /usr/lib/systemd/systemd --user
│       └─20397 (sd-pam)
├─init.scope (#19)
│ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 28
└─system.slice (#53)
 ...
  ├─dbus-broker.service (#2737)
  │ → user.invocation_id: 2bbe054a2c4d49809b16cb9c6552d5a6
  │ ├─1450 /usr/bin/dbus-broker-launch --scope system --audit
  │ └─1457 dbus-broker --log 4 --controller 9 --machine-id 852951209c274cfea35a953ad2964622 --max-bytes 536870912 --max-fds 4096 --max-matches 131072 --audit
 ...
  ├─chronyd.service (#2805)
  │ → user.invocation_id: e264f67ad6114ad5afbe7929142faa4b
  │ └─1482 /usr/sbin/chronyd -F 2
  ├─auditd.service (#2601)
  │ → user.invocation_id: f7a8286921734949b73849b4642e3277
  │ ├─1421 /sbin/auditd
  │ └─1423 /usr/sbin/sedispatch
  ├─tuned.service (#3349)
  │ → user.invocation_id: fec7f73678754ed687e3910017886c5e
  │ └─1564 /usr/bin/python3 -Es /usr/sbin/tuned -l -P
  ├─systemd-journald.service (#1837)
  │ → user.invocation_id: bf7fb22ba12f44afab3054aab661aedb
  │ └─1068 /usr/lib/systemd/systemd-journald
  ├─atd.service (#3961)
  │ → user.invocation_id: 1c59679265ab492482bfdc9c02f5eec5
  │ └─2146 /usr/sbin/atd -f
  ├─sshd.service (#3757)
  │ → user.invocation_id: 57e195491341431298db233e998fb180
  │ └─2097 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
  ├─crond.service (#3995)
  │ → user.invocation_id: 4f5b380a53db4de5adcf23f35d638ff5
  │ └─2150 /usr/sbin/crond -n
  ...

Die vorhergehende Beispielausgabe zeigt, wie sich alle "*.slice"-Kontrollgruppen unter dem Root-Bereich -.slice befinden. Unter dem Root-Bereich werden die Kontrollgruppen user.slice und system.slice angezeigt, die jeweils ihre eigenen untergeordneten cgroup-Unterbereiche haben.

Wenn Sie die Ausgabe des Befehls systemd-cgls untersuchen, können Sie sehen, wie sich mit Ausnahme von Root -.slice alle Prozesse auf Blattknoten befinden. Diese Anordnung wird durch cgroups v2 in einer Regel erzwungen, die als Regel "keine internen Prozesse" bezeichnet wird. Weitere Informationen zur Regel "keine internen Prozesse" finden Sie unter cgroups (7).

Die Ausgabe im vorherigen systemd-cgls Befehlsbeispiel zeigt auch, wie Bereiche untergeordnete Kontrollgruppen haben können, die systemd-Geltungsbereiche sind. systemd-Geltungsbereiche werden im folgenden Abschnitt geprüft.

systemd Geltungsbereiche

Der Geltungsbereich systemd ist ein Einheitstyp systemd, der Systemservice-Worker-Prozesse gruppiert, die unabhängig von systemd gestartet wurden. Die Geltungsbereichseinheiten sind transiente cgroups, die programmgesteuert mit den Busschnittstellen von systemd erstellt werden.

Beispiel: Im folgenden Beispielcode hat der Benutzer mit UID 1001 den Befehl systemd-cgls ausgeführt, und die Ausgabe zeigt, dass session-2.scope für Prozesse erstellt wurde, die der Benutzer unabhängig von systemd gestartet hat (einschließlich des Prozesses für den Befehl selbst, 21380 sudo systemd-cgls):

Hinweis

Im folgenden Beispiel wurde der Befehl im Mount Point der Kontrollgruppe /sys/fs/cgroup/ ausgeführt. Daher beginnt die Ausgabe anstelle des Root-Bereichs am cgroup-Speicherort, von dem aus der Befehl ausgeführt wurde.
sudo systemd-cgls
Working directory /sys/fs/cgroup:
...
├─user.slice (#1429)
│ → user.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
│ → trusted.invocation_id: 604cf5ef07fa4bb4bb86993bb5ec15e0
...
│ └─user-1001.slice (#7225)
│   → user.invocation_id: ce93ad5f5299407e9477964494df63b7
│   → trusted.invocation_id: ce93ad5f5299407e9477964494df63b7
│   ├─session-2.scope (#7463)
│   │ ├─20304 sshd: oracle [priv]
│   │ ├─20404 sshd: oracle@pts/0
│   │ ├─20405 -bash
│   │ ├─21380 sudo systemd-cgls
│   │ ├─21382 systemd-cgls
│   │ └─21383 less
│   └─user@1001.service … (#7293)
│     → user.delegate: 1
│     → trusted.delegate: 1
│     → user.invocation_id: 70284db060c1476db5f3633e5fda7fba
│     → trusted.invocation_id: 70284db060c1476db5f3633e5fda7fba
│     └─init.scope (#7327)
│       ├─20395 /usr/lib/systemd/systemd --user
│       └─20397 (sd-pam)

Resource Controller-Optionen festlegen und benutzerdefinierte Bereiche erstellen

Demonstriert drei Ansätze – Unit-Dateien, Drop-ins und systemctl set-property – für die Feinabstimmung von Resource Controllern und Slice-Layouts.

systemd bietet die folgenden Methoden zum Festlegen von Ressourcencontrolleroptionen, wie CPUWeight, CPUQuota usw., zum Anpassen der Ressourcenzuweisung auf dem System:

  • Diensteinheitendateien werden verwendet.

  • Drop-in-Dateien verwenden.

  • Verwenden Sie den Befehl systemctl set-property.

Die folgenden Abschnitte enthalten Beispielverfahren für die Verwendung jeder dieser Methoden zur Konfiguration von Ressourcen und Bereichen im System.

Serviceeinheitendateien verwenden

So legen Sie Optionen in einer Serviceeinheitendatei fest:

  1. Erstellen Sie die Datei /etc/systemd/system/myservice1.service mit dem folgenden Inhalt:
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
  2. Für den im vorherigen Schritt erstellten Service ist ein bash-Skript /usr/lib/systemd/generate_load.sh erforderlich. Erstellen Sie die Datei mit folgendem Inhalt:
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  3. Führen Sie das Skript aus:
    sudo chmod +x /usr/lib/systemd/generate_load.sh
  4. Aktivieren und starten Sie den Service:
    sudo systemctl enable myservice1 --now
  5. Führen Sie den Befehl systemd-cgls aus, und prüfen Sie, ob der Service myservice1 unter system.slice ausgeführt wird:
    systemd-cgls
    Control group /:
    -.slice
    ...
    ├─user.slice (#1429)
    ...
    └─system.slice (#53)
      ...
      ├─myservice1.service (#7939)
      │ → user.invocation_id: e227f8f288444fed92a976d391e6a897
      │ ├─22325 /bin/bash /usr/lib/systemd/generate_load.sh
      │ ├─22326 /bin/bash /usr/lib/systemd/generate_load.sh
      │ ├─22327 /bin/bash /usr/lib/systemd/generate_load.sh
      │ └─22328 /bin/bash /usr/lib/systemd/generate_load.sh
      ├─pmie.service (#4369)
      │ → user.invocation_id: 68fcd40071594481936edf0f1d7a8e12
       ...
  6. Erstellen Sie einen benutzerdefinierten Bereich für den Service.

    Fügen Sie die Zeile Slice=my_custom_slice.slice zum Abschnitt [Service] in der Datei myservice1.service hinzu, die in einem vorherigen Schritt erstellt wurde, wie im folgenden Codeblock gezeigt:

    [Service]
    Slice=my_custom_slice.slice
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    
    [Install]
    WantedBy=multi-user.target
    
    Aufmerksamkeit

    Verwenden Sie Unterstriche anstelle von Bindestrichen, um Begriffe in Bereichsnamen zu trennen.

    In systemd ist ein Bindestrich in einem Bereichsnamen ein Sonderzeichen: In systemd werden Bindestriche in Bereichsnamen verwendet, um den vollständigen cgroup-Pfad zum Bereich zu beschreiben (ab dem Root-Bereich).

    Beispiel: Wenn Sie einen Bereichsnamen als "my-custom-slice.slice" angeben, erstellt systemd anstelle eines Bereichs mit diesem Namen den folgenden cgroups-Pfad unter dem Root-Bereich: my.slice/my-custom.slice/my-custom-slice.slice.

  7. Stellen Sie nach dem Bearbeiten der Datei sicher, dass systemd die Konfigurationsdateien neu lädt und dann den Service neu startet:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
  8. Führen Sie den Befehl systemd-cgls aus, und bestätigen Sie, dass der Service myservice1 jetzt unter dem benutzerdefinierten Bereich my_custom_slice ausgeführt wird:
    systemd-cgls
    Control group /:
    -.slice
    ...
    ├─user.slice (#1429)
    ...
    ├─my_custom_slice.slice (#7973)
    │ → user.invocation_id: a8a493a8db1342be85e2cdf1e80255f8
    │ └─myservice1.service (#8007)
    │   → user.invocation_id: 9a4a6171f2844e479d4a0f347aac38ce
    │   ├─22385 /bin/bash /usr/lib/systemd/generate_load.sh
    │   ├─22386 /bin/bash /usr/lib/systemd/generate_load.sh
    │   ├─22387 /bin/bash /usr/lib/systemd/generate_load.sh
    │   └─22388 /bin/bash /usr/lib/systemd/generate_load.sh
    ├─init.scope (#19)
    │ └─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 28
    └─system.slice (#53)
      ├─irqbalance.service (#2907)
      │ → user.invocation_id: 00d64c9b9d224f179496a83536dd60bb
      │ └─1464 /usr/sbin/irqbalance --foreground
     ...
    

Drop-in-Dateien verwenden

Um Ressourcen mit einer Drop-in-Datei zu konfigurieren, gehen Sie wie folgt vor:

  1. Erstellen Sie das Verzeichnis für Ihre Service-Drop-in-Datei.
    Tipp

    Das "drop-in"-Verzeichnis für Drop-in-Dateien für einen Service befindet sich unter /etc/systemd/system/service_name.service.d, wobei service_name der Name des Service ist.

    Wenn Sie mit dem Beispiel für Service myservice1 fortfahren, führen Sie den folgenden Befehl aus:

    sudo mkdir -p /etc/systemd/system/myservice1.service.d/
  2. Erstellen Sie 2 Drop-in-Dateien mit dem Namen 00-slice.conf und 10-CPUSettings.conf im Verzeichnis myservice1.service.d, das im vorherigen Schritt erstellt wurde.
    Hinweis

    • Mehrere Drop-in-Dateien mit unterschiedlichen Namen werden in lexikografischer Reihenfolge angewendet.

    • Diese Drop-in-Dateien haben Vorrang vor der Service Unit-Datei.

  3. Fügen Sie den folgenden Inhalt zu 00-slice.conf hinzu.
    [Service]
    Slice=my_custom_slice2.slice
    MemoryAccounting=yes
    CPUAccounting=yes
    

    Die Bereichseinstellung Slice=my_custom_slice2.slice in der Drop-in-Datei hat Vorrang vor dem Eintrag Slice=my_custom_slice.slice, der der Serviceeinheitendatei in einem früheren Schritt hinzugefügt wurde.

  4. Fügen Sie den folgenden Inhalt zu 10-CPUSettings.conf hinzu.
    [Service]
    CPUWeight=200
    
  5. Erstellen Sie einen zweiten Service (myservice2), und weisen Sie ihm einen anderen CPUWeight zu, der myservice1 zugewiesen ist:
    1. Erstellen Sie die Datei /etc/systemd/system/myservice2.service mit dem folgenden Inhalt:
      [Service]
      Slice=my_custom_slice2.slice
      Type=oneshot
      ExecStart=/usr/lib/systemd/generate_load2.sh
      TimeoutSec=0
      StandardOutput=tty
      RemainAfterExit=yes
      
      [Install]
      WantedBy=multi-user.target
    2. Für den im vorherigen Schritt erstellten Service ist ein bash-Skript /usr/lib/systemd/generate_load2.sh erforderlich. Erstellen Sie die Datei mit folgendem Inhalt:
      #!/bin/bash
      for i in {1..4};do while : ; do : ; done & done
    3. Führen Sie das Skript aus:
      sudo chmod +x /usr/lib/systemd/generate_load2.sh
    4. Erstellen Sie ein Drop in file /etc/systemd/system/myservice2.service.d/10-CPUSettings.conf für myservice2 mit folgendem Inhalt:
      [Service]
      CPUWeight=400
      
  6. Stellen Sie sicher, dass systemd seine Konfigurationsdateien neu lädt und myservice1 neu startet. Aktivieren und starten Sie außerdem myservices2:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl enable myservice2 --now
  7. Führen Sie den Befehl systemd-cgtop aus, um Kontrollgruppen nach ihrer Ressourcennutzung sortiert anzuzeigen. In der folgenden Beispielausgabe wird gezeigt, wie der Befehl systemd-cgtop neben der Ressourcennutzung der einzelnen Bereiche auch die Ressourcennutzung innerhalb der einzelnen Bereiche anzeigt. So können Sie bestätigen, dass die CPU-Gewichtung wie erwartet aufgeteilt wurde.
    systemd-cgtop
    Control Group                                     Tasks   %CPU   Memory  Input/s Output/s
    /                                                   228  198.8   712.5M        -        -
    my_custom_slice2.slice                                8  198.5     1.8M        -        -
    my_custom_slice2.slice/myservice2.service             4  132.8   944.0K        -        -
    my_custom_slice2.slice/myservice1.service             4   65.6   976.0K        -        -
    user.slice                                           18    0.9    43.9M        -        -
    user.slice/user-1001.slice                            6    0.9    13.7M        -        -
    user.slice/user-1001.slice/session-2.scope            4    0.9     9.4M        -        -
    system.slice                                         60    0.0   690.8M        -        -
    

Verwendung von systemctl set-property

Mit dem Befehl systemctl set-property werden die Konfigurationsdateien in folgendem Verzeichnis abgelegt:

/etc/systemd/system.control
Achtung

Sie dürfen die vom Befehl "systemctl set-property" erstellten Dateien nicht manuell bearbeiten.

Hinweis

Der Befehl systemctl set-property erkennt nicht jede Resource-Control-Eigenschaft, die in den zuvor in diesem Thema behandelten Dateien mit system-unit und drop-in verwendet wird.

Das folgende Verfahren zeigt, wie Sie mit dem Befehl systemctl set-property die Ressourcenzuweisung konfigurieren können:

  1. Wenn Sie mit unserem Beispiel fortfahren, erstellen Sie eine weitere Servicedatei im Verzeichnis /etc/systemd/system/myservice3.service mit folgendem Inhalt:
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/generate_load3.sh
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    [Install]
    WantedBy=multi-user.target
  2. Setzen Sie den Bereich für den Service auf my_custom_slice2 (den gleichen Bereich, der von den Services verwendet wird, die aus früheren Schritten erstellt wurden), indem Sie die folgende Zeile zum Abschnitt [Service] in der Datei myservice3.service hinzufügen:
    Slice=my_custom_slice2.slice
    Hinweis

    Der Bereich muss in der Service-Unit-Datei festgelegt werden, da der Befehl systemctl set-property die Eigenschaft Slice nicht erkennt.

  3. Für den im vorherigen Schritt erstellten Service ist ein bash-Skript /usr/lib/systemd/generate_load3.sh erforderlich. Erstellen Sie die Datei mit folgendem Inhalt:
    #!/bin/bash
    for i in {1..4};do while : ; do : ; done & done
  4. Führen Sie das Skript aus:
    sudo chmod +x /usr/lib/systemd/generate_load3.sh
  5. Stellen Sie sicher, dass systemd seine Konfigurationsdateien neu lädt, und aktivieren und starten Sie den Service:
    sudo systemctl daemon-reload
    sudo systemctl enable myservice3 --now
  6. Führen Sie systemd-cgtop aus, um zu bestätigen, dass alle 3 Services myservice1, myservice2 und myservice3 im selben Bereich ausgeführt werden.
  7. Verwenden Sie den Befehl systemctl set-property, um CPUWeight für myservice3 auf 800 festzulegen:
    sudo systemctl set-property myservice3.service CPUWeight=800
  8. Bestätigen Sie, dass unter /etc/systemd/system.control/myservice3.service.d eine Drop-in-Datei für Sie erstellt wurde. Sie dürfen die Datei jedoch nicht bearbeiten:
    cat /etc/systemd/system.control/myservice3.service.d/50-CPUWeight.conf
    # This is a drop-in unit file extension, created via "systemctl set-property"
    # or an equivalent operation. Do not edit.
    [Service]
    CPUWeight=800
    
  9. Stellen Sie sicher, dass systemd seine Konfigurationsdateien neu lädt und alle Services neu startet:
    sudo systemctl daemon-reload
    sudo systemctl restart myservice1
    sudo systemctl restart myservice2
    sudo systemctl restart myservice3
  10. Führen Sie den Befehl systemd-cgtop aus, um zu bestätigen, dass die CPU-Gewichtung wie erwartet aufgeteilt wurde:
    systemd-cgtop
    Control Group                                         Tasks   %CPU   Memory  Input/s Output/s
    /                                                       235  200.0   706.1M        -        -
    my_custom_slice2.slice                                   12  198.4     2.9M        -        -
    my_custom_slice2.slice/myservice3.service                 4  112.7   976.0K        -        -
    my_custom_slice2.slice/myservice2.service                 4   56.9   996.0K        -        -
    my_custom_slice2.slice/myservice1.service                 4   28.8   988.0K        -        -
    user.slice                                               18    0.9    44.1M        -        -
    user.slice/user-1001.slice                                6    0.9    13.9M        -        -
    user.slice/user-1001.slice/session-2.scope                4    0.9     9.5M        -        -