Tutoriel Linux

Cgroups Linux, controleer de CPU- en geheugengrenzen van een service

Débutant5 min de lecture

Een webservice die traag is, een worker die zonder duidelijke boodschap is gestopt of een server die swapt, heeft misschien niet alle RAM van de machine uitgeput. Met systemd kan een limiet die op een eenheid is ingesteld, voldoende zijn om het symptoom te verklaren.

cgroups stellen de Linux-kernel in staat om de middelen van een groep processen te tellen, te beperken en te prioriteren. Voordat u geheugen toevoegt of willekeurig opnieuw opstart, controleert u wat systemd toepast op de betreffende service.

Tux voor servers met een CPU- en geheugenresource-meter
Cgroups en hulpbronnenlimieten van een Linux-service beheerd door systemd.

Bekijk de cgroup van een service

Op recente distributies plaatst systemd elke service in zijn eigen cgroup. U hoeft geen PID handmatig te verplaatsen om een klassieke eenheid zoals Nginx, PostgreSQL of een applicatieworker te diagnosticeren.

Begin met het lezen van de status van de service en de eigenschappen die met de middelen zijn verbonden. Vervang nginx.service door de daadwerkelijke naam van uw eenheid.

systemctl status nginx.service --no-pager
systemctl show nginx.service -p ControlGroup -p MainPID -p MemoryCurrent -p MemoryMax -p MemoryHigh -p CPUQuotaPerSecUSec

ControlGroup geeft het pad aan dat door systemd wordt beheerd. MemoryCurrent toont het geheugen dat op dat moment aan de eenheid is toegewezen. Als MemoryMax gelijk is aan infinity, heeft systemd geen harde geheugengrens voor deze service ingesteld.

Als u begint met een PID, lees dan zijn cgroup vanuit /proc. In cgroup v2 ziet u vaak een regel van het type 0::/system.slice/nginx.service.

pid=$(systemctl show nginx.service -p MainPID --value)
cat /proc/$pid/cgroup

Als MainPID gelijk is aan 0, heeft de service geen actieve hoofdprocessen. Ga terug naar systemctl status en journalctl in plaats van te concluderen vanuit een lege PID.

Lees de geheugen- en CPU-limieten

MemoryMax is een harde limiet. Als de cgroup deze grens bereikt en de kernel niet genoeg geheugen terugwint, kan een proces in de groep door de OOM-killer worden beëindigd.

MemoryHigh is minder ingrijpend. De kernel remt de toewijzingen en probeert geheugen te herstellen wanneer de cgroup deze drempel overschrijdt. Om een service te beperken zonder deze bij de eerste piek te laten instorten, is dit vaak een betere begininstelling dan MemoryMax.

CPUQuota beperkt de beschikbare CPU-tijd voor de service. CPUQuota=25% geeft het equivalent van een kwart van een logische core. Op een machine met meerdere cores stelt CPUQuota=200% tot twee cores CPU-tijd beschikbaar.

systemctl show nginx.service 
  -p MemoryCurrent -p MemoryMax -p MemoryHigh 
  -p CPUUsageNSec -p CPUQuotaPerSecUSec

Verwissel quota niet met prioriteit. Een quota voorkomt dat de service boven een hoeveelheid CPU uitkomt. Een prioriteit, met nice of CPUWeight, bepaalt vooral de concurrentie wanneer meerdere taken tegelijkertijd CPU aanvragen.

Vind de oorsprong van een limiet

Een limiet kan afkomstig zijn van het bestand dat door het pakket is geleverd, een drop-in van systemd of een lokaal aangemaakte overschrijving. Lees de volledige configuratie voordat u de service wijzigt.

systemctl cat nginx.service
systemctl show nginx.service -p FragmentPath -p DropInPaths

Een bestand onder /etc/systemd/system/nginx.service.d/ heeft normaal gesproken prioriteit boven de door het pakket geleverde eenheid. Vermijd het direct wijzigen van een bestand in /usr/lib/systemd/system/ of /lib/systemd/system/, aangezien een update het kan overschrijven.

Controleer vervolgens de symptomen. Een trage service kan ook worden veroorzaakt door een trage SQL-query, een volle schijf, een volle wachtrij of een applicatiefout.

journalctl -u nginx.service -b --no-pager
journalctl -k -b | grep -Ei 'oom|out of memory|killed process|memory cgroup'

Als de limieten nog steeds op infinity staan en de kernel-log geen geheugenevenementen toont, zoek dan elders voordat u de cgroups aanpast: applicatielogs, schijfmetrische gegevens, netwerklatentie of werkelijke procesgebruik.

Testen zonder de service aan te raken

Om een syntaxis te valideren of het effect van een limiet te meten, start u een tijdelijke eenheid met systemd-run. De test wijzigt Nginx, PostgreSQL of uw bedrijfsservice niet.

sudo systemd-run --unit=essai-limite-memoire 
  --property=MemoryMax=256M 
  --property=CPUQuota=25% 
  /usr/bin/bash -c 'sleep 300'

Controleer daarna de toegepaste eigenschappen. Voor CPUQuota=25% kan systemd een waarde tonen die gelijk is aan 250ms per seconde.

systemctl show essai-limite-memoire.service 
  -p MemoryMax -p CPUQuotaPerSecUSec -p ControlGroup -p ActiveState
systemctl cat essai-limite-memoire.service

Stop de testeenheid zodra u klaar bent. Met sleep is het vergeten niet zorgwekkend, maar deze reflex voorkomt verrassingen wanneer de test een echte opdracht start.

sudo systemctl stop essai-limite-memoire.service

Toepassen van een systemd-override

Wanneer de logs en de metingen bevestigen dat een limiet zinvol is, gebruik dan een systemd-override. Het onderstaande voorbeeld stelt een hoge drempel in op 800 MB, een harde limiet op 1 GB en beperkt de service tot het equivalent van één CPU-core.

sudo systemctl edit mon-service.service

Voeg alleen de nodige richtlijnen toe. Kopieer deze waarden niet naar een productieomgeving zonder de normale consumptie en pieken te observeren.

[Service]
MemoryHigh=800M
MemoryMax=1G
CPUQuota=100%

Herlaad systemd, en herstart de service alleen als de onderbreking acceptabel is. Houd op afstand een tweede SSH-sessie open wanneer u een kritiek onderdeel aanraakt.

sudo systemctl daemon-reload
sudo systemctl restart mon-service.service
systemctl status mon-service.service --no-pager
systemctl show mon-service.service -p MemoryCurrent -p MemoryHigh -p MemoryMax -p CPUQuotaPerSecUSec

Als de service niet meer opstart of te traag wordt, verwijder dan de override met voorzichtigheid. sudo systemctl revert mon-service.service verwijdert de lokale overrides van de eenheid. Gebruik het niet als dezelfde directory andere instellingen bevat die u wilt behouden.

Controles na wijziging

  • Controleer de status met systemctl is-active mon-service.service.
  • Herlees MemoryCurrent, MemoryHigh, MemoryMax en CPUQuotaPerSecUSec na de herstart.
  • Monitor journalctl -u mon-service.service -b en de kernel-log tijdens de probleem-piek.
  • Meet het effect aan de applicatiezijde: responsetijd, achterstallige jobs, wachtrijen, gebruikersfouten.
  • Noteer de reden voor de aanpassing, de datum, de vastgestelde waarde en het gecorrigeerde symptoom in uw operationele procedures.

De cgroups beschermen de rest van de machine en maken de limieten zichtbaar. Ze lossen geen geheugenslek, een te dure aanvraag of een verkeerd gedefinieerde worker op. Als de limiet is bereikt, bewaar dan het log, de waargenomen belasting en de geconfigureerde waarde om te kiezen tussen het aanpassen van de limiet en het corrigeren van de applicatie.

Voor meer informatie gaat u naar de pagina systemd.resource-control(5) voor gedetailleerde informatie over elke richtlijn. De gids Nice onder Linux helpt bij het kiezen van een CPU-prioriteit wanneer een strikte limiet niet geschikt is.