Ubuntuサーバーの1つには82のゾンビプロセスがあります。すべてのプロセスは、プロセスコマンドとして「[sh]defunct」と表示されます。どのプロセスがゾンビプロセスになるかを調べる方法はありますか?
/proc/PID/
私はゾンビプロセスの手がかりを得るためにディレクトリをチェックしてみましたが、すべてのファイルは空です。誰がこのプロセスをゾンビにしたかを調べる方法...他の方法を見つけることができますか?
アップデート/解決方法:質問をより明確にし、andcozが提案したように私の質問に答えました。
答え1
Linuxカーネルの監査サブシステムは、どのプロセスがゾンビになっているかを調べるのに非常に役立ちます。次のような状況が発生しました。
server ~ # ps -ef --forest
[...]
root 16385 1 0 17:04 ? 00:00:00 /usr/sbin/apache2 -k start
root 16388 16385 0 17:04 ? 00:00:00 \_ /usr/bin/perl -T -CSDAL /usr/lib/iserv/apache_user
root 16389 16385 0 17:04 ? 00:00:00 \_ /usr/bin/perl -T -CSDAL /usr/lib/iserv/apache_user
www-data 16415 16385 0 17:04 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 18254 16415 0 17:23 ? 00:00:00 | \_ [sh] <defunct>
www-data 18347 16415 0 17:23 ? 00:00:00 | \_ [sh] <defunct>
www-data 22966 16415 0 18:18 ? 00:00:00 | \_ [sh] <defunct>
www-data 16583 16385 0 17:05 ? 00:00:01 \_ /usr/sbin/apache2 -k start
www-data 18306 16583 0 17:23 ? 00:00:00 | \_ [sh] <defunct>
www-data 18344 16583 0 17:23 ? 00:00:00 | \_ [sh] <defunct>
www-data 17561 16385 0 17:12 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 22983 17561 0 18:18 ? 00:00:00 | \_ [sh] <defunct>
www-data 18318 16385 0 17:23 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 19725 16385 0 17:43 ? 00:00:01 \_ /usr/sbin/apache2 -k start
www-data 22638 16385 0 18:13 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 22659 16385 0 18:14 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 25102 16385 0 18:41 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 25175 16385 0 18:42 ? 00:00:00 \_ /usr/sbin/apache2 -k start
www-data 25272 16385 0 18:44 ? 00:00:00 \_ /usr/sbin/apache2 -k start
これらのゾンビプロセスの原因はPHPスクリプトである可能性が高いですが、これらのApacheサブプロセスは多数のHTTPリクエストとさまざまなPHPスクリプトを処理しているため、どのプロセスが原因であるかを理解するのは困難です。 Linuxはこれらのゾンビプロセスに関する重要な情報も公開しているため、どのスクリプトやコマンドが/proc/<pid>/cmdline
実行されているかを知る必要さえありません。-c
/bin/sh
server ~ # cat /proc/18254/cmdline
server ~ #
これを理解するために、以下をインストールしましたauditd
。https://linux-audit.com/configuring-and-auditing-linux-systems-with-audit-daemon/
次の監査ルールを設定しました。
auditctl -a always,exit -F arch=b32 -S execve -F path=/bin/dash
auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/dash
これらのルールは、/bin/dash
バイナリのすべてのプロセス生成を監査します。/bin/sh
これはシンボリックリンクなので、これはうまくいかず、監査では明らかにターゲットファイル名のみを見ることができます。
server ~ # ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Nov 8 2014 /bin/sh -> dash*
これで簡単なテストで監査ログが生成されます/var/log/audit/audit.log
(読みやすくするために多くの改行を自由に追加しました)。
server ~ # sh -c 'echo test'
test
server ~ # tail -f /var/log/audit/audit.log
[...]
type=SYSCALL msg=audit(1488219335.976:43871): arch=40000003 syscall=11 \
success=yes exit=0 a0=ffdca3ec a1=f7760e58 a2=ffdd399c a3=ffdca068 items=2 \
ppid=27771 pid=27800 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 \
fsgid=0 tty=pts7 ses=7532 comm="sh" exe="/bin/dash" key=(null)
type=EXECVE msg=audit(1488219335.976:43871): argc=3 a0="sh" a1="-c" \
a2=6563686F2074657374
type=CWD msg=audit(1488219335.976:43871): \
cwd="/var/lib/iserv/remote-support/iserv-martin.von.wittich"
type=PATH msg=audit(1488219335.976:43871): item=0 name="/bin/sh" inode=10403900 \
dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PATH msg=audit(1488219335.976:43871): item=1 name=(null) inode=5345368 \
dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PROCTITLE msg=audit(1488219335.976:43871): \
proctitle=7368002D63006563686F2074657374
ほとんどの情報はエンコードされていますが、ausearch
次のように翻訳できます-i
。
server ~ # ausearch -i -x /bin/dash | tail
[...]
----
type=PROCTITLE msg=audit(27.02.2017 19:15:35.976:43871) : proctitle=sh
type=PATH msg=audit(27.02.2017 19:15:35.976:43871) : item=1 name=(null) \
inode=5345368 dev=08:01 mode=file,755 ouid=root ogid=root rdev=00:00 \
nametype=NORMAL
type=PATH msg=audit(27.02.2017 19:15:35.976:43871) : item=0 name=/bin/sh \
inode=10403900 dev=08:01 mode=file,755 ouid=root ogid=root rdev=00:00 \
nametype=NORMAL
type=CWD msg=audit(27.02.2017 19:15:35.976:43871) : \
cwd=/var/lib/iserv/remote-support/iserv-martin.von.wittich
type=EXECVE msg=audit(27.02.2017 19:15:35.976:43871) : argc=3 a0=sh a1=-c \
a2=echo test
type=SYSCALL msg=audit(27.02.2017 19:15:35.976:43871) : arch=i386 \
syscall=execve success=yes exit=0 a0=0xffdca3ec a1=0xf7760e58 a2=0xffdd399c \
a3=0xffdca068 items=2 ppid=27771 pid=27800 auid=root uid=root gid=root \
euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts7 \
ses=7532 comm=sh exe=/bin/dash key=(null)
----
ausearch
フィルタリングをに制限したくない場合は、完全なログ翻訳を使用することも/bin/dash
できます。この場合、もう一つの良いフィルタはです。ausearch -i -m ALL
ausearch -i -p <PID of a zombie process>
ausearch -i -p 27800
新しいゾンビプロセスが表示されるまでこのルールを維持し、プロセス生成のゾンビPIDを検索します。
ausearch -i -p <PID>
これはゾンビプロセスの根本的な原因を特定するのに非常に役立ちます。私の場合、proc_open
.NET Frameworkを使用せずにPerlスクリプトを生成するのはPHPスクリプトでしたproc_close
。
答え2
答え3
短い答えはあなたが気にしないということです。ゾンビプロセスが終了しました。プロセステーブル内のこのエントリの場合、カーネルメモリのごく一部しか消費しません。
プロセスに残っているのはプロセステーブルのエントリだけなので、これ以上進むことはほとんどありません。ゾンビプロセスは、親がまだリサイクルされていない死んだプロセスです。プロセスのPPIDを確認して、親が誰であるかを確認してください。
答え4
ps auxf | grep --color -5 ' Z '
ゾンビとその親を含むプロセス階層を表示するゾンビスクリプト名を識別するのは、「sh defunct」だけを見ることができるので難しいです。