cgroups v2 resursgränser med systemd

11 min läsning - 3 juni 2026

hero section cover
Innehållsförteckning
  • cgroups v2 resursbegränsningar med systemd
  • Aktivera cgroups v2
  • Hur systemd organiserar cgroups
  • CPU-begränsningar
  • Minnesgränser med cgroups v2
  • I/O-gränser
  • Isolering av flera hyresgäster med segment
  • Övervakning med systemd-cgtop och PSI
Dela

Ställ in CPU-, minnes- och I/O-gränser med cgroups v2 och systemd. Praktisk konfiguration för Linux-värdar med flera hyresgäster, med PSI-övervakning och slice-isolering.

cgroups v2 resursbegränsningar med systemd

cgroups v2 är Linux-kärnans enhetliga ramverk för resurskontroll. Det ersätter den fragmenterade v1-hierarkin med ett enda träd som hanterar CPU, minne och I/O på ett konsekvent sätt och ligger till grund för containerisolering i Docker, Kubernetes och systemd. Det här inlägget handlar om hur man aktiverar cgroups v2, ställer in gränser via systemd och tillämpar det på verkliga scenarier för multitenant-hosting.

Aktivera cgroups v2

Moderna distributioner levereras med cgroups v2 aktiverat som standard: Ubuntu 21.10+, Debian 11+, Fedora 31+ och RHEL/Rocky 9+. Äldre system kan köra en hybridhierarki eller fortfarande ha v1 som standard. Kontrollera med:

stat -fc %T /sys/fs/cgroup/

Utmatningen från cgroup2fs bekräftar att v2 är aktivt. tmpfs betyder vanligtvis v1.

För att byta ett hybridsystem till ren v2, redigera /etc/default/grub och lägg till följande i GRUB_CMDLINE_LINUX_DEFAULT:

systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all

Generera sedan om GRUB och starta om:

sudo update-grub
sudo reboot

För produktion, kör kärna 5.2 eller nyare så att du får cgroup-freezer för v2 och systemd 244+ för full cpuset delegering. På Rocky Linux 8 och RHEL 8 kan du också behöva aktivera redovisning explicit genom att lägga till dessa rader i /etc/systemd/system.conf:

DefaultCPUAccounting=yes
DefaultMemoryAccounting=yes
DefaultIOAccounting=yes

Ladda om med sudo systemctl daemon-reexec. Efter omstarten, kontrollera vilka styrenheter som är tillgängliga:

cat /sys/fs/cgroup/cgroup.controllers

Du bör se cpu, memory, io, och pids listade. Dessa kontroller är inte aktiverade för underordnade cgroups som standard. För att aktivera dem, skriv till rotunderträdets kontrollfil:

echo "+cpu +memory +io" | sudo tee /sys/fs/cgroup/cgroup.subtree_control

För en grundlig genomgång av hur v2 skiljer sig från v1 internt är Michael Kerrisks föredrag på NDC TechTown den bästa enskilda källan:

Hur systemd organiserar cgroups

systemd skapar en cgroup för varje tjänst som startas, uppkallad efter enheten. nginx.service får /sys/fs/cgroup/system.slice/nginx.service/, och varje process som den genererar finns i den cgruppen. Tre enhetstyper mappar direkt till hierarkin:

EnhetstypRollBeskrivning
.sliceInre nodGrupperar relaterade tjänster och definierar delade gränser
.serviceTerminalnodHanterar processer som startats av systemd
.scopeBladnodSpårar processer som startats externt (container-payloads, inloggningssessioner)

Fyra standardskivor levereras som standard: -.slice (root), system.slice, user.sliceoch machine.slice. Alla begränsningar som tillämpas på en slice gäller automatiskt för alla tjänster i den.

En v2-regel som är värd att komma ihåg: processer kan endast finnas i bladnoder. En cgroup med underordnade cgroups kan inte direkt vara värd för processer, vilket är anledningen till att systemd aldrig placerar tjänster i en slices trunk.

Ställ alltid in begränsningar via systemd istället för att skriva direkt i /sys/fs/cgroup/ direkt. Manuella skrivningar kvarstår inte efter omstart och står i konflikt med systemds exklusiva äganderätt till hierarkin. Använd systemctl set-property för engångsändringar och tillfälliga enheter (systemctl edit nginx.service) för permanenta ändringar.

CPU-begränsningar

cgroups v2 ger dig två CPU-kontroller: en hård gräns (cpu.max, som visas som CPUQuota i systemd) och en proportionell vikt (cpu.weight / CPUWeight).

CPUQuota är ett absolut tak. CPUQuota=50% tillåter en halv kärna; CPUQuota=200% tillåter tid motsvarande två hela kärnor. Tjänsten stryps om den försöker gå högre, oavsett hur ledig resten av CPU:n är.

CPUWeight spelar endast roll vid konkurrens. Intervallet är 1 till 10 000, standardvärdet är 100. Tre tjänster med vikter på 150, 100 och 50 får ungefär 50 %, 33 % och 17 % av CPU-tiden när de alla vill ha den samtidigt. När CPU:n annars är ledig begränsar vikterna ingenting.

För latenskänsliga arbetsbelastningar kan du binda processer till specifika kärnor med AllowedCPUs=. Detta minskar kontextväxling och håller cachen per kärna aktiv:

[Service]
CPUQuota=200%
CPUWeight=150
AllowedCPUs=0-3

Använd en fast kvot när du behöver förutsägbara kostnader (fakturering för flera användare, isolering från störande grannar). Använd vikter när du vill ha maximal hårdvaruutnyttjande och bara behöver prioriteringsordning under toppar.

Minnesgränser med cgroups v2

Minnet har två nivåer: memory.high (mjuk, strypning) och memory.max (hård, OOM). För bakgrundsinformation om swap, page reclaim och kärnans OOM-killer, se vårt kompletterande inlägg om minneshantering i Linux.

Ställ in memory.high ungefär 10 till 20 % under memory.max. Kärnan börjar återvinna sidor och strypa allokeringar så snart memory.high gränsen överskrids, vilket vanligtvis låter arbetsbelastningen återhämta sig innan OOM-killer aktiveras. Om användningen når memory.max, avslutar kärnan processer i cgruppen.

En typisk konfiguration:

[Service]
MemoryHigh=400M
MemoryMax=512M
MemorySwapMax=0

MemorySwapMax=0 inaktiverar swap för denna cgroup. Värt att göra för latenskänsliga arbetsbelastningar (databaser, realtidsströmning) där swap-I/O skulle sänka svanslatensen.

För arbetarpooler där det skulle skada delat tillstånd att lämna kvar föräldralösa syskon, skriv 1 till cgruppens memory.oom.group fil. När en process avslutas på grund av OOM avslutar kärnan alla processer i cgruppen samtidigt.

Kontrollera memory.events för att se hur ofta en tjänst har strypts eller avslutats på grund av OOM:

cat /sys/fs/cgroup/system.slice/nginx.service/memory.events

Den high och oom_kill visar om dina gränser är rätt dimensionerade. Bestående värden som inte är noll innebär att arbetsbelastningen behöver mer utrymme.

I/O-gränser

I/O-kontrollern har samma design med två lägen: absoluta gränser via io.max och proportionell delning via io.weight.

Gränserna gäller per blockenhet, identifierade med major:minor-nummer. Hitta dem med lsblk -o NAME,MAJ:MIN. En typisk systemd-konfiguration:

[Service]
IOReadBandwidthMax=/dev/sda 50M
IOWriteBandwidthMax=/dev/sda 30M
IOReadIOPSMax=/dev/sda 1000
IOWriteIOPSMax=/dev/sda 500

io.weight fungerar som cpu.weight: intervall 1 till 10 000, standard 100. Att tilldela 500 till en kundinriktad tjänst och 50 till en nattlig säkerhetskopiering förhindrar att säkerhetskopieringen mättar disken under rusningstider, men låter den använda full bandbredd när inget annat behöver den.

I/O-gränser gäller endast när du riktar in dig på rätt enhet. Kärnan spårar I/O per blockenhet, så en gräns på /dev/sda har ingen effekt på I/O som går till /dev/nvme0n1. På värdar med flera diskar ska du ställa in gränser per enhet.

Isolering av flera hyresgäster med segment

För delade miljöer, definiera en slice per tenant. Skapa /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 begränsar det totala antalet processer och trådar, vilket förhindrar att en fork bomb hos en hyresgäst slår ut värden. Placera hyresgästtjänsterna i denna slice (via Slice=tenant-a.slice i deras enhetsfiler) så ärver de allt automatiskt.

Detta mönster fungerar också för att separera störande bakgrundsarbete från användarvända tjänster. Placera säkerhetskopior, loggrotation och batchjobb i en background.slice med låg CPUWeight och io.weight . De får full tillgång till resurser när systemet är inaktivt och träder åt sidan när produktionstrafik anländer.

För container-runtimes som Docker och Podman, lägg till Delegate=yes till deras systemd-enhetsfiler. Detta låter dem hantera sina egna undergrupper utan root, och de gränser som satts på den överordnade delen gäller fortfarande för allt under.

Övervakning med systemd-cgtop och PSI

För en live-vy i top-stil av CPU, minne och I/O per cgroup, kör:

systemd-cgtop

För den statiska hierarkin och vilka processer som finns var, använd systemd-cgls.

Den enskilt mest användbara v2-funktionen för produktionsövervakning är Pressure Stall Information (PSI). PSI rapporterar den procentuella tiden som uppgifter i en cgroup har stått stilla i väntan på en resurs, vilket visas i tre filer 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

En CPU med 100 % utnyttjande och 0 % tryck är i gott skick. Varje uppgift som behöver CPU får det. Samma CPU med 80 % utnyttjande men 30 % tryck innebär att uppgifter står i kö för körtid. Varna på PSI, inte på utnyttjande: det fångar upp konflikter som utnyttjandemätvärden helt missar.

Justera gränser i realtid utan att starta om något:

sudo systemctl set-property tenant-a.slice MemoryMax=6144M

Ändringen träder i kraft omedelbart och kvarstår även efter omstart. I kombination med PSI-baserade varningar kan du på så sätt reagera på belastningsförändringar innan de leder till OOM-avbrott eller okontrollerad latens.

Om du kör arbetsbelastningar med hög densitet och flera användare och behöver en värd med utrymme att tillämpa dessa policyer smidigt, är våra dedikerade servrar byggda för just det.

Blogg

Utvalda denna vecka

Fler artiklar
Varför det är viktigt att ha en kraftfull och omättad VPS

Varför det är viktigt att ha en kraftfull och omättad VPS

En VPS utan mätning ger bandbredd till fast pris med en fast porthastighet. Hur det skiljer sig från uppmätta planer, när det lönar sig och vad du ska kontrollera innan du köper.

7 min läsning - 9 maj 2025

Linux minneshantering: Swap, OOM Killer & Cgroups

12 min läsning - 31 maj 2026

Fler artiklar
background image

Har du frågor eller behöver du en anpassad lösning?

icon

Flexibla alternativ

icon

Global räckvidd

icon

Omedelbar driftsättning

icon

Flexibla alternativ

icon

Global räckvidd

icon

Omedelbar driftsättning