LimitNPROC proti TasksMax: kaj šteje enota OpenVPN
LimitNPROC šteje procese enega uporabnika v celem sistemu; TasksMax omejuje cgroup ene enote. Preberite dejanske vrednosti, preden katero od njiju dvignete.
Neuspešen zagon OpenVPN pogosto pride kot pritožba glede virov skupaj z dobronamernim predlogom, da se dvigne neka omejitev, predlog pa deluje le v približno polovici primerov. Za temi napakami stojita dva nepovezana števca. Eden je omejitev jedra na število opravil, ki jih ima resnični uporabniški ID, in se podeduje ob izvajanju procesa. Drugi je proračun cgroup, ki ga upravitelj storitev uporabi za enoto in vse, kar ta razveji. Branje dejanske vrednosti vsakega od njiju, za enoto, ki zares teče, stane manj kot ugibanje.
Dva števca, dve vprašanji
LimitNPROC je RLIMIT_NPROC pod imenom systemd, njegova obračunska enota pa je resnični uporabniški ID. Vsak proces, ki ga ta uporabnik ima, se šteje v isto vsoto, vključno z delom, ki so ga začele druge enote, prijavna seja ali opravilo razporejevalnika. Omejitev torej ni zgornja meja na storitev, tudi ko je nastavljena znotraj enote storitve, in storitev, ki za vsakega odjemalca razveji pomočnika, tekmuje z vsem drugim, kar teče pod tem računom. Zasedeno opravilo cron pod istim uporabnikom lahko enoto VPN potisne čez črto, ki je sama nikoli ni prestopila.
TasksMax ima drugega lastnika: krmilnik pids na cgroup enote, ki šteje opravila in ne procesov. Niti so opravila, zato lahko demon, ki je videti enonitni, a ima nabor delavcev, porabi proračun, ki je na prvi pogled videti veliko večji od števila njegovih procesov. EffectiveTasksMax poroča, kaj hierarhija cgroup zares dovoljuje, potem ko so nadrejeni rezini povedali svoje.
Zakaj izjema za root spremeni odgovor
Jeder ne uporabi RLIMIT_NPROC za proces, ki nosi CAP_SYS_RESOURCE ali CAP_SYS_ADMIN, zato enota, ki teče kot root brez odrekanja privilegijem, s to nastavitvijo praktično ni omejena. Ta edina izjema pojasnjuje nasprotujoče si nasvete, ki si jih ljudje izmenjujejo: dvig LimitNPROC popravi namestitev, ki se je odrekla privilegijem, in ne naredi čisto ničesar za tisto, ki je ostala privilegirana. Preden tej nastavitvi pripišete zasluge ali krivdo, preverite User= in ali demon po zagonu spremeni identiteto. Privilegirana enota, ki pozneje preide na neprivilegiran račun, v trenutku prehoda spet pade pod omejitev, kar naredi tudi časovnico napake vredno branja.
Faza napake to še zoži. Zavrnitev med pripravo izvajanja, napaka pri razvejitvi, ki jo sporoči sam demon, in zavrnjeno ustvarjanje opravila znotraj cgroup dajo različne vrstice v journalu, in le na eno od njih odgovori večji proračun.
Berite dejanske vrednosti, ne tistih iz lupine
ulimit -u interaktivne lupine opisuje to lupino. Ne opisuje, kaj je upravitelj storitev predal demonu, in ne pove ničesar o obračunavanju cgroup. Vprašajte raje enoto, z imenom primerka, ki na gostitelju obstaja, in ne s primerom iz priročnika.
systemctl show [email protected] -p User -p LimitNPROC -p TasksCurrent -p TasksMax -p EffectiveTasksMax
cat /proc/$(systemctl show -p MainPID --value [email protected])/limits | grep -i processes
Znotraj vsebnika odgovor potrebuje še dve branji, ker notranja vrednost infinity opisuje le pogled gosta. Vprašajte lastnika gostitelja za lastno zgornjo mejo pids vsebnika in potrdite, ali lahko notranji upravitelj storitev ta krmilnik sploh delegira. Gnezdena enota ne more držati proračuna, ki ji ga nadrejeni cgroup ni nikoli dodelil.
Izmerite obseg popravka in ga dokažite pod obremenitvijo
Število izberite iz delovne obremenitve, ne iz besedila napake. Preštejte procese, ki jih demon zažene na vsakega povezanega odjemalca ali vsak klic pomočnika, pomnožite s sočasnostjo, ki jo mora namestitev prenesti, dodajte rezervo za administrativne seje in nato to število primerjajte z dvema dejanskima vrednostima. Lokalno prepisovanje drop-in ohrani spremembo pregledno in preživi posodobitve paketov, medtem ko urejanje dobavljene datoteke enote skrije spremembo, dokler je ne nadomesti naslednja posodobitev. Aritmetiko zapišite poleg prepisovanja, ker naslednja oseba, ki ga bo dvignila ali znižala, potrebuje predpostavke, ne končnega števila.
Spremembe proračuna se uporabijo ob izvajanju, zato samo ponovno nalaganje ne spremeni velikosti že delujočih procesov. Znova zaženite enoto skozi njen običajni življenjski cikel, sprejmite prekinitev seje in znova preberite števce na novem primerku.
sudo systemctl daemon-reload
sudo systemctl restart [email protected]
systemctl show [email protected] -p TasksCurrent -p EffectiveTasksMax
sudo journalctl -u [email protected] -b --no-pager | tail -n 20
Popravek dokaže znova zagnana enota, katere število opravil ostane pod obema zgornjima mejama, medtem ko nosi predvideno obremenitev, skupaj z journalom, ki v isti fazi ne poroča več o izčrpanju opravil ali razvejitev. Shranite števila pred in po skupaj s spremembo, da se naslednja preiskava začne z meritvijo in ne z istim nasvetom. Če število še vedno doseže mejo, je bila aritmetika napačna in ne omejitev po naključju premajhna, in to razliko je vredno poznati pred naslednjim ponovnim zagonom.