ネットワークにつながらなくなった Amazon EC2 インスタンスを回復させる話

こんにちは。自称ネットワークエンジニアの貝塚です。SCSKでAWSの内製化支援『テクニカルエスコートサービス』を担当しています。

先日、EC2 Amazon Linuxを使って検証をしておりまして、付け焼刃でネットワーク周りの設定ファイルを変更してOSを再起動したところ、インスタンスに接続できなくなりました。その時回復するためにやったことを本稿にメモとして残したいと思います。

まずは状況整理

使用していたOSはAmazon Linux 2023。AWSの公式AMIから作成したものです。

OSにはセッションマネージャーを使用してログインしていました。OSのIPアドレス周りの設定を変更しOSの再起動をしたところ、セッションマネージャーで接続ができなくなりました。細かい切り分けはしていませんが、状況的にインスタンス側のネットワークの問題と断定してよいでしょうから、sshなどIPアドレスを使ってログインする手段はいずれもダメだと考えられます。

EC2シリアルコンソール

何か手段なかったか……?と考えていたところ、そういえばシリアルコンソールの機能があったな、と思い当たります。でも普段使っているEC2ではシリアルコンソールの接続ボタンは押せなかったような記憶が……などと考えつつ、藁にもすがる思いで画面を開きます。

ec2_serial_console

Nitroかあ……。実はNitro Systemというのにあまり興味がなく、どのインスタンスタイプがNitroなのか全く知りません。まずは調べるところから。

T3がNitroのようです。……よかった。どんな高額インスタンスが必要なのかドキドキしてしまいました。t2.microが好きすぎてT3すらほとんど使ったことありませんでした。早速インスタンスタイプを変更して起動。今度は接続ボタンが押せるようになっていて、一安心。コンソールを流れていく文字列を眺めていると、cloud-initが169.254.169.254に接続できません、みたいなログが出ています。やっぱりネットワーク設定が悪かったんだな、さてどこをどう直せばいいのだろうな……

console_login

あー……パスワード設定してあるユーザ、いないですね。

ルートボリュームのデタッチ&アタッチ

レスキューモード(エマージェンシーモード?)で起動すればいける気がするけれど、GRUB起動メニューにアクセスしなければいけないはずで、シリアルコンソールの画面を起動したときにはとっくにOS起動処理が始まっていたから、EC2ではGRUB起動メニューにアクセスできないのかなあ。あ、そういえばEC2ではルートボリュームをデタッチして別のインスタンスにアタッチできると聞いたことがあるような。

少々検索し、こちらの記事にたどり着きます。

まさに探していた情報そのものです。レスキュー用のLinuxインスタンスを準備し、早速試します。

  • インスタンス一覧から起動しなくなったインスタンスをチェックし、「ストレージ」タブからルートボリュームを特定。
  • ルートボリュームを選択し、アクション→ボリュームのデタッチを実行。
  • レスキュー用インスタンスにアタッチするために再度そのボリュームを選択し、アクション→ボリュームのアタッチを選択。

一覧からレスキュー用インスタンスを選択。デバイス名はデフォルトで表示されていた/dev/sdfとしました。(スクリーンショットに表示されているインフォメーションの通り、レスキュー用インスタンスのOS側では/dev/xvdf に変更されていました)

attache_to_rescue_instance

  • レスキュー用インスタンスにデバイスが認識されていることを確認し、mount。
[ec2-user@ip-10-32-1-157 ~]$ sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
xvda 202:0 0 8G 0 disk
├─xvda1 202:1 0 8G 0 part /
├─xvda127 259:0 0 1M 0 part
└─xvda128 259:1 0 10M 0 part /boot/efi
xvdf 202:80 0 8G 0 disk
├─xvdf1 202:81 0 8G 0 part
├─xvdf127 259:2 0 1M 0 part
└─xvdf128 259:3 0 10M 0 part
[ec2-user@ip-10-32-1-157 ~]$
[ec2-user@ip-10-32-1-157 ~]$ 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.

あれれ。だめですね。wrong fs type とか言われていますが、ファイルシステムはxfsで間違いないはず……。

またしばし検索……。

うん、これですね。

なるほど、そういえば、起動しなくなったインスタンスも、レスキュー用インスタンスも、同じAMIから作ったAmazon Linux 2023のインスタンスでした。/ のUUIDが同じだからエラーになったのですね。確認してみたところ、確かに同じUUIDでした。

[ec2-user@ip-10-32-1-157 ~]$ sudo lsblk --fs
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
xvda
├─xvda1 xfs / 439aed1d-715f-48fd-bfa0-0e5f1a23088b 6.4G 20% /
├─xvda127
└─xvda128 vfat FAT16 C86C-DC3E 8.7M 13% /boot/efi
xvdf
├─xvdf1 xfs / 439aed1d-715f-48fd-bfa0-0e5f1a23088b
├─xvdf127
└─xvdf128 vfat FAT16 C86C-DC3E

上記記事の手順に従ってUUIDの変更を実施し、再びmount。

[ec2-user@ip-10-32-1-157 ~]$ sudo uuidgen
12e50054-6690-41a6-b532-e75946ba9c6b
[ec2-user@ip-10-32-1-157 ~]$ sudo xfs_admin -U 12e50054-6690-41a6-b532-e75946ba9c6b /dev/xvdf1
Clearing log and setting UUID
writing all SBs
new UUID = 12e50054-6690-41a6-b532-e75946ba9c6b
[ec2-user@ip-10-32-1-157 ~]$
[ec2-user@ip-10-32-1-157 ~]$ sudo mount -t xfs /dev/xvdf1 /mnt/rescue/
[ec2-user@ip-10-32-1-157 ~]$
[ec2-user@ip-10-32-1-157 ~]$ ls /mnt/rescue/
bin boot dev etc home lib lib64 local media mnt opt proc root run sbin srv sys tmp usr var

OKですね!

起動しなくなった原因のファイルを取り除き、umountした上で、今度はレスキュー用インスタンスからボリュームをデタッチします。そして再び起動しなくなったインスタンスにボリュームをアタッチ。ルートボリュームなのでデバイス名は /dev/xvda を指定します。

インスタンス起動!シリアルコンソールで起動を見届け……

grub>

あれえ……。

そういえばすっかり読み流していましたが、先ほどの記事の末尾に

Finallly, we can start digging into the content of the device mount on /mnt and do whatever was required. Perhaps, one note if this device will be moved back to the original EC2 instance do not forget to updat the /mnt/etc/fstab file with the updated UUID of this modified boot device.

Change the UUID on a xfs file system より引用

UUIDが変わったから /etc/fstab の変更を忘れるなよって書いてありました。ドキュメントはよく読もう!

再度、ルートボリュームをレスキュー用インスタンスにアタッチし、fstabを修正します。

今度こそ!

grub>

あっれえ…。

その後、AWS re:Postの関連しそうな記事を参照し、fstabのオプションを変更してファイルシステムのチェックを無効にしたり、XFSのリペアをしたりいろいろ試しますが、相変わらずgrubのプロンプトになってしまいます。ひとつ試すたびにボリュームの付け替えをしているので、ひたすら面倒です。

最終的には、fstab以外におそらくgrubの設定ファイルにもUUIDが含まれていそうな気がする!だけどもう調べるの面倒くさい!となって、一度変更したファイルシステムのUUIDを元のUUIDに戻してあげることでOSの起動に成功したのでした。

教訓

  • パスワードを設定したOSユーザ作っておくの大事。(でも軽い検証のときはそのひと手間も面倒ですよね)
  • UUID被りを避けるため、レスキュー用インスタンスはレスキューされるインスタンスとは異なるOSバージョンにしておくと面倒がない。(でも違うディストリビューションとかにしちゃうと操作感が違って面倒くさいしねえ)
  • ドキュメントはよく読もう(でもちゃんと読んでもうまくいかないことはある)

後日談

その1

後日確認したら、grubの設定ファイルにUUIDが書かれていました。検証してないけれど、ここも追加で書き換えれば起動できていたはず。

$ sudo cat /boot/loader/entries/e8e94dc055b04f2484035693fbb04115-6.1.56-82.125.amzn2023.x86_64.conf
title Amazon Linux (6.1.56-82.125.amzn2023.x86_64) 2023
version 6.1.56-82.125.amzn2023.x86_64
linux /boot/vmlinuz-6.1.56-82.125.amzn2023.x86_64
initrd /boot/initramfs-6.1.56-82.125.amzn2023.x86_64.img
options root=UUID=439aed1d-715f-48fd-bfa0-0e5f1a23088b ro console=tty0 console=ttyS0,115200n8 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0 selinux=1 security=selinux quiet
grub_users $grub_users
grub_arg --unrestricted
grub_class amzn

その2

この記事を書くために資料整理していたら、先述のルートボリュームのデタッチ・アタッチを解説した記事から以下の記事へリンクが張られているのを発見しました。

1. 一時的にマウントするために、UUIDの重複を無視する

アタッチしたボリュームは一時的にマウントするためのものであり、本来のEC2にアタッチし直す場合は、このアプローチを採用します。

マウント時にUUIDの重複を無視するオプション(-o nouuid)を渡します。

Amazon EBSマウント時の「wrong fs type, bad option, bad superblock on…」というエラーを解決する方法を教えてください より引用。

UUIDの重複を無視するオプションがあったようですね。もう少しだけ丁寧に調べていればこんな苦労しなくて済んだのに……(よくある)

まとめ

疲れました。

著者について

SCSKにて、AWSの技術支援を提供するAWSテクニカルエスコートサービスの業務に従事しています。
自称ネットワークエンジニア。
CloudFormationは触っていても面白みが感じられないけれどCDKは好き。

所持資格は、
AWS Certified Solutions Architect - Professional
AWS Certified Advanced Networking - Specialty
AWS Certified Security - Specialty
AWS Certified DevOps Engineer - Professional
IPA 情報処理安全確保支援士
など。

好きなすみっコはとかげ。

貝塚広行をフォローする
クラウドに強いによるエンジニアブログです。
SCSKは専門性と豊富な実績を活かしたクラウドサービス USiZE(ユーサイズ)を提供しています。
USiZEサービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。
AWSクラウドソリューション運用・監視
シェアする
タイトルとURLをコピーしました