はじめに
株式会社じげんのrkinseiです。
留学エージェント比較サービス 留学くらベーるの開発を担当しています。
今回はAWS EC2の「No space left on device」エラーの解決方法を紹介します!
苦戦しながら修正したものの、完璧な対応はまだできていないと思いますが、今回実際に試してみた対処法をまとめてみました。
これから同じエラーを解決したい方の参考になれば幸いです。
エラーの概要
RailsアプリケーションをAWSのEC2インスタンスにデプロイした際に、「no space left on device」とエラーメッセージが表示されます
error An unexpected error occurred: "ENOSPC: no space left on device, copyfile '/home/ec2-user/.cache/yarn/XXXXXXXXX'".
rake aborted!
インスタンスにログインすると、以下のようにエラーメッセージが表示されました。
/home/user/.rbenv/libexec/rbenv-init: 行 131: ヒアドキュメント用一時ファイルを作成できません: デバイスに空き領域がありません
エラーの原因調査
エラーメッセージを読むと「このデバイスにもうスペースが無い」と言われています。
容量不足が発生する原因として、次の2つのパターンがあります。
ディスク容量が不足している
「inode」の容量が不足している
ディスク/inodeの容量を確認する
### ディスクの容量を確認する
「df」コマンドを使ってディスクの空き容量を調べます。基本的には「df -h」だけで十分です。
「df」を実行すると、ディスクの空き領域が表示されます。デフォルトでは、1K(1024バイト)のブロックサイズの表示となります。GBなど、読みやすい単位で表示したい場合は、「-h」オプションを使用します。
空き領域は、マウントしているファイルシステムごと、つまり、パーティションごとに表示されます。空き領域の合計を表示したい場合は、「--total」オプションを使用します。
## 実行例
[ec2-user@ip-XXXXXXXX/]$ df ## ディスクの空き容量を表示する
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
devtmpfs 2009420 60 2009360 1% /dev
tmpfs 2020068 0 2020068 0% /dev/shm
/dev/xvda1 1225231 8220416 3931652 68% /
[ec2-user@ip-XXXXXXXX/]$ df -h ## 読みやすいサイズ表記で表示する
ファイルシス サイズ 使用 残り 使用% マウント位置
devtmpfs 2.0G 60K 2.0G 1% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
/dev/xvda1 12G 7.9G 3.8G 68% /
[ec2-user@ip-XXXXXXXX /]$ df -h --total ##空き領域の合計も併せて表示する
ファイルシス サイズ 使用 残り 使用% マウント位置
devtmpfs 2.0G 60K 2.0G 1% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
/dev/xvda1 12G 7.9G 3.8G 68% /
total 16G 7.9G 7.6G 51% -
まだ3.8Gも残っているので、ディスクに十分な空き容量がある状態です。
ディスクの空き容量がない場合があれば、使用量の大きい不要なファイルを削除する必要があります。
「du」コマンドを実行して削減できる場所を探ってみます
## 実行例
[ec2-user@ip-XXXXXXXx ~]$ sudo du -sh /var/* | sort -rh
4.3G /var/www
294M /var/log
185M /var/cache
168M /var/lib
1.3M /var/spool
148K /var/run
16K /var/lock
16K /var/db
12K /var/kerberos
8.0K /var/empty
4.0K /var/yp
4.0K /var/tmp
4.0K /var/preserve
4.0K /var/opt
4.0K /var/nis
4.0K /var/local
4.0K /var/games
4.0K /var/account
0 /var/mail
### inodeの容量を確認する
ディスクの空き容量がある場合は、続いてinodeの容量を確認します。
- inodeとは:
UNIX系OSの一部のファイルシステムで用いられる、ファイルやディレクトリについての情報を記録した管理データのこと。
inodeの残りはdf
コマンドに「-i」
オプションをつければ確認できます。
[ec2-user@ip-XXXXXXXX /]$ df -i
ファイルシス Iノード I使用 I残り I使用% マウント位置
devtmpfs 502355 441 501914 1% /dev
tmpfs 505017 1 505016 1% /dev/shm
/dev/xvda1 786432 786431 1 100% /
I使用%
が100%
だったため、今回のエラーの原因はinodeの容量不足だということがわかりました
解決法
対処1: 不要なファイルを手動で削除する
① ファイル数が多いディレクトリがどこにあるのかを探す
sudo find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -nr
を実行すると、ルートディレクトリ直下にあるディレクトリのファイル数が表示されます。
コマンドの説明は下記の通りです。
「findコマンド 」: find - ディレクトリ階層下のファイルを検索する
「-xdev」 : マウント先のファイルシステムを検索しないようにしてくれる
「-type f」 :ディレクトリではなく、ファイルのみを対象とし検索する
「cut -d "/" -f 2」 : ファイル「/」の文字で区切り、その2項目目を表示する
「sort | uniq -c」: 重複行を並べ替えてからカウントする (sort省略可)
「sort -nr」: 文字列を数字として認識した上で、降順で表示してくれる
### 実行例
$ sudo find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -nr
357021 var
137808 home
65042 usr
8846 opt
3443 lib
618 etc
281 lib64
176 sbin
99 bin
34 root
30 boot
2 tmp
1 .autorelabel
1 .autofsck
/var
配下のどこに、多数のファイルが存在しているのかがわかりました
② ファイル数が多いディレクトリが見つかったら、そのディレクトリに対して同じコマンドを実行する
$ sudo find /var -xdev -type f | cut -d "/" -f 3 | sort | uniq -c | sort -nr
352693 www
3986 lib
177 log
106 cache
25 run
24 lock
8 spool
1 db
1 account
- ③ 上記の操作を何度か繰り返し、不要なファイルが多数存在しているディレクトリを探す
- ④ 不要なファイルを
sudo rm -rf ディレクトリパス
コマンドで削除する - ⑤ ⏬再びdfコマンドを実行してinodeの容量を確認する ==>「I使用%」の数値が下がっていれば、inodeの容量が確保できています。
[ec2-user@ip-XXXXXXXXX ~]$ df -i
ファイルシス Iノード I使用 I残り I使用% マウント位置
devtmpfs 253915 431 253484 1% /dev
tmpfs 256156 1 256155 1% /dev/shm
/dev/xvda1 786432 313277 473155 40% /
本番環境の場合、ファイルが不要なのかよく確認してください!
対処2: inode のサイズ拡張EBSボリュームを増やす
ディスク容量が小さすぎる場合は、デプロイするたびに手動でファイルを削除して容量を確保する必要があるため、面倒な場合はEBSのボリュームを増やしましょう。
1度ボリュームサイズやタイプを変更すると6時間は変更できなくなるので注意が必要です。
基本的には、下記公式ガイドと参考記事に沿って作業を行えば OK なので、ご参考にしてください。