カーネルをアップグレードするか Amazon Elastic Cloud Compute (Amazon EC2) Linux インスタンスを再起動した後に、initramfs またはカーネルモジュールがないために発生する「kernel panic」エラーを解決したいと考えています。
簡単な説明
デバイスまたはアドレスが存在しないため、「Kernel panic - not syncing」というエラーが表示されます。この問題を解決するには、一時インスタンスを起動し、障害が発生したルートディスクをセカンダリドライブとしてアタッチして診断を実行します。
重要: インスタンスを停止して再起動すると、インスタンスストアボリュームのデータが消去されます。このため、保持したいデータをバックアップしておきます。また、インスタンスの再起動により、インスタンスのパブリック IP アドレスの変更も行われます。外部トラフィックをインスタンスにルーティングする場合は、パブリック IP アドレスではなく、Elastic IP アドレスを使用するのがベストプラクティスです。
解決策
注: 以下の解決策は、Amazon Linux 2、Amazon Linux 2023、Fedora 16 以降、および Red Hat Enterprise Linux (RHEL) 7 以降に適用されます。
ルートディスクを一時インスタンスにアタッチするため、次の手順を実行します。
-
新しいキーペアを作成するか、既存のキーペアを使用します。
-
元のインスタンスとそのルートボリュームに関する情報を取得します。
-
元のインスタンスを停止します。
-
同じアベイラビリティーゾーン内の同じ Linux オペレーティングシステム (OS) バージョンの AMI (Amazon マシンイメージ) を使用して、一時インスタンスを起動します。
-
元のインスタンスからルートボリュームをデタッチし、セカンダリボリュームとして一時インスタンスにアタッチします。ボリュームのデバイス名を書き留めておきます。
-
SSH キーペアを使用して一時インスタンスに接続します。
-
ルートユーザーに変更するため、次のコマンドを実行します。
[ec2-user ~]$ sudo su
-
ブロックデバイス名とパーティションを識別するため、一時インスタンスで次のコマンドを実行します。
[root ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
xvdf 202:80 0 101G 0 disk
└─xvdf1 202:81 0 101G 0 part
上記の例では、blkfront ドライバーをインストールした XEN インスタンスを使用しています。/dev/xvda と /dev/xvdf はどちらもパーティション化されたボリュームですが、/dev/xvdg はそうではありません。 ボリュームがパーティション化されている場合は、raw デバイス (/dev/xvdf) の代わりにパーティション (/dev/xvdf1) をマウントする次のコマンドを実行します。
[root ~]$ mount -o nouuid /dev/xvdf1 /mnt
AWS Nitro System に構築されたインスタンスを使用する場合、ボリュームデバイス名は /dev/nvme[0-26]n1 という形式になります。インスタンスが NVMe を搭載した Nitro に構築されている場合は、/mnt ディレクトリにパーティションをマウントします。デバイス名としては、本手順 8 内で識別したものを使用します。
[root ~]$ mount -o nouuid /dev/nvme1n1p1 /mnt
詳細については、「Amazon EC2 インスタンス上のボリュームのデバイス名」を参照してください。
-
/mnt ディレクトリに chroot 環境を作成するため、次のコマンドを実行します。
[root ~]$ for i in dev proc sys run; do mount -o bind /$i /mnt/$i; done; chroot /mnt
上記の例では、/dev、/proc、/sys、/run ディレクトリが元のルートファイルシステムからバインドマウントされています。これにより、chroot 環境内で実行されるプロセスがシステムディレクトリにアクセスできるようになります。
-
「/」ディレクトリに initramfs のバックアップを作成するため、次のコマンドを実行します。
[root ~]$ for file in /boot/initramfs-*.img; do cp "${file}" "/$(basename "$file")_$(date +%Y%m%d)"; done
- デフォルトカーネルを一覧表示するため、次のコマンドを実行します。
[root ~]$ grubby --default-kernel
出力例:
/boot/vmlinuz-5.15.156-102.160.amzn2.x86_64
上記の出力には、起動時にブートしようとするカーネルがリストされています。
ブートディレクトリにあるカーネルと initramfs をリストします。
[root ~]$ ls -lh /boot/vmlinuz* && ls -lh /boot/initr*
出力例:
-rwxr-xr-x. 1 root root 9.7M Apr 23 20:37 /boot/vmlinuz-5.10.215-203.850.amzn2.x86_64
-rwxr-xr-x. 1 root root 9.9M Apr 23 17:00 /boot/vmlinuz-5.15.156-102.160.amzn2.x86_64
-rw-------. 1 root root 12M May 3 23:45 /boot/initramfs-5.10.215-203.850.amzn2.x86_64.img
-rw-------. 1 root root 9.8M May 14 08:03 /boot/initramfs-5.15.156-102.160.amzn2.x86_64.img
vmlinuz カーネルファイルのそれぞれに対応する initramfs ファイルが配置されている場所を確認してください。
initramfs を再構築するため、次のコマンドを実行します。
[root ~]$ dracut --force --verbose initramfs-kernelVersion.img kernelVersion
注: kernelVersion を最新のカーネルバージョンに置き換えてください。
インスタンスが UEFI と BIOS のどちらで起動しているかを確認するため、次のコマンドを実行します。
[root ~]$ boot_mode=$(ls /sys/firmware/efi/efivars >/dev/null 2>&1 && echo "EFI" || echo "BIOS"); echo "Boot mode detected: $boot_mode"
- grub の設定を更新するため、BIOS または UEFI で次のコマンドのいずれかを実行します。
BIOS の場合:
[root ~]$ grub2-mkconfig -o /boot/grub2/grub.cfg
注: 上記のコマンドを実行すると、「device-mapper: reload ioctl on osprober-linux-xvda2 (253:0) failed: Device or resource busy Command failed」というエラーが表示される場合があります。この問題を解決するには、/etc/default/grub ファイルに GRUB_DISABLE_OS_PROBER=true パラメータを追加し、コマンドを再実行します。
UEFI の場合:
Amazon Linux 2 および Amazon Linux 2023:
[root ~]$ grub2-mkconfig -o /boot/efi/EFI/amzn/grub.cfg
Fedora 16+:
[root ~]$ grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
Red Hat 7+:
[root ~]$ grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
- ボリュームを終了してデタッチするため、次のコマンドを実行します。
[root ~]$ exit; umount -fl /mnt
- 一時インスタンスからセカンダリボリュームをデタッチし、ルートデバイスとして元のインスタンスにアタッチします。デバイス名としては、手順 5 と同じものを使用してください。
- 元のインスタンスに接続します。