Başarısız bir OpenVPN başlatması çoğu zaman bir kaynak şikayetiyle birlikte bir sınırı yükseltmeyi öneren iyi niyetli bir tavsiye olarak gelir ve bu tavsiye yalnızca vakaların yaklaşık yarısında işe yarar. Bu hataların arkasında birbiriyle ilgisiz iki sayaç vardır. Biri, gerçek bir kullanıcı kimliğine ait görev sayısına ilişkin çekirdek sınırıdır ve süreç yürütülürken miras alınır. Diğeri, hizmet yöneticisinin bir birime ve onun çatalladığı her şeye uyguladığı cgroup bütçesidir. Her birinin gerçek değerini, fiilen çalışan birim için okumak bir tahminden daha ucuza gelir.

İki sayaç, iki soru

LimitNPROC, systemd adı altında RLIMIT_NPROC demektir ve hesap birimi gerçek kullanıcı kimliğidir. Bu kullanıcının sahip olduğu her süreç aynı toplama sayılır; diğer birimlerin, bir oturum açma oturumunun veya bir zamanlayıcı işinin başlattığı işler de buna dahildir. Bu nedenle sınır, bir hizmet biriminin içinde ayarlanmış olsa bile hizmet başına bir tavan değildir ve her istemci için bir yardımcı çatallayan hizmet, o hesap altında çalışan diğer her şeyle yarışır. Aynı kullanıcı altındaki meşgul bir cron işi, bir VPN birimini tek başına hiç geçmediği bir çizginin ötesine itebilir.

TasksMax başka bir sahibe sahiptir: birimin cgroup'u üzerindeki pids denetleyicisi; süreçleri değil görevleri sayar. İş parçacıkları da görevdir, bu yüzden tek iş parçacıklı görünen ama işçi havuzu olan bir arka plan programı, süreç sayısından ilk bakışta çok daha büyük görünen bir bütçe tüketebilir. EffectiveTasksMax, üst dilimler sözünü söyledikten sonra cgroup hiyerarşisinin gerçekte neye izin verdiğini bildirir.

root istisnası yanıtı neden değiştirir

Çekirdek, CAP_SYS_RESOURCE veya CAP_SYS_ADMIN taşıyan bir sürece RLIMIT_NPROC uygulamaz; bu yüzden ayrıcalıklardan vazgeçmeden root olarak çalışan bir birim bu ayar karşısında fiilen sınırsızdır. Bu tek istisna, insanların birbirine verdiği çelişkili tavsiyeleri açıklar: LimitNPROC değerini yükseltmek ayrıcalıklardan vazgeçmiş bir kurulumu onarır ve ayrıcalıklı kalmış bir kurulum için hiçbir şey yapmaz. O ayara paye veya suç vermeden önce User= değerini ve arka plan programının başlangıçtan sonra kimliğini değiştirip değiştirmediğini kontrol edin. Ayrıcalıklı bir birim sonradan ayrıcalıksız bir hesaba geçerse geçiş anında yeniden sınırın altına düşer; bu da hatanın zaman çizelgesini okumaya değer kılar.

Hata aşaması bunu daha da daraltır. Yürütme hazırlığı sırasındaki bir ret, arka plan programının kendisinin bildirdiği bir çatallama hatası ve bir cgroup içinde reddedilen görev oluşturma farklı journal satırları üretir ve bunlardan yalnızca birine daha büyük bir bütçeyle yanıt verilir.

Gerçek değerleri okuyun, kabuğunkileri değil

Etkileşimli bir kabuğun ulimit -u değeri o kabuğu tanımlar. Hizmet yöneticisinin arka plan programına ne aktardığını tanımlamaz ve cgroup muhasebesi hakkında hiçbir şey söylemez. Bunun yerine birimi sorgulayın; bir kılavuzdan alınan örnek yerine ana makinede var olan örnek adını kullanın.

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

Bir konteynerin içinde yanıt iki okuma daha gerektirir, çünkü infinity gibi içsel bir değer yalnızca konuğun görünümünü tanımlar. Ana makinenin sahibinden konteynerin kendi pids tavanını isteyin ve iç hizmet yöneticisinin bu denetleyiciyi devredebilip devredemeyeceğini doğrulayın. İç içe bir birim, üst cgroup'unun hiç vermediği bir bütçeyi tutamaz.

Düzeltmenin boyutunu ölçün ve yük altında kanıtlayın

Sayıyı hata metninden değil iş yükünden seçin. Arka plan programının her bağlı istemci veya her yardımcı çağrısı için başlattığı süreçleri sayın, kurulumun taşıması beklenen eşzamanlılıkla çarpın, yönetim oturumları için bir pay ekleyin ve sonra bu sayıyı iki gerçek değerle karşılaştırın. Yerel bir drop-in geçersiz kılma değişikliği gözden geçirilebilir tutar ve paket yükseltmelerinden sonra da kalır, oysa gönderilen bir birim dosyasını düzenlemek, değişikliği bir sonraki güncelleme onu değiştirene kadar gizler. Aritmetiği geçersiz kılmanın yanına yazın, çünkü onu sonra yükseltecek veya düşürecek kişiye son sayı değil varsayımlar gerekir.

Bütçe değişiklikleri yürütme sırasında uygulanır, bu yüzden tek başına yeniden yükleme zaten çalışan süreçlerin boyutunu değiştirmez. Birimi normal yaşam döngüsüyle yeniden başlatın, oturum kesintisini kabul edin ve sayaçları yeni örnekte yeniden okuyun.

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

Onarımı kanıtlayan şey, amaçlanan yükü taşırken görev sayısı iki tavanın da altında kalan yeniden başlatılmış bir birim ve aynı aşamada artık görev veya çatallama tükenmesi bildirmeyen bir journal'dır. Önceki ve sonraki sayıları değişiklikle birlikte saklayın ki bir sonraki inceleme aynı tavsiyeden değil bir ölçümden başlasın. Sayı hâlâ tavana ulaşıyorsa aritmetik yanlıştı, sınır tesadüfen çok küçük değildi; ve bu farkı bir sonraki yeniden başlatmadan önce bilmekte yarar var.

İlgili makaleler