OOM Killer発動時にサーバーを再起動する方法

OOM Killer発動時にサーバーを再起動する方法 サーバー

VPSで管理してるWEBサイトの死活監視のアラートメールが届き、ブラウザでチェックしたらサイトが見れない。SSHでログをチェックしたら「httpd invoked oom-killer:」の文字が…。

OOM KillerさんにApache(httpd)のプロセスが強制終了させられたらしい。

Jan 12 11:37:53 ns1 kernel: httpd invoked oom-killer: gfp_mask=0x200da, order=0, oom_score_adj=0
Jan 12 11:37:53 ns1 kernel: httpd cpuset=/ mems_allowed=0
Jan 12 11:37:53 ns1 kernel: CPU: 0 PID: 18178 Comm: httpd Not tainted 3.10.0-957.1.3.el7.x86_64 #1
Jan 12 11:37:53 ns1 kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Jan 12 11:37:53 ns1 kernel: Call Trace:
Jan 12 11:37:53 ns1 kernel: [<ffffffff84161e41>] dump_stack+0x19/0x1b
Jan 12 11:37:53 ns1 kernel: [<ffffffff8415c86a>] dump_header+0x90/0x229
Jan 12 11:37:53 ns1 kernel: [<ffffffff83b01052>] ? ktime_get_ts64+0x52/0xf0
...以下略...

更にApacheのログを見たら不審なIPアドレスから大量アクセスの形跡を発見。

とりあえずサーバーを再起動して復旧させた。

今後このような事態の際には強制的にサーバーを再起動してメール通知を行うようにする。

※動作確認環境
CentOS 7.6
Apache 2.4.6

OOM Killerの確認

OOM Killer(Out of Memory Killer)とはサーバーのメモリが枯渇してシステムが必要なメモリを新たに確保できない際に(これをOOMという)、既存のプロセスを強制終了させて空きメモリを確保するというLinuxカーネルの機能。

メモリ不足でOOM Killerが発動した場合は、「oom_score_adj」という値が高い順にプロセスを停止していく。

とりあえず今現在の「oom_score_adj」の優先順位の設定を確認する。

# for pid in /proc/[0-9]*; do echo "cat $pid/comm: cat $pid/oom_score_adj"; done|sort|uniq
/usr/bin/spamd : 0
/usr/libexec/we: 0
NetworkManager: 0
agetty: 0
anvil: 0
ata_sff: 0
auditd: -1000
bash: 0
bioset: 0
chronyd: 0
clamd: 0
config: 0
crond: 0
crypto: 0
dbus-daemon: -900
deferwq: 0
...以下略...
# for pid in /proc/[0-9]*; do if [ "cat $pid/comm" == httpd ]; then echo "cat $pid/comm: cat $pid/oom_score_adj"; fi done|uniq
httpd: 0
# for pid in /proc/[0-9]*; do if [ "cat $pid/oom_score_adj" != 0 ]; then echo "cat $pid/comm: cat $pid/oom_score_adj"; fi done|sort|uniq
auditd: -1000
dbus-daemon: -900
sshd: -1000
systemd-udevd: -1000

優先順位設定を見てみたところ、Apache(httpd)の優先度はゼロ(0)で全プロセス中一位タイなので真っ先に強制終了させられたんでしょうね。

Apache(httpd)の強制終了優先度を下げる(又は上げる)という手もありますが、このVPSでメモリ不足になる原因はほぼ99.9%Apacheなので、OOM発動時は潔くサーバーを再起動させることにします。

現在のVPSはSSDが主流なのでサーバーの再起動もとても速いですからね。

対策

OOM発動時にサーバーを再起動

OOM発動時にサーバーを再起動させるには以下の手順を踏みます。

  1. OOMが発動したら「カーネルパニック」を発生させる。
  2. 「カーネルパニック」が発生したらサーバーを再起動する。

この設定を行っていきます。

OOMの設定変更

現在のOOMの設定を確認します。

# sysctl vm.panic_on_oom kernel.panic
vm.panic_on_oom = 0
kernel.panic = 0

OOM設定の設定ファイルを「/etc/sysctl.d/」以下に作成します。
※ファイル名は「oom_reboot.conf」とします。

# vi /etc/sysctl.d/oom_reboot.conf
vm.panic_on_oom=1
kernel.panic=30
【設定内容】
「vm.panic_on_oom=1」でOOM発動時にカーネルパニックを発生させ、「kernel.panic=30」で30秒後にリブートします。

設定を反映させます。

# sysctl --system

設定が変更されたか確認します。

# sysctl vm.panic_on_oom kernel.panic
vm.panic_on_oom = 1
kernel.panic = 30

ちゃんと設定が変更されました。

サーバー再起動時にメール通知を行う設定

OOM Killerの発生頻度やシステムの状況を把握するために、サーバー再起動時にはcronにてメール通知を行う設定も追加します。

「mailx」をインストール

# yum -y install mailx
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.iij.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ mailx.x86_64 0:12.5-19.el7 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

======================================================================================================================
 Package                   アーキテクチャー           バージョン                       リポジトリー              容量
======================================================================================================================
インストール中:
 mailx                     x86_64                     12.5-19.el7                      base                     245 k

トランザクションの要約
======================================================================================================================
インストール  1 パッケージ

総ダウンロード容量: 245 k
インストール容量: 466 k
Downloading packages:
mailx-12.5-19.el7.x86_64.rpm                                                                   | 245 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : mailx-12.5-19.el7.x86_64                                                              1/1 
  検証中                  : mailx-12.5-19.el7.x86_64                                                              1/1 

インストール:
  mailx.x86_64 0:12.5-19.el7                                                                                          

完了しました!

cron設定

# crontab -e
@reboot echo "cron reboot mail" | mail -s "$(hostname) is rebooted" 受け取りたいメールアドレス

これでメールを受信できます。

うむ。これで万全。備えあれば憂い無し。
以上で解決です。

タイトルとURLをコピーしました