LimitNPROC mot TasksMax: hva en OpenVPN-enhet teller
LimitNPROC teller én brukers prosesser i hele systemet; TasksMax begrenser cgroupen til én enhet. Les de effektive verdiene før du hever noen av dem.
En mislykket oppstart av OpenVPN kommer ofte som en klage på ressurser pluss et velment forslag om å heve en grense, og forslaget virker bare omtrent halvparten av gangene. Bak disse feilene står to uavhengige tellere. Den ene er en kjernegrense for antall oppgaver som en ekte bruker-ID eier, og den arves når prosessen kjøres. Den andre er et cgroup-budsjett som tjenestestyringen bruker på en enhet og alt den forgrener. Å lese den effektive verdien av hver av dem, for enheten som faktisk kjører, koster mindre enn en gjetning.
To tellere, to spørsmål
LimitNPROC er RLIMIT_NPROC under et systemd-navn, og regnskapsenheten er den ekte bruker-ID-en. Hver prosess som brukeren eier telles mot den samme summen, inkludert arbeid startet av andre enheter, av en innloggingsøkt eller av en planleggerjobb. Grensen er derfor ikke et tak per tjeneste selv når den er satt inne i en tjenesteenhet, og en tjeneste som forgrener en hjelper for hver klient, konkurrerer med alt annet som kjører under den kontoen. En travel cron-jobb under samme bruker kan skyve en VPN-enhet over en linje den aldri selv krysset.
TasksMax har en annen eier: pids-kontrolleren på enhetens cgroup, som teller oppgaver i stedet for prosesser. Tråder er oppgaver, så en daemon som ser entrådet ut, men har en arbeiderpool, kan bruke et budsjett som ved første øyekast ser langt større ut enn prosessantallet. EffectiveTasksMax rapporterer hva cgroup-hierarkiet faktisk tillater når de overordnede slicene har sagt sitt.
Hvorfor root-unntaket endrer svaret
Kjernen bruker ikke RLIMIT_NPROC på en prosess som bærer CAP_SYS_RESOURCE eller CAP_SYS_ADMIN, og derfor er en enhet som kjører som root uten å gi slipp på privilegier, reelt ubegrenset av den innstillingen. Dette ene unntaket forklarer de motstridende rådene folk utveksler: å heve LimitNPROC reparerer en utrulling som ga slipp på privilegier og gjør absolutt ingenting for en som ble privilegert. Sjekk User= og om daemonen bytter identitet etter oppstart før du gir den innstillingen æren eller skylden. En privilegert enhet som senere bytter til en uprivilegert konto, faller tilbake under grensen i bytteøyeblikket, noe som gjør feilens tidslinje verdt å lese også.
Feilfasen snevrer det ytterligere inn. En avvisning under klargjøring av kjøringen, en forgreningsfeil rapportert av daemonen selv og en avvist oppgaveoppretting inne i en cgroup gir forskjellige journal-linjer, og bare én av dem besvares av et større budsjett.
Les de effektive verdiene, ikke skallens
ulimit -u i et interaktivt skall beskriver det skallet. Det beskriver ikke hva tjenestestyringen sendte til daemonen, og sier ingenting om cgroup-regnskap. Spør enheten i stedet, med instansnavnet som finnes på verten og ikke et eksempel fra en veiledning.
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
Inne i en container trenger svaret to avlesninger til, fordi en indre verdi av infinity bare beskriver gjestens syn. Spør vertens eier om containerens eget pids-tak, og bekreft om den indre tjenestestyringen i det hele tatt kan delegere den kontrolleren. En nestet enhet kan ikke holde et budsjett som dens overordnede cgroup aldri ga.
Dimensjoner rettelsen og bevis den under belastning
Velg et tall fra arbeidsbelastningen i stedet for fra feilteksten. Tell prosessene daemonen starter per tilkoblet klient eller per hjelperkall, multipliser med samtidigheten utrullingen forventes å bære, legg til en margin for administrative økter, og sammenlign deretter tallet med de to effektive verdiene. En lokal drop-in-overstyring holder endringen gjennomgåelig og overlever pakkeoppdateringer, mens redigering av en levert enhetsfil skjuler endringen til neste oppdatering erstatter den. Skriv regnestykket ved siden av overstyringen, fordi neste person som hever eller senker den trenger forutsetningene, ikke det endelige tallet.
Budsjettendringer brukes ved kjøring, så en ny innlasting alene endrer ikke størrelsen på prosesser som allerede kjører. Start enheten på nytt gjennom dens normale livssyklus, godta øktavbruddet, og les tellerne igjen på den nye instansen.
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
Det som beviser reparasjonen, er en omstartet enhet hvis oppgavetall ligger under begge takene mens den bærer den tiltenkte belastningen, pluss en journal som ikke lenger rapporterer oppgave- eller forgreningsutmattelse på samme stadium. Ta vare på tallene før og etter sammen med endringen, slik at neste undersøkelse starter fra en måling og ikke fra det samme rådet. Hvis tallet fortsatt når taket, var regnestykket feil og ikke grensen tilfeldigvis for liten, og den forskjellen er verdt å kjenne før neste omstart.