LimitNPROC versus TasksMax: mida OpenVPN-i üksus loeb
LimitNPROC loeb ühe kasutaja protsesse kogu süsteemis; TasksMax piirab ühe üksuse cgroupi. Lugege tegelikke väärtusi enne, kui kumbagi tõstate.
Ebaõnnestunud OpenVPN käivitamine saabub sageli ressursikaebuse ja heas usus tehtud soovitusega piirangut tõsta, ning see soovitus töötab vaid umbes pooltel juhtudel. Nende ebaõnnestumiste taga on kaks omavahel sidumata loendurit. Üks on tuuma piirang reaalse kasutaja ID-le kuuluvate ülesannete arvule ja see pärandatakse protsessi käivitamisel. Teine on cgroupi eelarve, mida teenusehaldur rakendab üksusele ja kõigele, mida see harundab. Nende mõlema tegeliku väärtuse lugemine, selle üksuse jaoks, mis tegelikult töötab, maksab vähem kui oletus.
Kaks loendurit, kaks küsimust
LimitNPROC on RLIMIT_NPROC systemd nime all ja selle arvestusühik on reaalne kasutaja ID. Iga protsess, mida see kasutaja omab, arvestatakse sama summa hulka, sealhulgas töö, mille on algatanud teised üksused, sisselogimissessioon või planeerija ülesanne. Piirang ei ole seega teenusepõhine ülempiir ka siis, kui see on seatud teenuseüksuse sees, ja teenus, mis harundab iga kliendi jaoks abilise, võistleb kõige muu sama kontoga töötavaga. Hõivatud cron-ülesanne sama kasutaja all võib lükata VPN-i üksuse üle joone, mille see ise kunagi ületas.
TasksMax on teise omanikuga: üksuse cgroupi pids-kontroller, mis loeb ülesandeid, mitte protsesse. Lõimed on ülesanded, seega näiliselt ühelõimeline aga töötajate basseiniga deemon võib tarbida eelarvet, mis esmapilgul tundub tema protsesside arvust palju suurem. EffectiveTasksMax teatab, mida cgroupi hierarhia tegelikult lubab, kui vanemate lõigud on oma sõna öelnud.
Miks root-i erand vastust muudab
Tuum ei rakenda RLIMIT_NPROC protsessile, mis kannab CAP_SYS_RESOURCE või CAP_SYS_ADMIN, mistõttu üksus, mis töötab rootina privileege loovutamata, on selle seadega sisuliselt piiramatu. See üks erand selgitab vasturääkivaid nõuandeid, mida inimesed vahetavad: LimitNPROC tõstmine parandab juurutust, mis loovutas privileegid, ja ei tee absoluutselt mitte midagi selle jaoks, mis jäi privilegeerituks. Kontrollige User= ja seda, kas deemon muudab pärast käivitumist identiteeti, enne kui omistate sellele seadele au või süü. Privilegeeritud üksus, mis hiljem läheb üle mitteprivilegeeritud kontole, langeb ülemineku hetkel uuesti piirangu alla, mis teeb ka rikke ajajoone lugemist väärt.
Rikke staadium kitsendab seda veelgi. Käivituse ettevalmistuse aegne keeldumine, deemon enda teatatud harundamise viga ja cgroupi sees tagasi lükatud ülesande loomine annavad erinevad journali read ja ainult ühele neist vastab suurem eelarve.
Lugege tegelikke väärtusi, mitte kesta omi
Interaktiivse kesta ulimit -u kirjeldab seda kesta. See ei kirjelda, mida teenusehaldur deemonile edasi andis, ega ütle midagi cgroupi arvestuse kohta. Pärige selle asemel üksust, kasutades hostil olemasolevat eksemplarinime, mitte juhendist võetud näidet.
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
Konteineri sees vajab vastus veel kahte lugemist, sest infinity sisemine väärtus kirjeldab ainult külalise vaadet. Küsige hosti omanikult konteineri enda pids-ülempiiri ja kinnitage, kas sisemine teenusehaldur saab seda kontrollerit üldse delegeerida. Pesastatud üksus ei saa hoida eelarvet, mida tema vanem-cgroup kunagi ei andnud.
Mõõtke paranduse suurus ja tõestage seda koormuse all
Valige arv töökoormusest, mitte veatekstist. Loendage protsessid, mida deemon käivitab iga ühendatud kliendi või iga abilise kutse kohta, korrutage paralleelsusega, mida juurutus peaks kandma, lisage varu haldussessioonide jaoks ja võrrelge siis seda arvu kahe tegeliku väärtusega. Kohalik drop-in-i ülekirje hoiab muudatuse ülevaatatavana ja elab üle paketiuuendused, samas kui pakutud üksusefaili muutmine peidab muudatuse, kuni järgmine uuendus selle asendab. Kirjutage aritmeetika ülekirje kõrvale, sest järgmisel inimesel, kes seda tõstab või langetab, on vaja eeldusi, mitte lõplikku arvu.
Eelarve muudatused rakendatakse käivitamisel, seega üksi uuesti laadimine ei muuda juba töötavate protsesside suurust. Taaskäivitage üksus oma tavapärase elutsükli kaudu, võtke vastu sessiooni katkestus ja lugege loendurid uuel eksemplaril uuesti.
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
Parandust tõestab taaskäivitatud üksus, mille ülesannete arv püsib mõlema ülempiiri all, kandes samal ajal kavandatud koormust, pluss journal, mis ei teata enam ülesannete ega harundamise ammendumisest samas staadiumis. Hoidke enne ja pärast numbrid muudatuse juures, et järgmine uurimine algaks mõõtmisest, mitte samast nõuandest. Kui arv jõuab endiselt ülempiirini, oli aritmeetika vale, mitte piirang juhuslikult liiga väike, ja seda erinevust tasub teada enne järgmist taaskäivitust.