cgroups v2 bronlimieten met systemd
11 min lezen - 3 juni 2026

CPU-, geheugen- en I/O-limieten instellen met cgroups v2 en systemd. Praktische configuratie voor multi-tenant Linux hosts, met PSI monitoring en slice-isolatie.
cgroups v2-bronlimieten met systemd
cgroups v2 is het uniforme raamwerk voor resourcebeheer van de Linux-kernel. Het vervangt de gefragmenteerde v1-hiërarchie door een enkele boomstructuur die CPU, geheugen en I/O consistent afhandelt, en vormt de basis voor containerisolatie in Docker, Kubernetes en systemd. Dit bericht behandelt hoe u cgroups v2 inschakelt, limieten instelt via systemd en dit toepast op echte multi-tenant hostingscenario's.
Cgroups v2 inschakelen
Moderne distributies worden standaard geleverd met cgroups v2 ingeschakeld: Ubuntu 21.10+, Debian 11+, Fedora 31+ en RHEL/Rocky 9+. Oudere systemen kunnen een hybride hiërarchie gebruiken of nog steeds standaard v1 gebruiken. Controleer dit met:
stat -fc %T /sys/fs/cgroup/
De uitvoer van cgroup2fs bevestigt dat v2 actief is. tmpfs betekent doorgaans v1.
Om een hybride systeem om te schakelen naar puur v2, bewerk /etc/default/grub en voeg het volgende toe aan GRUB_CMDLINE_LINUX_DEFAULT:
systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all
Genereer vervolgens GRUB opnieuw en start opnieuw op:
sudo update-grub
sudo reboot
Gebruik voor productie kernel 5.2 of nieuwer, zodat je de cgroup-freezer voor v2 krijgt, en systemd 244+ voor volledige cpuset delegatie. Op Rocky Linux 8 en RHEL 8 moet u mogelijk ook accounting expliciet inschakelen door deze regels toe te voegen aan /etc/systemd/system.conf:
DefaultCPUAccounting=yes
DefaultMemoryAccounting=yes
DefaultIOAccounting=yes
Herlaad met sudo systemctl daemon-reexec. Controleer na het opnieuw opstarten welke controllers beschikbaar zijn:
cat /sys/fs/cgroup/cgroup.controllers
U zou cpu, memory, io, en pids vermeld. Deze controllers zijn standaard niet ingeschakeld voor child cgroups. Om ze te activeren, schrijf je naar het root subtree control-bestand:
echo "+cpu +memory +io" | sudo tee /sys/fs/cgroup/cgroup.subtree_control
Voor een uitgebreide uitleg over hoe v2 intern verschilt van v1, is de NDC TechTown-lezing van Michael Kerrisk de beste bron:
Hoe systemd cgroups organiseert
systemd maakt een cgroup aan voor elke service die het start, genoemd naar de unit. nginx.service krijgt /sys/fs/cgroup/system.slice/nginx.service/, en elk proces dat het voortbrengt bevindt zich binnen die cgroup. Drie unit-types komen direct overeen met de hiërarchie:
| Type unit | Rol | Beschrijving |
|---|---|---|
.slice | Binnenste knooppunt | Groepeert gerelateerde services en definieert gedeelde limieten |
.service | Eindknooppunt | Beheert processen die door systemd zijn gestart |
.scope | Bladknooppunt | Houdt extern gestarte processen bij (container-payloads, inlogsessies) |
Vier standaardpartities worden standaard meegeleverd: -.slice (root), system.slice, user.sliceen machine.slice. Elke limiet die op een slice wordt toegepast, geldt automatisch voor elke service daarin.
Een v2-regel die het onthouden waard is: processen kunnen alleen in leaf-knooppunten staan. Een cgroup met onderliggende cgroups kan niet direct processen hosten, en daarom plaatst systemd nooit services in de trunk van een slice.
Stel limieten altijd in via systemd in plaats van /sys/fs/cgroup/ . Handmatig schrijven blijft niet behouden na een herstart en is in strijd met het exclusieve eigendom van de hiërarchie door systemd. Gebruik systemctl set-property voor eenmalige wijzigingen en unit drop-ins (systemctl edit nginx.service) voor permanente wijzigingen.
CPU-limieten
cgroups v2 biedt u twee CPU-regelaars: een harde limiet (cpu.max, weergegeven als CPUQuota in systemd) en een proportioneel gewicht (cpu.weight / CPUWeight).
CPUQuota is een absoluut maximum. CPUQuota=50% staat een halve core toe; CPUQuota=200% staat de tijd van twee volledige kernen toe. De service wordt afgeremd als deze hoger probeert te gaan, ongeacht hoe inactief de rest van de CPU is.
CPUWeight is alleen van belang bij concurrentie. Het bereik is 1 tot 10.000, standaard 100. Drie services met gewichten van 150, 100 en 50 ontvangen ruwweg 50%, 33% en 17% van de CPU-tijd wanneer ze die allemaal tegelijk willen. Wanneer de CPU verder inactief is, leggen de gewichten geen beperkingen op.
Voor latentiegevoelige workloads kunt u processen aan specifieke kernen koppelen met AllowedCPUs=. Dit vermindert contextwisselingen en houdt de cache per kern warm:
[Service]
CPUQuota=200%
CPUWeight=150
AllowedCPUs=0-3
Gebruik een harde quota wanneer u voorspelbare kosten nodig hebt (facturering voor meerdere tenants, isolatie van luidruchtige buren). Gebruik gewichten wanneer u maximale hardwarebenutting wilt en alleen prioriteitsvolgorde nodig hebt tijdens pieken.
Geheugenlimieten met cgroups v2
Geheugen kent twee niveaus: memory.high (zacht, throttling) en memory.max (hard, OOM). Voor achtergrondinformatie over swap, page reclaim en de kernel OOM-killer, zie ons bijbehorende artikel over Linux-geheugenbeheer.
Stel memory.high ongeveer 10 tot 20% lager memory.max. De kernel begint met het terugwinnen van pagina's en het afremmen van toewijzingen zodra memory.high de drempel wordt overschreden, waardoor de werklast zich meestal kan herstellen voordat de OOM-killer in werking treedt. Als het gebruik memory.max, beëindigt de kernel processen in de cgroup.
Een typische configuratie:
[Service]
MemoryHigh=400M
MemoryMax=512M
MemorySwapMax=0
MemorySwapMax=0 schakelt swap uit voor deze cgroup. De moeite waard voor latentiegevoelige workloads (databases, realtime streaming) waarbij swap-I/O de staartlatentie zou verpesten.
Voor werkpools waarbij het achterlaten van verweesde broers en zussen de gedeelde status zou beschadigen, schrijf 1 naar het memory.oom.group bestand. Wanneer één proces door OOM wordt beëindigd, beëindigt de kernel alle processen in de cgroup tegelijk.
Controleer memory.events om te zien hoe vaak een service is afgeremd of door OOM is beëindigd:
cat /sys/fs/cgroup/system.slice/nginx.service/memory.events
De high en oom_kill tellers geven aan of uw limieten correct zijn ingesteld. Aanhoudende waarden die niet nul zijn, betekenen dat de werklast meer ruimte nodig heeft.
I/O-limieten
De I/O-controller heeft hetzelfde ontwerp met twee modi: absolute limieten via io.max en proportioneel delen via io.weight.
Limieten gelden per blokapparaat, geïdentificeerd door major:minor-nummers. Zoek ze op met lsblk -o NAME,MAJ:MIN. Een typische systemd-configuratie:
[Service]
IOReadBandwidthMax=/dev/sda 50M
IOWriteBandwidthMax=/dev/sda 30M
IOReadIOPSMax=/dev/sda 1000
IOWriteIOPSMax=/dev/sda 500
io.weight werkt als cpu.weight: bereik 1 tot 10.000, standaard 100. Door 500 toe te wijzen aan een klantgerichte service en 50 aan een nachtelijke back-up, voorkomt u dat de back-up de schijf tijdens piekuren verzadigt, maar laat u deze de volledige bandbreedte gebruiken wanneer niets anders deze nodig heeft.
I/O-limieten zijn alleen van toepassing als u het juiste apparaat selecteert. De kernel houdt I/O bij per blokapparaat, dus een limiet op /dev/sda heeft geen effect op I/O die naar /dev/nvme0n1. Stel op hosts met meerdere schijven limieten per apparaat in.
Multi-tenant-isolatie met slices
Definieer voor gedeelde omgevingen een slice per tenant. Maak /etc/systemd/system/tenant-a.slice:
[Slice]
CPUQuota=200%
CPUWeight=150
MemoryHigh=3584M
MemoryMax=4096M
MemorySwapMax=0
IOReadBandwidthMax=/dev/sda 200M
TasksMax=512
TasksMax=512 beperkt het totale aantal processen en threads, waardoor wordt voorkomen dat een fork-bom in één tenant de host platlegt. Plaats tenant-services in deze slice (via Slice=tenant-a.slice in hun unit-bestanden) en ze erven alles automatisch.
Dit patroon werkt ook voor het scheiden van luidruchtige achtergrondtaken van gebruikersgerichte services. Plaats back-ups, logrotatie en batchtaken in een background.slice met lage CPUWeight en io.weight waarden. Ze krijgen volledige resources wanneer het systeem inactief is en maken plaats wanneer er productieverkeer binnenkomt.
Voeg voor container-runtimes zoals Docker en Podman Delegate=yes toe aan hun systemd-unitbestanden. Hierdoor kunnen ze hun eigen sub-cgroups beheren zonder root, en zijn de limieten die op de bovenliggende slice zijn ingesteld nog steeds van toepassing op alles daaronder.
Monitoring met systemd-cgtop en PSI
Voor een live top-achtige weergave van CPU, geheugen en I/O per cgroup, voer het volgende uit:
systemd-cgtop
Gebruik voor de statische hiërarchie en om te zien welke processen zich waar bevinden systemd-cgls.
De meest nuttige v2-functie voor productiemonitoring is Pressure Stall Information (PSI). PSI rapporteert het percentage van de tijd dat taken in een cgroup zijn vastgelopen in afwachting van een resource, weergegeven in drie bestanden per cgroup:
cat /sys/fs/cgroup/tenant-a.slice/cpu.pressure
cat /sys/fs/cgroup/tenant-a.slice/memory.pressure
cat /sys/fs/cgroup/tenant-a.slice/io.pressure
Een CPU met 100% bezetting en 0% druk is gezond. Elke taak die CPU nodig heeft, krijgt die ook. Dezelfde CPU met 80% bezetting maar 30% druk betekent dat taken in de wachtrij staan voor uitvoeringstijd. Geef een waarschuwing op basis van PSI, niet op basis van bezetting: het signaleert conflicten die bezettingsstatistieken volledig missen.
Pas limieten live aan zonder iets opnieuw op te starten:
sudo systemctl set-property tenant-a.slice MemoryMax=6144M
De wijziging wordt onmiddellijk toegepast en blijft behouden na herstarts. In combinatie met op PSI gebaseerde waarschuwingen kunt u zo reageren op verschuivingen in de belasting voordat deze leiden tot OOM-kills of uit de hand gelopen latentie.
Als u multi-tenant-workloads met hoge dichtheid uitvoert en een host nodig hebt met voldoende ruimte om dit beleid netjes toe te passen, zijn onze dedicated servers hiervoor gebouwd.
Waarom het belangrijk is om een krachtige en unmetered VPS te hebben
Een unmetered VPS geeft flat-rate bandbreedte op een vaste poortsnelheid. Hoe het verschilt van bemeterde plannen, wanneer het loont en wat u moet controleren voordat u koopt.
7 min lezen - 9 mei 2025
Linux geheugenbeheer: Swap, OOM-moordenaar & Cgroepen
12 min lezen - 31 mei 2026

Hebt u vragen of wilt u een oplossing op maat?
Flexibele opties
Wereldwijd bereik
Directe inzet
Flexibele opties
Wereldwijd bereik
Directe inzet