💽

AMIから起動したRedashのEC2インスタンスが突然500エラーを返すようになった時に対応したこと

2023/11/21に公開

対象読者

この記事は以下の方が対象読者です。

  • 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接続ができない(?)

具体的なログは以下の記事と同じ
https://dev.classmethod.jp/articles/how-to-expand-ec2-storage/

記事の通り no space left on device を解決すれば、インスタンスが期待通りに起動しそう。

ディスク枯渇問題を解決する方法

EBSボリュームを増やす。
https://qiita.com/mangano-ito/items/629b10ea5d1ab80f2cc6#チェック

上記を参照し、EBSのボリュームを 8GiB から 16GiB に変更。
インスタンスの再起動を行ったが、同様のエラーを確認。
ボリュームのサイズを変更したが適用されていない。

ここで公式ドキュメントを読む
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html

パーティション拡張という手順を行う必要がある。
ただし、今回はインスタンスに接続できない状態。どうするか。

ディスク領域が枯渇しているEBSのボリュームを、接続可能なEC2インスタンスにアタッチする

インスタンスに接続できないのであれば、
接続可能なインスタンスに ディスク領域が枯渇しているEBSボリュームをアタッチ し、
パーティション拡張の手順を行えばよいのではないか?という仮説が立つ。のでやっていく。

現在起動しているEC2インスタンスを停止する

AWSマネジメントコンソールからポチポチ。

停止したEC2インスタンスのEBSボリュームをデタッチする

これもAWSマネジメントコンソールからポチポチ。
停止が完了していないとデタッチできないので注意。

新しいEC2インスタンスを起動する

新しく起動するEC2インスタンスは、同じAMIを使用した方が安全。
使用したAMIは以下を参照。
今回使用したリージョンは ap-northeast-1。

https://redash.io/help/open-source/setup#aws

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