LimitNPROC və TasksMax: OpenVPN vahidi nəyi sayır
LimitNPROC bir istifadəçinin proseslərini bütün sistem üzrə sayır; TasksMax isə bir vahidin cgroup həddini müəyyən edir. Hər hansı birini artırmazdan əvvəl faktiki dəyərləri oxuyun.
Uğursuz OpenVPN başlatması çox vaxt resurs şikayəti və hansısa limiti artırmaq barədə yaxşı niyyətli bir təklif şəklində gəlir, bu təklif isə yalnız təxminən yarısında işləyir. Bu uğursuzluqların arxasında bir-biriylə əlaqəsiz iki sayğac durur. Biri real istifadəçi ID-sinə məxsus tapşırıqların sayına dair nüvə limitidir və proses icra olunarkən miras alınır. Digəri xidmət menecerinin vahidə və onun törətdiyi hər şeyə tətbiq etdiyi cgroup büdcəsidir. Hər birinin faktiki dəyərini, həqiqətən işləyən vahid üçün oxumaq təxmin etməkdən ucuz başa gəlir.
İki sayğac, iki sual
LimitNPROC systemd adı altında RLIMIT_NPROC deməkdir və onun hesab vahidi real istifadəçi ID-sidir. Həmin istifadəçiyə məxsus hər proses eyni cəmiyə sayılır, o cümlədən başqa vahidlər, giriş sessiyası və ya planlaşdırıcı tapşırığı tərəfindən başladılan işlər. Buna görə bu limit xidmət vahidi içində təyin olunsa belə, xidmət başına sərhəd deyil və hər müştəri üçün köməkçi proses törədən xidmət həmin hesabla işləyən hər şeylə rəqabət aparır. Eyni istifadəçi altında işləyən məşğul bir cron tapşırığı VPN vahidini təkbaşına heç vaxt keçmədiyi həddən o tərəfə itələyə bilər.
TasksMax fərqli sahibə malikdir: vahidin cgroup-u üzərindəki pids nəzarətçisi, hansı ki prosesləri deyil, tapşırıqları sayır. Saplar tapşırıqdır, yəni işçi hovuzu olan və bir saplı görünən daemon proses sayından qat-qat böyük görünən büdcəni istehlak edə bilər. EffectiveTasksMax isə valideyn dilimləri sözünü dedikdən sonra cgroup iyerarxiyasının həqiqətən nəyə icazə verdiyini göstərir.
Kök istisnası cavabı niyə dəyişir
Nüvə CAP_SYS_RESOURCE və ya CAP_SYS_ADMIN daşıyan prosesə RLIMIT_NPROC tətbiq etmir; buna görə imtiyazlardan əl çəkmədən root kimi işləyən vahid həmin parametrlə faktiki olaraq məhdudiyyətsizdir. Bu tək istisna insanların bir-birinə verdiyi ziddiyyətli məsləhəti izah edir: LimitNPROC dəyərini artırmaq imtiyazlardan əl çəkmiş quraşdırmanı düzəldir və imtiyazlı qalmış biri üçün heç nə etmir. Həmin parametri tərifləməzdən və ya günahlandırmazdan əvvəl User= dəyərinə və daemonun işə başladıqdan sonra kimliyini dəyişib-dəyişmədiyinə baxın. Sonradan imtiyazsız hesaba keçən imtiyazlı vahid keçid anında yenidən limitin altına düşür, bu da uğursuzluğun zaman xəttini oxumağa dəyər edir.
Uğursuzluq mərhələsi məsələni daha da daraldır. İcra hazırlığı zamanı rədd, daemonun özünün bildirdiyi fork xətası və cgroup daxilində rədd edilmiş tapşırıq yaratma fərqli jurnal sətirləri verir və onlardan yalnız birinə daha böyük büdcə cavab verir.
Faktiki dəyərləri oxuyun, qabığınkını deyil
İnteraktiv qabığın ulimit -u dəyəri həmin qabığı təsvir edir. O, xidmət menecerinin daemona nə ötürdüyünü təsvir etmir və cgroup hesablaşması barədə heç nə demir. Bunun əvəzinə vahidi sorğulayın, təlimdən götürülmüş nümunə yerinə hostda mövcud olan instansiya adından istifadə edin.
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
Konteyner daxilində cavab üçün daha iki oxunuş lazımdır, çünki infinity kimi daxili dəyər yalnız qonağın baxışını təsvir edir. Host sahibindən konteynerin öz pids sərhədini soruşun və daxili xidmət menecerinin həmin nəzarətçini ümumiyyətlə delegasiya edə bilib-bilmədiyini təsdiqləyin. İç-içə vahid valideyn cgroup-unun heç vaxt vermədiyi büdcəni saxlaya bilməz.
Düzəlişin həcmini ölçün və yük altında sübut edin
Rəqəmi xəta mətnindən deyil, iş yükündən götürün. Daemonun hər qoşulmuş müştəri və ya hər köməkçi çağırışı üçün başlatdığı prosesləri sayın, quraşdırmanın daşıması gözlənilən paralelliklə vurun, inzibati sessiyalar üçün ehtiyat pay əlavə edin, sonra bu rəqəmi iki faktiki dəyərlə müqayisə edin. Yerli drop-in əvəzləməsi dəyişikliyi yoxlanıla bilən saxlayır və paket yeniləmələrindən sonra da qalır, halbuki paketlə gələn vahid faylını redaktə etmək dəyişikliyi növbəti yeniləmə onu əvəz edənədək gizlədir. Hesabı əvəzləmənin yanında yazın, çünki onu sonradan artıracaq və ya azaldacaq adam yekun rəqəmə deyil, fərziyyələrə ehtiyac duyur.
Büdcə dəyişiklikləri icra zamanı tətbiq olunur, yəni tək yükləmə artıq işləyən proseslərin ölçüsünü dəyişmir. Vahidi normal həyat dövrü ilə yenidən başladın, sessiya kəsilməsini qəbul edin və sayğacları yeni instansiyada yenidən oxuyun.
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
Təmiri sübut edən şey, hədəflənən yükü daşıyarkən tapşırıq sayı hər iki sərhədin altında qalan yenidən başladılmış vahid və eyni mərhələdə artıq tapşırıq və ya fork tükənməsi bildirməyən jurnaldır. Əvvəl-sonra rəqəmlərini dəyişikliklə birlikdə saxlayın ki, növbəti araşdırma eyni məsləhətdən deyil, ölçmədən başlasın. Əgər say hələ də sərhədə çatırsa, deməli hesab səhv idi, limit təsadüfən çox kiçik deyildi və bu fərqi növbəti yenidən başlatmadan əvvəl bilməyə dəyər.