AWS EC2のUbuntu 22.04で古いLinuxカーネルで起動したくなった時に読む記事

記事タイトルとURLをコピーする

はじめに

まいど! CS部の くつなりょうすけ です。 この後、諸事情でLinuxカーネルを一つ前の状態に戻す作業が出ました。 そこでちょっとしたツマヅキがあったのでメモ代わりに記事に残します。

概要

Ubuntu 22.04で最新から一つ古いカーネルで起動して、最新のカーネルを削除しようと思います。 インストールされている最新カーネルを削除しようとしましたが、削除できませんでした。

この記事で得られることは以下、2点です。

  • AWS EC2のUbuntuで最新ではないLinuxカーネルで起動する方法
  • AWS EC2のUbuntuでカーネルパッケージを削除する方法

環境概要

EC2でUbuntu 22.04を起動。 apt-updateで最新状態までアップデート済。

作業

Linuxカーネルが3つインストールされている状態で、現在 6.2.0-1015-aws が起動している。 これを 6.2.0-1014-aws に戻します。

$ dpkg -l | grep linux-image
ii  linux-image-6.2.0-1012-aws       6.2.0-1012.12~22.04.1                   amd64        Signed kernel image aws
ii  linux-image-6.2.0-1014-aws       6.2.0-1014.14~22.04.1                   amd64        Signed kernel image aws
ii  linux-image-6.2.0-1015-aws       6.2.0-1015.15~22.04.1                   amd64        Signed kernel image aws

Grubではメニューから起動するカーネルを選択できます。 「menuentry」で並んでいれば、上から「0」始まりでエントリ順番を指定すればそのカーネルで起動します。 「submenu」が組まれていると「1>」というプレフィックスをつけて、サブメニュー内の上から「0」始まりでエントリ順番を指定してカーネルを起動します。 (参照: https://help.ubuntu.com/community/Grub2/Submenus)

ここでは/etc/default/grubの GRUB_DEFAULT="1>2" として update-grub を実行するとrecovery modeではない「Ubuntu, with Linux 6.2.0-1014-aws」が起動します。

$ sudo grep -E "menuentry |submenu " /boot/grub/grub.cfg  --color
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-4f575094-453e-450d-aeed-215d8cbcbf58' {
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-4f575094-453e-450d-aeed-215d8cbcbf58' {
        menuentry 'Ubuntu, with Linux 6.2.0-1015-aws' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-1015-aws-advanced-4f575094-453e-450d-aeed-215d8cbcbf58' {
        menuentry 'Ubuntu, with Linux 6.2.0-1015-aws (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-1015-aws-recovery-4f575094-453e-450d-aeed-215d8cbcbf58' {
        menuentry 'Ubuntu, with Linux 6.2.0-1014-aws' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-1014-aws-advanced-4f575094-453e-450d-aeed-215d8cbcbf58' {
        menuentry 'Ubuntu, with Linux 6.2.0-1014-aws (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-1014-aws-recovery-4f575094-453e-450d-aeed-215d8cbcbf58' {
        menuentry 'Ubuntu, with Linux 6.2.0-1012-aws' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-1012-aws-advanced-4f575094-453e-450d-aeed-215d8cbcbf58' {
        menuentry 'Ubuntu, with Linux 6.2.0-1012-aws (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-1012-aws-recovery-4f575094-453e-450d-aeed-215d8cbcbf58' {

Linuxカーネル 6.2.0-1014-aws で無事に起動するのを確認します。 /etc/default/grub のGRUB_DEFAULTを「1>2」のままにしておくと、今後Linuxカーネルのアップデートをインストールしても常に一つ古いLinuxが起動してしまいます。

GRUB_DEFAULTを「0」の標準状態に戻したいですよね。 ならば、EC2でのLinuxカーネルを 6.2.0-1014-aws を最新としておけばよいのです。 Linux カーネル 6.2.0-1015-aws のLinuxカーネルを削除しましょう。

EC2が、Linuxカーネル6.2.0-1014-awsで起動している状態で6.2.0-1015-awsのパッケージを削除します。

$ uname -a   # 起動カーネルの確認
Linux ip-10-110-100-180 6.2.0-1014-aws #14~22.04.1-Ubuntu SMP Thu Oct  5 22:43:45 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
$
$
$ sudo apt remove linux-image-6.2.0-1015-aws   # apt removeでLinuxカーネルを一つ削除する
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  linux-image-unsigned-6.2.0-1015-aws
Suggested packages:
  fdutils linux-aws-6.2-doc-6.2.0 | linux-aws-6.2-source-6.2.0 linux-aws-6.2-tools
The following packages will be REMOVED:
  linux-image-6.2.0-1015-aws
The following NEW packages will be installed:
  linux-image-unsigned-6.2.0-1015-aws
0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
Need to get 13.9 MB of archives.
After this operation, 152 kB of additional disk space will be used.
Do you want to continue? [Y/n]
Get:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu jammy-updates/main amd64 linux-image-unsigned-6.2.0-1015-aws amd64 6.2.0-1015.15~22.04.1 [13.9 MB]
Fetched 13.9 MB in 0s (36.8 MB/s)
dpkg: linux-image-6.2.0-1015-aws: dependency problems, but removing anyway as you requested:
 linux-modules-6.2.0-1015-aws depends on linux-image-6.2.0-1015-aws | linux-image-unsigned-6.2.0-1015-aws; however:
  Package linux-image-6.2.0-1015-aws is to be removed.
  Package linux-image-unsigned-6.2.0-1015-aws is not installed.
(略)
Generating grub configuration file ...
GRUB_FORCE_PARTUUID is set, will attempt initrdless boot
Found linux image: /boot/vmlinuz-6.2.0-1015-aws
Found initrd image: /boot/microcode.cpio /boot/initrd.img-6.2.0-1015-aws
Found linux image: /boot/vmlinuz-6.2.0-1014-aws
Found initrd image: /boot/microcode.cpio /boot/initrd.img-6.2.0-1014-aws
Found linux image: /boot/vmlinuz-6.2.0-1012-aws
Found initrd image: /boot/microcode.cpio /boot/initrd.img-6.2.0-1012-aws
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
done
(略)

メッセージをよく読めば書いてありますが、実は 6.2.0-1015-aws が削除できていません。 カーネルパッケージを uninstall しようとしてるのになぜ消えないのでしょう。

検証

AWSではなく、手元のPCのVirtualBoxにインストールしたUbuntu 22.04では同様の手段(apt remove linux-image-VERSION)で一つ前のLinuxカーネルバージョンでの起動、インストールされている最新Linuxカーネルの削除ができることを検証していました。 AWS EC2のUbuntu 22.03では同じ手順で削除ができません。

この現象の理由は、AWS EC2のUbuntu用カーネルは依存関係の影響でカーネルパッケージを削除しようとしても別のパッケージがインストールされてしまうのが原因です。 以下のように、削除メッセージの中で代替えパッケージがインストールされることが明記されています。

$ uname -a
Linux ip-10-110-100-180 6.2.0-1014-aws #14~22.04.1-Ubuntu SMP Thu Oct  5 22:43:45 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
$ sudo apt remove linux-image-6.2.0-1015-aws
(略)
The following packages will be REMOVED:
  linux-image-6.2.0-1015-aws
The following NEW packages will be installed:
  linux-image-unsigned-6.2.0-1015-aws
0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded.
(略)

linux-imageと一緒にインストールされているlinux-modulesパッケージの依存性の関係でカーネルイメージパッケージが残ってしまうことがわかります。 linux-modulesの依存パッケージ一覧を確認するには以下のようにコマンドを実行すると「Depends」に依存関係が表示されます。

$ apt show linux-modules-6.2.0-1015-aws
(略)
Depends: linux-image-6.2.0-1015-aws | linux-image-unsigned-6.2.0-1015-aws
(略)

linux-module-6.2.0-1015-awsが linux-imageとlinux-image-unsignedのどちらかが必要とのことで、linux-imageを消してもパッケージマネージャがlinux-image-unsignedを親切心で(ただの依存関係です)インストールしてくれます。

これに対応するには、依存するパッケージをすべて削除します。 今回の場合は、以下のように削除すればOKです。

$ sudo apt remove linux-image-6.2.0-1015-aws linux-modules-6.2.0-1015-aws

ちなみに、AWSではなく物理PCにUbuntuをインストールして利用されるカーネル linux-modules-6.2.0-36-generic は linux-imageやlinux-image-unsignedの依存をしていないので linux-imageのみを削除すれば/bootの該当イメージを削除することができます。

$ apt-cache show linux-modules-6.2.0-36-generic | grep ^Depends:
$

まとめ

AWS EC2のUbuntuでLinuxカーネルの削除を行う場合に期待した動作にならない場合は依存性を確認しましょう。

dpkgやapt、rpmとyum・dnfなどはパッケージマネージャとしてとても便利です。 ですが、時にユーザの予想しない動作をすることががあります。 しかし、冷静にみればそれは定義されていることです。メッセージやパッケージ情報を確認して対応しましょう。

同じパッケージ名でもクラウド用とオンプレミス用パッケージで異なることがある、という話でした。

沓名 亮典(執筆記事の一覧)

クラウドインテグレーション部 SRE1課

Linuxでのサーバ構築・保守業務をしてましたがクラウド業務をしたくて2021年12月に入社したネットワークエンジニア。 趣味でマラソン、トレラン、トライアスロン、ロードバイクやってる変態。