本篇文章,分享如何使用开源工具,轻松实现包括容器在内的 Ubuntu 环境中的内核版本升级,更好地适配新硬件和解锁内核的新特性。

写在前面

作为开发者,我们经常需要在不同的环境中工作,特别是在使用 Docker 容器时。Linux 内核作为操作系统的核心,其版本不仅关系到系统性能的优化、功能特性的支持程度,还包含了重要的错误修复和安全补丁。

有的时候,我们也会遇到这样的场景:需要在容器中使用一些特定的硬件特性,或者要支持最新的硬件设备,这时就需要升级到比发行版更新的内核版本。

回顾过去的分享,我在《AMD 4750u 及 5800u 笔记本安装 Ubuntu 20.04》中曾详细介绍过如何通过升级内核来支持新款 AMD APU。在类处理嵌入式设备时,比如《快速构建稳定的 Armbian 系统:玩客云折腾速通指南(二)》中,我也分享了如何利用容器快速编译 Armbian 设备的内核和系统。

不过,这些方法都相对复杂。今天要介绍的是一个更简便的方案:使用 mainline 这款开源的 Ubuntu 内核安装工具。它能让我们在 Ubuntu 系统(包括容器环境)中轻松实现内核的安装和切换。

想要快速切换内核版本,我们首先要了解当前的内核版本是什么,以及系统默认支持到什么版本。

让我们先来看看 Ubuntu 24.04 和 24.10 的默认内核版本情况。

查看当前系统内核版本

默认情况下,我们能够在登录系统后的欢迎文本中,查看到系统的内核版本:

Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-52-generic x86_64)

Welcome to Ubuntu 24.10 (GNU/Linux 6.11.0-14-generic x86_64)

Ubuntu 24.04 的默认版本是 6.8.x,Ubuntu 24.10 的默认版本是 6.11.x。我们也可以使用命令 uname -r 来查看版本:

# uname -r
6.8.0-52-generic
# 或
6.11.0-14-generic

目前,如果我们想通过 apt install 来安装 6.12 内核,会因为内核尚未发布到官方仓库,而无法直接安装。

通过以下命令可以看到,不论是 Ubuntu 24.04 还是 Ubuntu 24.10,当前仓库中最新的版本都只到 Linux 6.11:

# sudo apt-cache search linux-headers | grep 6.1

linux-headers-6.11.0-1003-gcp - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-headers-6.11.0-1004-aws - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-headers-6.11.0-1004-azure - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-headers-6.11.0-1004-lowlatency - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-headers-6.11.0-1006-oracle - Oracle Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-headers-6.11.0-8 - Header files related to Linux kernel version 6.11.0
linux-headers-6.11.0-8-generic - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-source-6.11.0 - Linux kernel source for version 6.11.0 with Ubuntu patches
linux-headers-6.11.0-1001-realtime - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
linux-headers-6.11.0-1004-gcp - Linux kernel headers for version 6.11.0 on 64 bit x86 SMP
...

如何安装软件仓库中不存在的内核版本呢?

快速切换任意版本的 Linux 内核

第一步,我们需要先安装 mainline 的软件包。只需要添加它的软件源,然后用 apt 安装即可:

sudo add-apt-repository ppa:cappelikan/ppa -y
sudo apt update && sudo apt install mainline -y

安装好工具后,我们就可以指定想要安装的内核版本了。比如要安装 6.12.3 版本,可以直接运行:

sudo mainline install 6.12.3

需要说明的是,所有可用的内核版本都可以在 Ubuntu 的官方内核仓库查看:https://kernel.ubuntu.com/mainline/。有一些内核版本目录虽然创建完毕,但因为一些 BUG 和尚未完成的工作,还没有预构建的产物,如果你需要安装,就需要自行编译安装啦。

言归正传,执行命令后,工具会自动开始内核相关文件的下载。

mainline 1.4.11
Updating Kernels...
Downloading 6.12.3
▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░ 23%  3/13 MB - file 3/4

当内核软件包下载完毕后,会自动开始安装过程。

# sudo mainline install 6.12.3
mainline 1.4.11
Updating Kernels...
Downloading 6.12.3
Installing 6.12.3                                                     
Selecting previously unselected package linux-modules-6.12.3-061203-generic.
(Reading database ... 210708 files and directories currently installed.)
Preparing to unpack .../linux-modules-6.12.3-061203-generic_6.12.3-061203.202412060638_amd64.deb ...
Unpacking linux-modules-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
Selecting previously unselected package linux-headers-6.12.3-061203.
Preparing to unpack .../linux-headers-6.12.3-061203_6.12.3-061203.202412060638_all.deb ...
Unpacking linux-headers-6.12.3-061203 (6.12.3-061203.202412060638) ...
Selecting previously unselected package linux-headers-6.12.3-061203-generic.
Preparing to unpack .../linux-headers-6.12.3-061203-generic_6.12.3-061203.202412060638_amd64.deb ...
Unpacking linux-headers-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
Selecting previously unselected package linux-image-unsigned-6.12.3-061203-generic.
Preparing to unpack .../linux-image-unsigned-6.12.3-061203-generic_6.12.3-061203.202412060638_amd64.deb ...
Unpacking linux-image-unsigned-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
Setting up linux-modules-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
Setting up linux-headers-6.12.3-061203 (6.12.3-061203.202412060638) ...
Setting up linux-headers-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
Setting up linux-image-unsigned-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
I: /boot/initrd.img.old is now a symlink to initrd.img-6.11.0-14-generic
I: /boot/vmlinuz is now a symlink to vmlinuz-6.12.3-061203-generic
I: /boot/initrd.img is now a symlink to initrd.img-6.12.3-061203-generic
Processing triggers for linux-image-unsigned-6.12.3-061203-generic (6.12.3-061203.202412060638) ...
/etc/kernel/postinst.d/initramfs-tools:
update-initramfs: Generating /boot/initrd.img-6.12.3-061203-generic
/etc/kernel/postinst.d/kdump-tools:
kdump-tools: Generating /var/lib/kdump/initrd.img-6.12.3-061203-generic
/etc/kernel/postinst.d/zz-update-grub:
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/kdump-tools.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.12.3-061203-generic
Found initrd image: /boot/initrd.img-6.12.3-061203-generic
Found linux image: /boot/vmlinuz-6.11.0-14-generic
Found initrd image: /boot/initrd.img-6.11.0-14-generic
Found memtest86+ 64bit EFI image: /boot/memtest86+x64.efi
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.
Adding boot menu entry for UEFI Firmware Settings ...
done
mainline: done

等待安装完成后,只需要重启系统即可:

sudo reboot

重启后,系统就会自动切换到新安装的内核版本。我们可以用以下两种方式确认调整是否生效。

查看登录欢迎信息,会显示当前的内核版本:

Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.12.3-061203-generic x86_64)

Welcome to Ubuntu 24.10 (GNU/Linux 6.12.3-061203-generic x86_64)

使用 uname -r 命令直接查看内核版本号:

# uname -r
6.12.3-061203-generic

值得一提的是,在 Ubuntu 24.04 中安装新版内核后,系统可能会更好地识别一些硬件设备,比如原本系统中不能够被直接识别的显卡设备。

容器中的内核版本

而 Docker 容器中的内核版本,其实会复用宿主机的内核,当我们完成宿主机的内核版本升级之后,容器内的内核版本也就升级好啦。

你可以通过下面的命令来进行验证:

docker run --rm -it ubuntu:24.04 bash -c "uname -r"
6.12.3-061203-generic

清理陈旧内核版本

因为我们安装的都是 Ubuntu 验证过的预构建内核,所以通常不会出现兼容性问题。当设备重启新的内核生效后,我们可以做一些系统维护工作,清理掉系统中不需要的旧内核版本。

根据 Ubuntu 版本不同,我们有不同的处理方式。

Ubuntu 24.10 版本的处理方法

对于 Ubuntu 24.10,操作相对简单,只需要执行一条自动清理命令:

sudo apt autoremove -y

系统会自动识别并移除不需要的旧版本内核文件,通常能释放几百 MB 的存储空间。

# sudo apt autoremove -y

REMOVING:                       
  linux-headers-6.11.0-8  linux-headers-6.11.0-8-generic  linux-modules-6.11.0-8-generic  linux-modules-extra-6.11.0-8-generic  linux-tools-6.11.0-8  linux-tools-6.11.0-8-generic

Summary:
  Upgrading: 0, Installing: 0, Removing: 6, Not Upgrading: 1
  Freed space: 302 MB

(Reading database ... 249471 files and directories currently installed.)
Removing linux-headers-6.11.0-8-generic (6.11.0-8.8) ...
Removing linux-headers-6.11.0-8 (6.11.0-8.8) ...
Removing linux-modules-extra-6.11.0-8-generic (6.11.0-8.8) ...
Removing linux-modules-6.11.0-8-generic (6.11.0-8.8) ...
Removing linux-tools-6.11.0-8-generic (6.11.0-8.8) ...
Removing linux-tools-6.11.0-8 (6.11.0-8.8) ...

Ubuntu 24.04 版本的处理方法

对于 Ubuntu 24.04,我们需要采取更精细的方式来管理内核版本。首先,我们需要列出系统中所有的旧版本内核(使用文章《Docker 稳定性保障:Ubuntu 环境版本锁定方案》的技巧):

# dpkg -l | grep -E "linux-(headers|image|modules-extra)+" | grep -v 6.12.3 | awk '{print $2}'

linux-headers-6.8.0-52
linux-headers-6.8.0-52-generic
linux-headers-generic-hwe-24.04
linux-image-6.8.0-52-generic
linux-image-generic-hwe-24.04
linux-modules-extra-6.8.0-52-generic

接着,使用 xargs 命令批量清理这些旧内核:

dpkg -l | grep -E "linux-(headers|image|modules-extra)+" | grep -v 6.12.3 | awk '{print $2}' | xargs -I {} sudo apt remove -y {}

锁定当前内核版本

为了确保系统稳定性,特别是考虑到比如 Intel 驱动和相关软件的兼容性,我们可以锁定当前的内核版本:

sudo apt-mark hold  $(dpkg -l | grep -E "linux-(headers|image|unsigned|modules|modules-extra)" | grep 6.12.3 | awk '{print $2}')

最后

好了,这篇文章就先写到这里吧。

–EOF