AMIから起動したRedashのEC2インスタンスが突然500エラーを返すようになった時に対応したこと
対象読者
この記事は以下の方が対象読者です。
- EC2インスタンスのシステムログを確認すると
no space left on device
エラー が発生していて正常に起動しない - EC2インスタンスにデプロイしているアプリケーションが500エラーを返すようになった
Redashユーザーに限らず参考になると思います。
何が起きたのか
- いつも見ているRedashが突然
Internal Server Error
をレスポンス - EC2は正常に起動していてステータスチェックも問題なし
- AWSマネジメントコンソールからEC2インスタンスに接続を試したが credential error
原因
・EC2インスタンスのシステムログを確認すると、no space left on device
エラーを発見
・systemctl周りの起動が正常に行えていないエラーもありSSH接続ができない(?)
具体的なログは以下の記事と同じ
記事の通り no space left on device
を解決すれば、インスタンスが期待通りに起動しそう。
ディスク枯渇問題を解決する方法
EBSボリュームを増やす。
上記を参照し、EBSのボリュームを 8GiB から 16GiB に変更。
インスタンスの再起動を行ったが、同様のエラーを確認。
ボリュームのサイズを変更したが適用されていない。
ここで公式ドキュメントを読む
パーティション拡張という手順を行う必要がある。
ただし、今回はインスタンスに接続できない状態。どうするか。
ディスク領域が枯渇しているEBSのボリュームを、接続可能なEC2インスタンスにアタッチする
インスタンスに接続できないのであれば、
接続可能なインスタンスに ディスク領域が枯渇しているEBSボリュームをアタッチ
し、
パーティション拡張の手順を行えばよいのではないか?という仮説が立つ。のでやっていく。
現在起動しているEC2インスタンスを停止する
AWSマネジメントコンソールからポチポチ。
停止したEC2インスタンスのEBSボリュームをデタッチする
これもAWSマネジメントコンソールからポチポチ。
停止が完了していないとデタッチできないので注意。
新しいEC2インスタンスを起動する
新しく起動するEC2インスタンスは、同じAMIを使用した方が安全。
使用したAMIは以下を参照。
今回使用したリージョンは ap-northeast-1。
SSH接続ができることを確認する
ssh ubuntu@IPアドレス -i 秘密鍵
ディスク領域が枯渇しているEBSのボリュームを起動したEC2インスタンスにアタッチする
ボリュームをアタッチするときのデバイス名は /dev/sdf
パーティション拡張の手順
新しいEC2インスタンスにSSHしている状態で以下の作業を行う
- ディスク領域が枯渇しているEBSのボリュームをこのインスタンスにマウント
- パーティション拡張
- 不要なファイルを削除
ディスク領域が枯渇しているEBSボリュームをインスタンスにマウント
まずはボリュームがアタッチされていることを確認する。
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 18M 1 loop /snap/amazon-ssm-agent/1480
loop1 7:1 0 105.8M 1 loop /snap/core/16202
xvda 202:0 0 16G 0 disk
└─xvda1 202:1 0 16G 0 part /
xvdf 202:80 0 16G 0 disk
└─xvdf1 202:81 0 8G 0 part
xvda
は、新しいEC2に使用されているボリューム
xvdf
は、ディスク領域が枯渇しているボリューム
上記の結果から枯渇したEBSボリュームがアタッチされていることが確認できた。
また、xvdfには16GiBのディスク領域があるが、xvdf1には8GiBのパーティションで割り当てられている。
AWSマネジメントコンソールからお手軽にボリュームサイズを増加させられるため、マネジメントコンソールをポチポチして対応完了と認識してしまいやすいので注意。
実際はパーティション拡張を行う必要がある。
パーティションの拡張
sudo growpart /dev/xvdf 1
CHANGED: partition=1 start=2048 old: size=16775135 end=16777183 new: size=33552351,end=33554399
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 105.8M 1 loop /snap/core/16202
loop1 7:1 0 18M 1 loop /snap/amazon-ssm-agent/1480
xvda 202:0 0 16G 0 disk
└─xvda1 202:1 0 16G 0 part /
xvdf 202:80 0 16G 0 disk
└─xvdf1 202:81 0 16G 0 part
これで 8Gのパーティションから16Gのパーティションに変更が完了した。
しかし、この設定ではディスク領域の拡張は完了していない(この理由については後述)。
もう一度ファイルシステムを確認する。
sudo file -s /dev/xvd*
/dev/xvda: DOS/MBR boot sector
/dev/xvda1: Linux rev 1.0 ext4 filesystem data, UUID=c530eaa8-71ad-4d2e-8870-a15b5f24e30e, volume name "cloudimg-rootfs" (needs journal recovery) (extents) (64bit) (large files) (huge files)
/dev/xvdf: DOS/MBR boot sector
/dev/xvdf1: Linux rev 1.0 ext4 filesystem data, UUID=c530eaa8-71ad-4d2e-8870-a15b5f24e30e, volume name "cloudimg-rootfs" (extents) (64bit) (large files) (huge files)
再掲になるが
/dev/xvda
は、新しいEC2インスタンスに使用されているボリューム
/dev/xvdf
は、ディスク領域が枯渇しているEBSボリューム
/dev/xvdf
を、CLIから操作できるようにマウントする。
sudo mkdir /mt/xvdf/
sudo mount /dev/xvdf1 /mnt/xvdf/
ここでディスク領域を確認する
df
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1007744 0 1007744 0% /dev
tmpfs 203976 1224 202752 1% /run
/dev/xvda1 16197480 3616752 12564344 23% /
tmpfs 1019872 0 1019872 0% /dev/shm
tmpfs 5120 0 5120 0% /run/lock
tmpfs 1019872 0 1019872 0% /sys/fs/cgroup
/dev/loop0 18432 18432 0 100% /snap/amazon-ssm-agent/1480
/dev/loop1 108416 108416 0 100% /snap/core/16202
tmpfs 203972 0 203972 0% /run/user/1000
/dev/xvdf1 8056264 8039880 0 100% /mnt/xvdf
/dev/xvdf1
に8GBしか割り当てられていないことがわかり、100%の領域が使用されている。
そりゃ no space left on device
吐きますよね...
パーティション拡張を行ったのになぜ8GBのままなのだろうか?
これはファイルシステムのディスク領域が8GBと設定されているから。
よって、ファイルシステムのディスク領域を16GBに変更する。
sudo resize2fs /dev/xvdf1
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/xvdf1 is mounted on /mnt/xvdf; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 2
The filesystem on /dev/xvdf1 is now 4194043 (4k) blocks long.
df -h
Filesystem Size Used Avail Use% Mounted on
udev 985M 0 985M 0% /dev
tmpfs 200M 1.2M 198M 1% /run
/dev/xvda1 16G 3.5G 12G 23% /
tmpfs 996M 0 996M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 996M 0 996M 0% /sys/fs/cgroup
/dev/loop0 18M 18M 0 100% /snap/amazon-ssm-agent/1480
/dev/loop1 106M 106M 0 100% /snap/core/16202
tmpfs 200M 0 200M 0% /run/user/1000
/dev/xvdf1 16G 7.7G 7.8G 50% /mnt/xvdf
なんということでしょう、使用領域が綺麗に100%から50%に。
これでパーティションの拡張作業は完了です。
ついでに不要なファイルを削除する
Redashはログファイルを出力し続けているようです。
1GB以上のファイルを抽出するコマンド
/mnt/xvdf$ sudo find ./ -size +1G
./var/lib/docker/containers/a0933fe0732c8b3327c8e0ea10fde8fa96706e70122d01bffa0a0b8a546108c6/a0933fe0732c8b3327c8e0ea10fde8fa96706e70122d01bffa0a0b8a546108c6-json.log
↑を削除
df
Filesystem 1K-blocks Used Available Use% Mounted on
udev 1007744 0 1007744 0% /dev
tmpfs 203976 1224 202752 1% /run
/dev/xvda1 16197480 3616808 12564288 23% /
tmpfs 1019872 0 1019872 0% /dev/shm
tmpfs 5120 0 5120 0% /run/lock
tmpfs 1019872 0 1019872 0% /sys/fs/cgroup
/dev/loop0 18432 18432 0 100% /snap/amazon-ssm-agent/1480
/dev/loop1 108416 108416 0 100% /snap/core/16202
tmpfs 203972 0 203972 0% /run/user/1000
/dev/xvdf1 16197480 6190352 9990744 39% /mnt/xvdf
11%削減。
インスタンスを停止してボリュームをアタッチし直す
- インスタンスを停止する
- 全てのボリュームをデタッチする
- 枯渇していたボリュームを デバイス名
/dev/xvda
としてアタッチ - インスタンスを再起動
Fin.
最後に
いずれ同じように no space left on device
が発生することは予想できます。
それまでに以下の対策を行っておく必要がありますね。
- ディスク領域をCloud Watch Alarm などで監視
- 定期的にログファイルを削除するcronの実行
同様の問題で困った方の助けになれば幸いです!
Happy Coding!
Discussion