Epäonnistunut OpenVPN-käynnistys saapuu usein resurssivalituksena ja hyväntahtoisena ehdotuksena nostaa rajaa, ja ehdotus toimii vain noin puolessa tapauksista. Näiden epäonnistumisten takana on kaksi toisistaan riippumatonta laskuria. Toinen on ytimen raja sille, kuinka monta tehtävää todellinen käyttäjätunnus omistaa, ja se periytyy prosessia käynnistettäessä. Toinen on cgroup-budjetti, jota palvelunhallinta soveltaa yksikköön ja kaikkeen, mitä se haarauttaa. Kummankin tehollisen arvon lukeminen, sen yksikön osalta joka todella käynnistyy, maksaa vähemmän kuin arvaus.

Kaksi laskuria, kaksi kysymystä

LimitNPROC on RLIMIT_NPROC systemd-nimen alla, ja sen laskentayksikkö on todellinen käyttäjätunnus. Jokainen prosessi, jonka kyseinen käyttäjä omistaa, lasketaan samaan summaan, mukaan lukien työ, jonka ovat käynnistäneet muut yksiköt, kirjautumisistunto tai ajastimen tehtävä. Raja ei siis ole palvelukohtainen yläraja, vaikka se asetettaisiin palveluyksikön sisällä, ja palvelu, joka haarauttaa avustajan jokaista asiakasta varten, kilpailee kaiken saman tilin alla toimivan kanssa. Kiireinen cron-tehtävä saman käyttäjän alla voi työntää VPN-yksikön yli rajan, jota se ei itse koskaan ylittänyt.

TasksMax on eri omistaja: yksikön cgroupin pids-ohjain, joka laskee tehtäviä eikä prosesseja. Säikeet ovat tehtäviä, joten yhden säikeen näköinen mutta työntekijäaltaan omaava taustapalvelu voi kuluttaa budjetin, joka ensisilmäyksellä näyttää paljon suuremmalta kuin sen prosessimäärä. EffectiveTasksMax kertoo, mitä cgroup-hierarkia todella sallii, kun ylemmät lohkot ovat sanoneet sanottavansa.

Miksi root-poikkeus muuttaa vastausta

Ydin ei sovella RLIMIT_NPROC prosessiin, jolla on CAP_SYS_RESOURCE tai CAP_SYS_ADMIN, minkä vuoksi ilman etuoikeuksien luovuttamista rootina toimiva yksikkö on käytännössä rajoittamaton sen asetuksen osalta. Tämä yksi poikkeus selittää ristiriitaiset neuvot, joita ihmiset vaihtavat: LimitNPROC-rajan nostaminen korjaa käyttöönoton, joka luopui etuoikeuksista, eikä tee lainkaan mitään sille, joka pysyi etuoikeutettuna. Tarkista User= ja se, vaihtaako taustapalvelu identiteettiään käynnistymisen jälkeen, ennen kuin annat asetukselle ansion tai syyn. Etuoikeutettu yksikkö, joka myöhemmin siirtyy etuoikeudettomaan tiliin, putoaa takaisin rajan alle siirtymän hetkellä, mikä tekee myös vian aikajanasta lukemisen arvoisen.

Vian vaihe kaventaa sitä edelleen. Kieltäytyminen suorituksen valmistelun aikana, taustapalvelun itsensä raportoima haarautumisvirhe ja hylätty tehtävän luonti cgroupin sisällä tuottavat erilaisia journal-rivejä, ja vain yhteen niistä vastaa suurempi budjetti.

Lue teholliset arvot, älä kuoren

Interaktiivisen kuoren ulimit -u kuvaa tuota kuorta. Se ei kuvaa sitä, mitä palvelunhallinta välitti taustapalvelulle, eikä sano mitään cgroup-kirjanpidosta. Kysy sen sijaan yksikköä käyttäen isännällä olevaa instanssinimeä eikä oppaasta otettua esimerkkiä.

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

Kontin sisällä vastaus tarvitsee kaksi lukemaa lisää, koska sisäinen infinity-arvo kuvaa vain vieraan näkymää. Kysy isännän omistajalta kontin oma pids-yläraja ja varmista, voiko sisäinen palvelunhallinta ylipäätään delegoida tämän ohjaimen. Sisäkkäinen yksikkö ei voi pitää budjettia, jota sen ylempi cgroup ei koskaan myöntänyt.

Mitoita korjaus ja todista se kuormituksessa

Valitse luku työkuormasta, älä virhetekstistä. Laske prosessit, jotka taustapalvelu käynnistää kutakin liitettyä asiakasta tai kutakin avustajakutsua kohden, kerro rinnakkaisuudella, jonka käyttöönoton odotetaan kantavan, lisää marginaali hallinnollisia istuntoja varten ja vertaa sitten lukua kahteen teholliseen arvoon. Paikallinen drop-in-korvaus pitää muutoksen tarkistettavana ja kestää pakettipäivitykset, kun taas toimitetun yksikkötiedoston muokkaaminen kätkee muutoksen, kunnes seuraava päivitys korvaa sen. Kirjoita laskelma korvauksen viereen, koska seuraava sitä nostava tai laskeva henkilö tarvitsee oletukset eikä lopullista lukua.

Budjettimuutokset otetaan käyttöön suorituksen yhteydessä, joten pelkkä uudelleenlataus ei muuta jo käynnissä olevien prosessien kokoa. Käynnistä yksikkö uudelleen sen normaalin elinkaaren kautta, hyväksy istunnon keskeytys ja lue laskurit uudelleen uudesta instanssista.

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

Korjauksen todistaa uudelleenkäynnistetty yksikkö, jonka tehtävämäärä pysyy molempien ylärajojen alapuolella samalla kun se kantaa aiottua kuormaa, sekä journal, joka ei enää ilmoita tehtävien tai haarautumisten loppumisesta samassa vaiheessa. Säilytä ennen ja jälkeen -luvut muutoksen yhteydessä, jotta seuraava tutkimus alkaa mittauksesta eikä samasta neuvosta. Jos määrä yhä saavuttaa ylärajan, laskelma oli väärin eikä raja sattumalta liian pieni, ja tuo ero kannattaa tietää ennen seuraavaa uudelleenkäynnistystä.

Aiheeseen liittyvät artikkelit