はじめに
先日、EC2インスタンスのディスクがいっぱいになり、SSH
でもSession Manager
でも接続できなくなってしまったため、今後同じようなことが起きたときにすぐに対応できるよう、手順をまとめておこうと思います。
2023/02/11 EBSボリュームの拡張方法も投稿しました。
ディスクフルになった場合に起こる問題
EC2インスタンスに限らず、一般的なLinux
マシンでも同様ですが、ディスクフルになったマシンにログインしようとした場合、一時ファイルやログを出力できるディスク容量が無いことで以下のように接続に失敗してしまいます。
※以下はディスクフルのEC2インスタンスにSession Manager
で接続しようとして失敗したときの例
ディスクフルになって接続できなくなった場合の対処方法
対処方法は色々とありますが、思いつく限りだと以下のような方法が考えられます。
それぞれの手順について以下で紹介していきます。
再起動
EC2インスタンスを再起動することで一時ファイルが削除されるため、一時的にSSH
、Session Manager
で接続できる可能性があります。
ディスクフルでEC2インスタンスに接続できなくなった場合はひとまず再起動して接続できるようになるか確認してみましょう。
※ちなみに私は再起動したらSession Manager
で接続できるようになったため、後述の作業は行わずに済みました。
他のEC2インスタンスでEBSをマウント
再起動しても接続できない場合は復旧作業用EC2インスタンスを準備して、復旧用EC2インスタンスで元のEC2インスタンスにアタッチされていたEBSボリュームをマウントすることで不要ファイルの削除等を行うことができます。
手順としては以下のような流れで進めていきます。
- ディスクフルEBSボリュームのデタッチ
- ディスクフルEBSボリュームのアタッチ
- ディスクフルEBSボリュームのデバイス名確認
- ディスクフルEBSボリュームのマウント
- 不要ファイルの削除
- ディスクフルEBSボリュームのアンマウント
- 元のEC2インスタンスへのアタッチ
- 元のEC2インスタンスの起動
この方法はディスクフルで接続できなくなった場合だけではなく、例えばfstab
の修正を誤って接続できなくなった場合などにも応用できるので、覚えておくと良いと思います。
ディスクフルEBSボリュームのデタッチ
ディスクフルとなっているEC2インスタンスを停止してEBSボリュームをデタッチします。
ログインできない状態だとコマンド操作での停止はできないので、EC2のダッシュボードより「インスタンスの状態」→「インスタンスの停止」を行って停止させます。
停止後、「Elastic Block Store」→「ボリューム」で該当のEBSボリュームを選択→「アクション」から「ボリュームのデタッチ」でEC2インスタンスから取り外します。
また、再度EBSボリュームをアタッチする際に必要となるため、以下EBSボリュームの詳細タブの「アタッチされたインスタンス」からデバイス名を確認しておきます。
ディスクフルEBSボリュームのアタッチ
先程デタッチしたEBSボリュームを復旧用EC2インスタンスにアタッチします。
アタッチして操作ができれば良いので、他のEC2インスタンスが存在するのであれば、復旧用EC2インスタンスは新たに準備しなくても問題ありません。
また、アタッチする際には復旧用EC2インスタンスは起動したままでもEBSボリュームをアタッチできるため、停止する必要もありません。
デタッチした方法と同様、「Elastic Block Store」→「ボリューム」で該当のEBSボリュームを選択→「アクション」から「ボリュームのアタッチ」で復旧用EC2インスタンスに取り付けます。
アタッチする際の画面で以下のように表示されますが、今回は復旧用EC2インスタンスにデータボリュームとしてアタッチするため、デバイス名はデフォルトのまま/dev/sdf
でアタッチします。
ディスクフルEBSボリュームのデバイス名確認
Linux
の仕様としてボリュームをアタッチしただけではディスクフルとなっているEBSボリュームの操作ができないため、復旧用EC2インスタンスにログインし、領域をマウントして不要ファイルの削除等を行えるようにします。
事前作業として、先程アタッチしたEBSボリュームのデバイス名を確認するため、blkid
コマンドでデバイス名を確認します。
$ sudo blkid
/dev/xvda1: LABEL="/" UUID="5d259081-e60a-4c60-8f74-78ad0ee25652" TYPE="xfs" PARTLABEL="Linux" PARTUUID="f257d0ed-ac68-4b9b-8ee1-1f8cbe74e9e6"
/dev/xvdf1: LABEL="/" UUID="5d259081-e60a-4c60-8f74-78ad0ee25652" TYPE="xfs" PARTLABEL="Linux" PARTUUID="f257d0ed-ac68-4b9b-8ee1-1f8cbe74e9e6"
操作を行っているEC2インスタンスに元々アタッチされているルートボリュームはdf
コマンドなどを実行して確認します。
$ df
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
devtmpfs 485168 0 485168 0% /dev
tmpfs 493960 0 493960 0% /dev/shm
tmpfs 493960 516 493444 1% /run
tmpfs 493960 0 493960 0% /sys/fs/cgroup
/dev/xvda1 8376300 1652180 6724120 20% /
tmpfs 98796 0 98796 0% /run/user/1000
tmpfs 98796 0 98796 0% /run/user/0
今回の場合は/dev/xvda1
が復旧用EC2インスタンスのルートボリューム、/dev/xvdf1
がディスクフルとなっているボリュームとなります。
ディスクフルEBSボリュームのマウント
先程確認したデバイス名を指定して、復旧用EC2インスタンスにディスクフルEBSボリュームをマウントしていきます。
注意点として、復旧用EC2インスタンスもディスクフルとなったEC2インスタンスと同一のイメージ(AMI
)を使用している場合、復旧用EC2インスタンスのルートボリュームのUUID
と同じIDとなり、以下のようにマウントに失敗してしまいます。
※今回テストで準備したEC2インスタンスも同じAMIから作成したため、blkid
で確認したUUID
が同一であることが確認できます。
$ sudo mount -t xfs /dev/xvdf1 /mnt
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/xvdf1, missing codepage or helper program, or other error.
その場合、mount
コマンドにオプションを付与することでUUID
を無視することができるので、今回は以下のコマンドで/mnt
にマウントを行います。
$ sudo mount -t xfs -o nouuid /dev/xvdf1 /mnt
不要ファイルの削除
/mnt
にディスクフルとなっているEBSボリュームをマウントしたことでディスクフルとなっているEBSボリュームの中身が確認できるようになります。
不要ファイル削除を行う際、パス指定を間違えると復旧用EC2インスタンス自体のファイルが削除されることになるため、気をつけましょう。
$ sudo rm /mnt/root/diskfulltest
ディスクフルEBSボリュームのアンマウント
不要ファイルを削除したらデバイス指定でアンマウントして元のEC2インスタンスにアタッチする準備を行います。
$ sudo umount -d /dev/xvdf1
元のEC2インスタンスへのアタッチ
「Elastic Block Store」→「ボリューム」で該当のEBSボリュームを選択→「アクション」から「ボリュームのデタッチ」で復旧用EC2インスタンスから取り外します。
復旧用EC2インスタンスは今回の手順に従えば特に停止しなくてもデタッチできるはずですが、デタッチできず、device busy
となるようであれば、停止するか強制デタッチを行ってください。
復旧用EC2インスタンスからデタッチ後、「Elastic Block Store」→「ボリューム」で該当のEBSボリュームを選択→「アクション」から「ボリュームのアタッチ」で元のEC2インスタンスにアタッチしますが、復旧用EC2インスタンスにアタッチした場合と異なり、今回はルートボリュームとしてアタッチする必要があるため、以下のようにデバイス名を元のデバイス名に書き換え(今回の場合は/dev/xvda
)「ボリュームのアタッチ」を選択します。
元のEC2インスタンスの起動
EBSボリュームアタッチ後は通常と同じくEC2インスタンスを起動してログインできるか確認してみます。
問題なく接続できれば完了です。
バックアップからの復元
AMI
またはEBSボリュームのスナップショットを定期的にバックアップしている場合は、バックアップから復元して新たにEC2インスタンスを作成することで、問題が発生する以前の状態に戻すこともできます。
ただし、復元を行う場合は当然ながらバックアップを取得したときの状態に戻るため、バックアップ取得後に行った操作やファイルは無くなってしまうことに注意しましょう。
※今回はAMI
、スナップショットからの復元手順は省略します。
ルートボリュームの置き換えによる復旧
ディスクフルとなっているEC2インスタンスをどうしても停止させたくないような場合は、以下のような手順でルートボリュームの置き換えを行うことで無停止で復旧させることも可能です。
ただし、置き換えの名の通り、ルートボリュームをそのまま別のボリュームに置き換えることになるため、仕組みとしてはAMI
やスナップショットからのリストアと同等の対処となります。
また、無停止で復旧することは可能ですが、ボリュームを置き換えるタイミングで1分程度応答が無くなるため、サービス提供を行っているEC2インスタンスに対して実施する場合は注意が必要です。
ルートボリューム交換時の無応答検証は以前の記事でまとめているため、興味がある方は以下も参照してください。
ルートボリュームの置き換え
ルートボリュームを置き換えするには、EC2ダッシュボードの「インスタンス」で該当のインスタンスを選択→「アクション」から「モニタリングとトラブルシューティング」→「ルートボリュームを置き換える」を選択します。
ルートボリュームを置き換える際、以下3つの復元方法を選択できます。
AMI
やスナップショットを指定することもできるため、バックアップを取得している場合は、AMI
やスナップショットを指定しても良いです。
復元 | 内容 |
---|---|
起動状態 | 現在起動中のルートボリュームの初期状態に戻す |
スナップショット | 指定したスナップショットに置き換える |
イメージ | 指定したAMIイメージに置き換える |
「置き換えられたルートボリュームを削除」にチェックをすることで、置き換え時にボリュームを削除できますが、削除すると古いルートボリュームに入っているファイルが救出できないため、確実に削除しても問題ないとわかっている場合以外はチェックを行わず、問題ないと判断できた時点で削除するのが良いでしょう。
ルートボリューム置き換え後の接続
置き換え後、1分ほど経過すると再接続できるようになるため、 SSH
やSession Manager
で接続を行います。
SSH
で接続を行う場合はフィンガープリントが変わるため、以下のようなワーニングで接続できません。
そのため操作端末のknown_hosts
から該当の定義を削除して再度接続するようにします。
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please contact your system administrator.
Add correct host key in /Users/user01/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /Users/user01/.ssh/known_hosts:51
Host key for X.X.X.X has changed and you have requested strict checking.
Host key verification failed.
削除方法はどのような方法でも問題ありませんが、以下sed
で削除する場合の例。
sed -i -e '/192.0.2.1/d' ~/.ssh/known_hosts
おわりに
ディスクフルになって接続できなくなった場合の対処方法をいくつか紹介しましたが、改めて整理するとオンプレミスのサーバで問題が発生した場合よりも対応方法があると感じました。
とはいえ、今回の手順は最終手段なので、実際にはディスク容量監視を行い、ディスクフルになる前に対処できるようにしましょう。