Neizdevusies OpenVPN palaišana bieži nāk kā sūdzība par resursiem kopā ar labi domātu ieteikumu paaugstināt kādu ierobežojumu, un ieteikums darbojas tikai apmēram pusē gadījumu. Aiz šīm kļūmēm stāv divi nesaistīti skaitītāji. Viens ir kodola ierobežojums uz uzdevumu skaitu, kas pieder reālam lietotāja ID, un tas tiek mantots, izpildot procesu. Otrs ir cgroup budžets, ko pakalpojumu pārvaldnieks piemēro vienībai un visam, ko tā atzaro. Izlasīt katra faktisko vērtību tai vienībai, kas patiešām darbojas, izmaksā mazāk nekā minējums.

Divi skaitītāji, divi jautājumi

LimitNPROC ir RLIMIT_NPROC zem systemd nosaukuma, un tā uzskaites vienība ir reālais lietotāja ID. Katrs process, kas pieder šim lietotājam, tiek skaitīts tajā pašā kopsummā, tostarp darbs, ko sākušas citas vienības, pieteikšanās sesija vai plānotāja uzdevums. Tāpēc šis ierobežojums nav katra pakalpojuma griesti arī tad, ja tas ir iestatīts pakalpojuma vienības iekšienē, un pakalpojums, kas katram klientam atzaro palīgu, konkurē ar visu pārējo, kas darbojas ar šo kontu. Aizņemts cron uzdevums zem tā paša lietotāja var pastumt VPN vienību pāri līnijai, kuru tā pati nekad nav šķērsojusi.

TasksMax ir cits īpašnieks: pids kontrolieris uz vienības cgroup, kas skaita uzdevumus, nevis procesus. Pavedieni ir uzdevumi, tāpēc dēmons, kas izskatās vienpavediena, bet kam ir strādnieku kopums, var patērēt budžetu, kas no pirmā acu uzmetiena izskatās daudz lielāks par tā procesu skaitu. EffectiveTasksMax ziņo, ko cgroup hierarhija patiešām atļauj pēc tam, kad vecāku šķēles ir pateikušas savu.

Kāpēc root izņēmums maina atbildi

Kodols nepiemēro RLIMIT_NPROC procesam, kam ir CAP_SYS_RESOURCE vai CAP_SYS_ADMIN, tāpēc vienība, kas darbojas kā root, neatmetot privilēģijas, ar šo iestatījumu praktiski nav ierobežota. Šis vienīgais izņēmums izskaidro pretrunīgos padomus, ko cilvēki apmaina: LimitNPROC palielināšana salabo izvietojumu, kas atteicās no privilēģijām, un nedara absolūti neko tam, kas palika privilēģēts. Pirms piešķirt šim iestatījumam nopelnus vai vainu, pārbaudiet User= un to, vai dēmons pēc palaišanas maina identitāti. Privilēģēta vienība, kas vēlāk pāriet uz kontu bez privilēģijām, pārejas brīdī atkal nokļūst zem ierobežojuma, kas padara arī kļūmes laika līniju lasīšanas vērtu.

Kļūmes posms to vēl vairāk sašaurina. Atteikums izpildes sagatavošanas laikā, paša dēmona ziņotā atzarošanas kļūda un noraidīta uzdevuma izveide cgroup iekšienē dod dažādas journal rindas, un tikai uz vienu no tām atbild lielāks budžets.

Lasiet faktiskās vērtības, nevis čaulas

ulimit -u interaktīvas čaulas apraksta šo čaulu. Tas neapraksta, ko pakalpojumu pārvaldnieks nodeva dēmonam, un neko nesaka par cgroup uzskaiti. Tā vietā vaicājiet vienību, izmantojot resursdatorā esošo instanču nosaukumu, nevis piemēru no rokasgrāmatas.

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

Konteinera iekšienē atbildei vajadzīgas vēl divas nolasīšanas, jo iekšējā infinity vērtība apraksta tikai viesa skatījumu. Pajautājiet resursdatora īpašniekam konteinera paša pids griestus un apstipriniet, vai iekšējais pakalpojumu pārvaldnieks vispār var deleģēt šo kontrolieri. Iekļauta vienība nevar turēt budžetu, ko tās vecāku cgroup nekad nav devis.

Nomēriet labojuma apjomu un pierādiet to slodzē

Izvēlieties skaitli no darba slodzes, nevis no kļūdas teksta. Saskaitiet procesus, ko dēmons palaiž katram pievienotajam klientam vai katram palīga izsaukumam, reiziniet ar paralēlismu, kas izvietojumam jāiztur, pievienojiet rezervi administratīvajām sesijām un pēc tam salīdziniet šo skaitli ar divām faktiskajām vērtībām. Vietējs drop-in pārraksts saglabā izmaiņas pārskatāmas un pārdzīvo pakotņu atjauninājumus, kamēr piegādātā vienības faila rediģēšana paslēpj izmaiņas, līdz nākamais atjauninājums to aizstāj. Pierakstiet aritmētiku blakus pārrakstam, jo nākamajam cilvēkam, kas to paaugstinās vai pazeminās, vajadzīgi pieņēmumi, nevis galīgais skaitlis.

Budžeta izmaiņas tiek piemērotas izpildes laikā, tāpēc tikai atkārtota ielāde nemaina jau darbojošos procesu lielumu. Restartējiet vienību tās parastajā dzīves ciklā, pieņemot sesijas pārtraukumu, un nolasiet skaitītājus vēlreiz jaunajā instancē.

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

Labojumu pierāda restartētā vienība, kuras uzdevumu skaits paliek zem abiem griestiem, kamēr tā nes paredzēto slodzi, kopā ar journal, kas tajā pašā posmā vairs neziņo par uzdevumu vai atzarošanas izsīkumu. Saglabājiet pirms un pēc skaitļus kopā ar izmaiņām, lai nākamā izmeklēšana sāktos ar mērījumu, nevis ar to pašu padomu. Ja skaits joprojām sasniedz griestus, aritmētika bija nepareiza, nevis ierobežojums nejauši pārāk mazs, un šo atšķirību ir vērts zināt pirms nākamās restartēšanas.

Saistītie raksti