Tutoriel Linux

Cgroups Linux, zkontrolujte omezení CPU a paměti služby

Débutant5 min de lecture

Webová služba, která zpomaluje, pracovník zabit bez jasné zprávy nebo server, který přepíná, nemusí nutně využívat veškerou RAM stroje. S systemd může být limit nastavený na jednotku dostatečný k vysvětlení symptomu.

Cgroups umožňují jádru Linuxu počítat, omezovat a priorizovat zdroje skupiny procesů. Než přidáte paměť nebo náhodně restartujete, zkontrolujte, co systemd aplikuje na dotčenou službu.

Tux před servery se stupnicí zdrojů CPU a paměti
Cgroups a limity zdrojů služby Linuxu řízené systemd.

Zobrazit cgroup služby

Na nedávných distribucích systemd umisťuje každou službu do jejího vlastního cgroup. Nemusíte ručně přesouvat PID, abyste diagnostikovali klasickou jednotku jako Nginx, PostgreSQL nebo aplikačního pracovníka.

Začněte čtením stavu služby a vlastností souvisejících se zdroji. Nahraďte nginx.service skutečným názvem vaší jednotky.

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

ControlGroup dává cestu řízenou systemd. MemoryCurrent zobrazuje paměť započítanou pro jednotku v okamžiku čtení. Pokud MemoryMax je infinity, systemd nenastavil tvrdý paměťový strop pro tuto službu.

Pokud vycházíte z PID, přečtěte si jeho cgroup ze /proc. Ve cgroup v2 často uvidíte řádek typu 0::/system.slice/nginx.service.

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

Pokud MainPID je 0, služba nemá žádný aktivní hlavní proces. Vraťte se k systemctl status a journalctl, místo abyste usuzovali na základě prázdného PID.

Číst limity paměti a CPU

MemoryMax je tvrdý limit. Pokud cgroup dosáhne tohoto stropu a jádro nezíská dostatek paměti, může být proces ve skupině zabit OOM killerem.

MemoryHigh je méně drastický. Jádro zpomaluje alokace a snaží se uvolnit paměť, když cgroup překročí tento práh. Aby bylo možné udržet službu bez jejího zhroucení při prvním vrcholu, je často lepší prvotní nastavení než MemoryMax.

CPUQuota omezuje dostupný čas CPU pro službu. CPUQuota=25% dává ekvivalent čtvrtinového logického jádra. Na stroji s více jádry CPUQuota=200% povoluje až dvě jádra CPU času.

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

Nespojujte kvótu a prioritu. Kvóta brání službě překročit množství CPU. Priorita, s nice nebo CPUWeight, spíše rozhoduje o konkurenci, když více úloh žádá o CPU současně.

Najít zdroj limitu

Limit může pocházet z konfiguračního souboru dodaného balíčkem, z drop-in systemd nebo z místního přepsání. Přečtěte si celou konfiguraci, než upravíte službu.

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

Soubor pod /etc/systemd/system/nginx.service.d/ obvykle přebírá kontrolu nad jednotkou dodanou balíčkem. Vyhněte se přímému upravování souboru v /usr/lib/systemd/system/ nebo /lib/systemd/system/, protože aktualizace jej mohou přepsat.

Poté zkontrolujte symptomy. Zpomalená služba může také pocházet z pomalého SQL dotazu, saturace disku, plné fronty nebo aplikační chyby.

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

Pokud limity zůstávají na infinity a jádrový žurnál neukazuje žádné události paměti, hledejte jinde, než se dotknete cgroups: aplikační logy, metriky disku, síťová latence nebo skutečná spotřeba procesu.

Testovat bez dotyku služby

Pro ověření syntaxe nebo měření efektu limitu spusťte dočasnou jednotku pomocí systemd-run. Test nemění Nginx, PostgreSQL nebo vaši obchodní službu.

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

Poté si přečtěte aplikované vlastnosti. Pro CPUQuota=25% může systemd zobrazit hodnotu ekvivalentní 250ms za sekundu.

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

Jakmile dokončíte, zastavte testovací jednotku. S sleep není zapomenutí tragické, ale tento reflex zabraňuje překvapením, když test spouští skutečný příkaz.

sudo systemctl stop essai-limite-memoire.service

Použití přepsání systemd

Když žurnály a měření potvrzují, že limit dává smysl, přejděte k přepsání systémem systemd. Příklad níže nastavuje vysokou hranici na 800 MB, tvrdý strop na 1 GB a omezuje službu na ekvivalent jednoho CPU jádra.

sudo systemctl edit mon-service.service

Přidejte pouze nezbytné direktivy. Nekopírujte tyto hodnoty na produkční službu, aniž byste sledovali její normální spotřebu a vrcholy.

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

Načtěte znovu systemd a restartujte službu pouze pokud je to přerušení přijatelné. Na dálku si nechte otevřenou druhou relaci SSH, když se dotýkáte kritické komponenty.

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

Pokud se služba nespustí nebo se stane příliš pomalou, opatrně odstraňte přepsání. sudo systemctl revert mon-service.service odstraní místní přepsání jednotky. Nepoužívejte to, pokud stejný adresář obsahuje další nastavení, která chcete uchovat.

Kontroly po změně

  • Zkontrolujte stav pomocí systemctl is-active mon-service.service.
  • Přečtěte si MemoryCurrent, MemoryHigh, MemoryMax a CPUQuotaPerSecUSec po restartu.
  • Sledujte journalctl -u mon-service.service -b a jádrové žurnály během problému zatížení.
  • Změřte efekt na aplikační straně: doba odezvy, opožděné úkoly, fronty, chyby uživatele.
  • Poznamenejte důvod nastavení, datum, přijatou hodnotu a opravený symptom do své provozní dokumentace.

Cgroups chrání zbytek stroje a činí limity viditelnými. Neopravují únik paměti, příliš nákladný dotaz nebo špatně dimenzovaného pracovníka. Pokud je strop dosažen, uchovejte žurnál, pozorované zatížení a nakonfigurovanou hodnotu, abyste se rozhodli mezi úpravou limitu a opravou aplikace.

Pro hlubší porozumění stránka systemd.resource-control(5) podrobně popisuje každou direktivu. Průvodce Nice pod Linuxem pomáhá vybrat prioritu CPU, když striktní strop není vhodný.

sudo apt update && sudo apt upgrade