はじめに
先日、ELB がヘルスチェックに失敗し、EC2 インスタンスが終了・新規作成されました。
まず、構成は以下の通りです。
こちらは、本ブログ KUDs Blog をホストしている構成です。
WordPress を使用しています。
なお、AutoScaling はシングルインスタンス構成ですので、EC2 の再作成は期待通りです。
しかし、ヘルスチェック失敗はもちろん期待通りではありません。
この記事では、インスタンス再作成時のログから原因を確認します。
また、それに応じた対策を検討、実行します。
インスタンスが終了したからログが見られない!という方は、こちらの記事を参照してください。
こちらの記事では、システムログを CloudWatch Logs に出力する方法を記載しています。
AutoScaling を利用している場合、インスタンスが削除されてしまい、ログが確認できないことが多々あります。
ログがない状況で原因を追究するのは困難ですので、ログ退避は実装しておきましょう。
問題の概要
前述の通り、EC2 では WordPress をホストしています。
通常時には問題なく動作していました。
しかし、突如として ELB のヘルスチェックに失敗してしまいました。
そう、「何もしてないのに壊れた」のです!
ヘルスチェックとは
AWS が提供するサービスの一つで、アプリケーションが正常に応答しているかを定期的に確認します
特に、ELB のヘルスチェックは、ロードバランサーからターゲットとなるインスタンスに対して定期的にリクエストを送り、その応答に基づいてインスタンスのヘルス状態を評価します。
このヘルスチェックが失敗すると、通常はアプリケーションに何らかの問題があることを示しています。
問題の原因を特定するためには、CloudWatch メトリクスや、アプリケーションログ、システムログを詳細に確認する必要があります。
トラブルシューティングの方法については、AWS 公式の記事も参考になります。
原因の特定:OOMの発生
AWS の EC2 インスタンスで発生したヘルスチェックの失敗。
まず、その原因を特定するために確認したのはシステムログです。
そして、そのログからは、OOM エラーを確認できました。
※OOM: Out Of Memory
kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/,task=httpd,pid=7981,uid=48
kernel: Out of memory: Killed process 7981 (httpd) total-vm:604720kB, anon-rss:40696kB, file-rss:0kB, shmem-rss:88kB, UID:48 pgtables:876kB oom_score_adj:0
kernel: httpd invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0
OOM (Out Of Memory) とは?
OOM はシステムが物理的なメモリーを超えてメモリを消費したときに発生します。
この状況は通常、システムによって自動的に管理され、最も重要性が低いと判断されるプロセスが終了されることでメモリを解放します。
ただし、この自動的なプロセスの終了は、適切な監視とログ記録がなされていない場合、突然のアプリケーションの停止やサービスの中断を引き起こす可能性があります。
OOM について詳しく知りたい方は、kernel.org もご参照ください。
メモリ使用量の監視
OOM が発生した場合、最初に確認すべきはインスタンスのメモリ使用量です。
AWS の CloudWatch はデフォルトで多くのメトリクスを提供します。
しかし、残念ながらメモリ使用量はデフォルトでは含まれていません。
このため、free
コマンドやtop
コマンドを使用してリアルタイムでメモリ使用量を確認したり、CloudWatch Agentを使用してメモリ使用量を定期的に監視するなどの手段が必要となります。
以下は、top コマンド実行時の結果です。
top - 05:03:06 up 2:18, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 109 total, 1 running, 65 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.3 st
KiB Mem : 975596 total, 113940 free, 772996 used, 88660 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 86752 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3332 apache 20 0 708148 78772 10428 S 0.0 8.1 0:33.51 httpd
3084 apache 20 0 707876 78676 10428 S 0.0 8.1 0:33.41 httpd
3340 apache 20 0 707876 78660 10428 S 0.0 8.1 0:32.90 httpd
3621 apache 20 0 937276 78640 10584 S 0.0 8.1 0:20.39 httpd
3614 apache 20 0 707840 78624 10584 S 0.0 8.1 0:19.77 httpd
3634 apache 20 0 707688 78464 10436 S 0.0 8.0 0:20.78 httpd
3635 apache 20 0 707828 78460 10436 S 0.0 8.0 0:20.93 httpd
3323 apache 20 0 707972 78416 10428 S 0.0 8.0 0:33.07 httpd
3339 apache 20 0 707828 78308 10428 S 0.0 8.0 0:33.66 httpd
3314 apache 20 0 707852 78296 10428 S 0.0 8.0 0:33.13 httpd
3167 root 24 4 641736 54932 5532 S 0.3 5.6 0:39.20 aws
2971 root 20 0 520032 18424 11796 S 0.0 1.9 0:00.43 httpd
3243 root 20 0 723848 10300 2940 S 0.0 1.1 0:00.28 ssm-agent-worke
3166 root 20 0 255592 9004 3224 S 0.0 0.9 0:00.39 rsyslogd
こちらは OOM 発生時ではありませんが、メモリ使用率が高いことが確認できます。
Swap 領域もないため、いつ OOM が発生してもおかしくない状況ですね。
解決策:Swap領域の作成
メモリ不足によるOOMの発生を解決するための方法はいくつかあります。
例えば、水平 / 垂直スケーリングは常套手段です。
※インスタンスタイプをアップグレードする
※インスタンス数を増やして負荷分散する
しかし、これらの方法は追加のコストが発生します。
今回は、コストを抑えつつメモリ不足に対処するために、Swap 領域を作成します。
Swap 領域とは
Swap 領域はハードドライブの一部を仮想メモリとして利用するものです。
物理メモリが不足した場合にオペレーティングシステムが利用します。
そのため、メモリ不足という問題を緩和する手段として有効です。
しかし、物理メモリよりもアクセス速度は遅い点は注意が必要です。
頻繁にスワッピングが発生する場合、パフォーマンスは低下します。
Swap 領域の作成方法
AWS 公式の記事も参考になりますので、是非ご参照ください。
Linux 系の OS の場合、次の手順で Swap 領域を作成できます。
ここでは、例として 1 GB の Swap 領域を作成します。
スワップファイルを作成
$ sudo dd if=/dev/zero of=/swapfile count=1024 bs=1M
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 15.5141 s, 69.2 MB/s
スワップファイルのパーミッションを変更
$ sudo chmod 600 /swapfile
スワップエリアを設定
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=ff0be66d-a38d-4eb5-91ff-2aca65ddf2a0
スワップ有効化
$ sudo swapon /swapfile
自動マウント設定
$ echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
/swapfile swap swap defaults 0 0
スワップが正しく作成されたことを確認
$ sudo swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 0B -2
$ free -h
total used free shared buff/cache available
Mem: 952M 758M 65M 540K 128M 60M
Swap: 1.0G 0B 1.0G
以上で、メモリが不足した場合でも Swap 領域が利用されます。
これによって、OOM の発生を回避することが可能です。
ただし、Swap 領域はあくまでメモリ不足を一時的に緩和するための手段です。
頻繁に Swap 領域が利用される場合は、パフォーマンスに影響を与えます。
そのため、その原因を特定して適切な対策をとることが重要です。
さいごに
この記事では、EC2 – ELB でのヘルスチェック失敗について調査しました。
まず、その原因が OOM (Out of Memory) であることを特定しました。
次に、Swap 領域の作成という暫定対応を実施しました。
しかし、この対策はあくまで一時的なものです。
将来的には以下のような対策も検討すべきでしょう。
- インスタンスのメモリを増強する:
- メモリが不足しているならメモリを増強するのが常套手段です
- ただし、インスタンスのコストが増加するデメリットがあります
- アプリケーションの最適化:
- アプリケーションのメモリ使用量を抑えるように最適化することも一つの解決策です
- 開発コストが発生しますが、長期的にはインフラコストを抑えることができます
アプリケーションの最適化について、 OOM を Apache / PHP の最適化で回避する記事を書きましたので、こちらも合わせてご覧ください。
なお、メモリ使用率やスワップ使用率については、デフォルトでは CloudWatch メトリクスで確認できません。
メモリ使用率・スワップ使用率を CloudWatch メトリクスで表示する方法については、以下の記事をご覧ください。
以上です。
コメント