Fórum Root.cz
Hlavní témata => Server => Téma založeno: Praktik 15. 10. 2016, 15:27:31
-
Dobrý den,
před několika lety jsem objevil chybu v jednom modulu webserveru Apache, která se projevuje neustálou alokací paměti, což způsobí postupné vyžrání volné RAM i swap a vede k OOM.
Chtěl bych omezit množství alokovatelné paměti pomocí /etc/security/limits.conf, ale nějak se to nedaří a nastavení se na uživatele apache neaplikuje. Zkoušel jsem v Scientific Linux 6.1 a CentOS 7.
# /etc/security/limits.conf
apache hard data 524288
apache hard rss 16384
apache hard stack 4096
# /proc/3249/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 3900 3900 processes
Max open files 1024 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 3900 3900 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
Má prosím někdo nápad, jak by šlo nastavení vynutit?
P.S. Bylo by dobré na této diskusi prodloužit dobu přihlášení, protože než jsem stihl napoprvé příspěvek napsat a odeslat, tak mě systém odhlásil a já jsem o něj přišel.
-
P.S. Bylo by dobré na této diskusi prodloužit dobu přihlášení, protože než jsem stihl napoprvé příspěvek napsat a odeslat, tak mě systém odhlásil a já jsem o něj přišel.
To je v pohodě, to jsem tady hlásil už v roce 2014. To je ještě brzo na nějakou opravu.
-
/etc/security/limits.conf nastavuje limity přes PAM, ale Apache se nespouští přes PAM.
Limity lze nastavovat pomocí systemd vytvořením souboru /etc/systemd/system/httpd.service.d/limits.conf s obsahem:
[Service]
LimitDATA=524288
LimitRSS=16384
LimitSTACK=4096
-
Limity lze nastavovat pomocí systemd vytvořením souboru /etc/systemd/system/httpd.service.d/limits.conf
Děkuji. V Scientific Linux 6.1 aka CentOS 6.1 nemám systemd.
Vypadá to, že v CentOS 7 se pak limity nastaví (jen jsem musel zvýšit LimitSTACK=32768, aby Apache nastartoval), ale nezabije se proces, jakmile překročí povolených LimitDATA=524288, takže omezování za běhu nefunguje. Proces se ukončí jako zombie až potom, co se od něj odpojí HTTP klient, který chybu alokace paměti vzdáleně vyvolává.
Co je to za šlendrián? Tak by měl ulimit fungovat?
# /proc/4465/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size 524288 524288 bytes
Max stack size 32768 32768 bytes
Max core file size 0 unlimited bytes
Max resident set 16384 16384 bytes
Max processes 3900 3900 processes
Max open files 1024 4096 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 3900 3900 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
# /proc/4465/status
Name: httpd
State: S (sleeping)
Tgid: 4465
Ngid: 0
Pid: 4465
PPid: 4460
TracerPid: 0
Uid: 48 48 48 48
Gid: 48 48 48 48
FDSize: 64
Groups: 48
VmPeak: 1164380 kB
VmSize: 1164380 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 649780 kB
VmRSS: 649780 kB
VmData: 985616 kB
VmStk: 32 kB
VmExe: 468 kB
VmLib: 8336 kB
VmPTE: 2112 kB
VmSwap: 0 kB
Threads: 27
SigQ: 0/3900
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: fffffffe3ffba207
SigIgn: 0000000001001000
SigCgt: 00000001880046eb
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff
Seccomp: 0
Cpus_allowed: 1
Cpus_allowed_list: 0
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1
nonvoluntary_ctxt_switches: 1
-
Proces se ukončí jako zombie až potom, co se od něj odpojí HTTP klient, který chybu alokace paměti vzdáleně vyvolává.
Toto bylo chybné vyhodnocení z mé strany. K zabíjení zombíka docházelo z důvodu stále moc malé hodnoty LimitSTACK. S touto konfigurací přežívá proces všechno:
[Service]
LimitDATA=524288
LimitRSS=16384
LimitSTACK=65536
Jak tedy omezit procesy, aby nemohly zabrat celou paměť?
-
Zkusil bych sem doplnit
/etc/pam.d/common-session
/etc/pam.d/common-session-noninteractive
/etc/pam.d/login
session required pam_limits.so
Mohlo by to zabrat, nicméně je to případ od případu jiné.
-
Zkusil bych sem doplnit
/etc/pam.d/common-session
/etc/pam.d/common-session-noninteractive
/etc/pam.d/login
session required pam_limits.so
Mohlo by to zabrat, nicméně je to případ od případu jiné.
První dva soubory na CentOS nemám, ale /etc/pam.d/login obsahuje include /etc/pam.d/system-auth, který ho již obsahuje.
V Scientific Linux (CentOS) 6.1 se mi to zatím podařilo vyřešit nastavením limitu "virtual memory", ale globálně pro celý Apache v konfiguračním souboru /etc/sysconfig/httpd příkazem:
ulimit -d 131072 -m 16384 -s 4096 -v 524288
V CentOS 7 pomohlo přidání odpovídající volby LimitAS do /etc/systemd/system/httpd.service.d/limits.conf a vynásobení 1024, protože výchozí jednotky jsou tam bajty a ne kilobajty jako v limits.conf.
[Service]
LimitDATA=134217728
LimitRSS=16777216
LimitSTACK=4194304
LimitAS=536870912
Jinak omezení paměti DATA a RSS se v rámci systému zřejmě vůbec nevynucuje, protože změna hodnot neměla na nic vliv.
Pokud ještě někoho napadne něco lepšího, tak další pomoc uvítám. Děkuji.
P.S. Bylo by dobré na této diskusi prodloužit dobu přihlášení, protože než jsem stihl napoprvé příspěvek napsat a odeslat, tak mě systém odhlásil a já jsem o něj přišel.
To je v pohodě, to jsem tady hlásil už v roce 2014. To je ještě brzo na nějakou opravu.
Tak to je opravdu ostuda, protože je dost otravné se každých 30 minut přihlašovat.