LimitNPROC naspram TasksMax: što broji jedna OpenVPN jedinica
LimitNPROC broji procese jednog korisnika na cijelom sistemu; TasksMax ograničava cgroup jedne jedinice. Pročitajte stvarne vrijednosti prije nego što podignete bilo koju od njih.
Neuspjelo pokretanje OpenVPN često dolazi kao žalba na resurse plus dobronamjerni savjet da se podigne neki limit, a taj savjet uspijeva samo u otprilike polovini slučajeva. Iza tih neuspjeha stoje dva nepovezana brojača. Jedan je ograničenje kernela na broj zadataka koje posjeduje stvarni korisnički ID, a nasljeđuje se kada se proces izvrši. Drugi je cgroup budžet koji servisni menadžer primjenjuje na jedinicu i sve što ona račva. Čitanje stvarne vrijednosti svakog od njih, za jedinicu koja zaista radi, košta manje od nagađanja.
Dva brojača, dva pitanja
LimitNPROC je RLIMIT_NPROC pod systemd imenom, a njegova obračunska jedinica je stvarni korisnički ID. Svaki proces koji taj korisnik posjeduje broji se u isti ukupni zbir, uključujući rad koji su pokrenule druge jedinice, prijavna sesija ili zadatak zakazivača. Limit zato nije gornja granica po servisu čak i kada je postavljen unutar servisne jedinice, a servis koji račva pomoćnika za svakog klijenta takmiči se sa svim ostalim što radi pod tim računom. Zauzet cron zadatak pod istim korisnikom može gurnuti VPN jedinicu preko crte koju ona sama nikada nije prešla.
TasksMax ima drugog vlasnika: pids kontroler na cgroup jedinice, koji broji zadatke, a ne procese. Niti su zadaci, pa daemon koji izgleda jednokončano, ali ima pul radnika, može trošiti budžet koji na prvi pogled izgleda daleko veći od broja njegovih procesa. EffectiveTasksMax prijavljuje šta hijerarhija cgroup zaista dopušta nakon što roditeljski slojevi kažu svoje.
Zašto root izuzetak mijenja odgovor
Kernel ne primjenjuje RLIMIT_NPROC na proces koji nosi CAP_SYS_RESOURCE ili CAP_SYS_ADMIN, zbog čega jedinica koja radi kao root bez odricanja privilegija zapravo nije ograničena tom postavkom. Taj jedini izuzetak objašnjava proturječne savjete koje ljudi razmjenjuju: podizanje LimitNPROC popravlja raspoređivanje koje se odreklo privilegija i ne čini baš ništa za ono koje je ostalo privilegovano. Provjerite User= i mijenja li daemon identitet nakon pokretanja prije nego što toj postavci pripišete zaslugu ili krivicu. Privilegovana jedinica koja kasnije pređe na neprivilegovan račun vraća se pod limit u trenutku prelaska, što i vremensku liniju kvara čini vrijednom čitanja.
Faza neuspjeha dodatno sužava stvar. Odbijanje tokom pripreme izvršavanja, greška pri račvanju koju prijavi sam daemon i odbijeno stvaranje zadatka unutar cgroup daju različite linije journala, a samo na jednu od njih odgovara veći budžet.
Čitajte stvarne vrijednosti, ne one iz ljuske
ulimit -u interaktivne ljuske opisuje tu ljusku. Ne opisuje šta je servisni menadžer prenio daemonu i ne govori ništa o cgroup obračunu. Umjesto toga pitajte jedinicu, koristeći naziv instance koji postoji na hostu, a ne primjer iz priruč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
Unutar kontejnera odgovor traži još dva očitanja, jer unutrašnja vrijednost infinity opisuje samo pogled gosta. Pitajte vlasnika hosta za vlastiti pids plafon kontejnera i potvrdite može li unutrašnji servisni menadžer uopće delegirati taj kontroler. Ugniježđena jedinica ne može držati budžet koji njezin roditeljski cgroup nikada nije dao.
Odredite veličinu popravke i dokažite je pod opterećenjem
Uzmite broj iz radnog opterećenja, a ne iz teksta greške. Prebrojite procese koje daemon pokreće po povezanom klijentu ili po pozivu pomoćnika, pomnožite sa paralelnošću koju raspoređivanje treba da nosi, dodajte marginu za administrativne sesije, pa uporedite tu cifru sa dvije stvarne vrijednosti. Lokalno drop-in prepisivanje održava promjenu preglednom i preživljava nadogradnje paketa, dok uređivanje isporučene datoteke jedinice skriva izmjenu dok je sljedeće ažuriranje ne zamijeni. Zapišite računicu pored prepisivanja, jer sljedećoj osobi koja će je podići ili spustiti trebaju pretpostavke, a ne konačni broj.
Promjene budžeta primjenjuju se pri izvršavanju, pa samo ponovno učitavanje ne mijenja veličinu procesa koji već rade. Ponovo pokrenite jedinicu kroz njezin uobičajeni životni ciklus, prihvatite prekid sesije i ponovo pročitajte brojače na novoj instanci.
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
Popravku dokazuje ponovo pokrenuta jedinica čiji broj zadataka stoji ispod oba plafona dok nosi predviđeno opterećenje, plus journal koji više ne prijavljuje iscrpljenost zadataka ili račvanja u istoj fazi. Sačuvajte brojeve prije i poslije uz promjenu kako bi sljedeća istraga počela od mjerenja, a ne od istog savjeta. Ako broj još doseže plafon, računica je bila pogrešna, a ne limit slučajno premali, i tu razliku vrijedi znati prije sljedećeg restarta.