CentOS 7.x 升级内核

默认,CentOS 7.x下,运行yum update会自动升级内核,不过一般都是非常保守的升级:

yum list kernel*
已安装的软件包
kernel.x86_64      3.10.0-514.el7                                         @anaconda     
kernel.x86_64      3.10.0-514.10.2.el7                                    @updates      
kernel.x86_64      3.10.0-514.16.1.el7                                    @updates 

这里可以看到,默认安装的是3.10.0-514.el7, 后来更新两次,分别安装了3.10.0-514.10.2.el7和3.10.0-514.16.1.el7。可见,内核版本号并没有发生任何改变,只是横杆后(-)的数字发生改变,这个应该是发行商维护的(非Linux内核维护),主要应该是一些补丁包添加。

如果要升级到最新的Linux内核,可以去kernel.org去下载源代码编译,不过随着内核越来越复杂,编译涉及到的内容非常多,所以注定是一件费时费力的事情。

首先了解一下kernel.org提供的Linux内核的版本(https://www.kernel.org/category/releases.html)。简单来说,RC版本就是预发布版本,Mainline主线版本,一般2-3月发布一次。Mainline之后就会释放稳定(Stable)版本。还有Longterm版本,表示是长期支持的版本。大部分发行版本Linux都会考虑使用Longterm版本的内核,比如CentOS中就使用3.10.0这个版本。

Longterm release kernels
Version Maintainer Released Projected EOL
4.9 Greg Kroah-Hartman 2016-12-11 Jan, 2019
4.4 Greg Kroah-Hartman 2016-01-10 Feb, 2018
4.1 Sasha Levin 2015-06-21 Sep, 2017
3.16 Ben Hutchings 2014-08-03 Apr, 2020
3.12 Jiri Slaby 2013-11-03 May, 2017
3.10 Willy Tarreau 2013-06-30 Oct, 2017
3.4 Li Zefan 2012-05-20 Apr, 2017
3.2 Ben Hutchings 2012-01-04 May, 2018

从这个表格看,3.10.0这个内核从2013年开始发布,到现在(2017年)已几年过去了,看起来稍微是有点旧了。而且2017年以后,至少需要使用4.4的内核。

为了便利地升级内核,可以使用elrepo(http://elrepo.org)这个软件源,以yum的方法快速安装:

# import key
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# install elrepo repo
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
# install kernel
yum --enablerepo=elrepo-kernel install  kernel-ml-devel kernel-ml -y
# modify grub
grub2-set-default 0
# reboot
reboot

以上安装的是最新的稳定版。源elrepo提供两个内核,kernel-ml中的ml是指mainline, 是mainline后的最新稳定版本;还有一个叫kernel-lt,它是基于长期支持版本的,比如当前kernel-lt就是指4.4版本的内核。

可以浏览如下链接,查看具体的软件包:
http://elrepo.org/linux/kernel/el7/x86_64/RPMS/

要确定可以使用哪些内核,可以使用:

yum --enablerepo=elrepo-kernel list kernel*

关于Grub2:
“Briefly, a boot loader is the first software program that runs when a computer starts. It is responsible for loading and transferring control to an operating system kernel software (such as Linux or GNU Mach). The kernel, in turn, initializes the rest of the operating system (e.g. a GNU system). ”

查看下安装:

rpm -qa | grep grub2
grub2-tools-2.02-0.44.el7.centos.x86_64
grub2-2.02-0.44.el7.centos.x86_64

rpm -ql grub2-2.02-0.44.el7.centos.x86_64
/boot/grub2/grub.cfg
/boot/grub2/grubenv
/etc/grub2.cfg  #软连接到/boot/grub2/grub.cfg

rpm -ql grub2-tools-2.02-0.44.el7.centos.x86_64
/etc/default/grub

/etc/grub.d
/etc/grub.d/00_header
/etc/grub.d/01_users
/etc/grub.d/10_linux
/etc/grub.d/20_linux_xen
/etc/grub.d/20_ppc_terminfo
/etc/grub.d/30_os-prober
/etc/grub.d/40_custom
/etc/grub.d/41_custom
/etc/grub.d/README

/etc/prelink.conf.d/grub2.conf
/etc/sysconfig/grub -> /etc/default/grub

/usr/bin/grub2-editenv
/usr/bin/grub2-file
/usr/bin/grub2-fstest
/usr/bin/grub2-glue-efi
/usr/bin/grub2-kbdcomp
/usr/bin/grub2-menulst2cfg
/usr/bin/grub2-mkfont
/usr/bin/grub2-mkimage
/usr/bin/grub2-mklayout
/usr/bin/grub2-mknetdir
/usr/bin/grub2-mkpasswd-pbkdf2
/usr/bin/grub2-mkrelpath
/usr/bin/grub2-mkrescue
/usr/bin/grub2-mkstandalone
/usr/bin/grub2-render-label
/usr/bin/grub2-script-check
/usr/bin/grub2-syslinux2cfg

/usr/sbin/grub2-bios-setup
/usr/sbin/grub2-get-kernel-settings
/usr/sbin/grub2-install
/usr/sbin/grub2-macbless
/usr/sbin/grub2-mkconfig
/usr/sbin/grub2-ofpathname
/usr/sbin/grub2-probe
/usr/sbin/grub2-reboot
/usr/sbin/grub2-rpm-sort
/usr/sbin/grub2-set-default
/usr/sbin/grub2-setpassword
/usr/sbin/grub2-sparc64-setup

Grub简单来说就是一个引导程序。机器子上电自检后,会从启动硬盘寻找引导程序,控制权交给引导程序后,由它负责系统引导,最关键的任务就是从什么地方载入内核。

配置文件/etc/grub2.cfg是一个软连接,指向/boot/grub2/grub.cfg,这个是主要的配置文件,其中有启动菜单项(多个,第一个标号为0,第二个为1,依次类推):

menuentry 'CentOS Linux (4.10.12-1.el7.elrepo.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-514.el7.x86_64-advanced-3f38705e-ad35-43b8-b624-4f021e320c87' {
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_msdos
	insmod xfs
	set root='hd0,msdos1'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1'  f89b61bd-58b6-48c5-98db-ec8a00d84a3e
	else
	  search --no-floppy --fs-uuid --set=root f89b61bd-58b6-48c5-98db-ec8a00d84a3e
	fi
	linux16 /vmlinuz-4.10.12-1.el7.elrepo.x86_64 root=/dev/mapper/cl-root ro crashkernel=auto rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet LANG=zh_CN.UTF-8
	initrd16 /initramfs-4.10.12-1.el7.elrepo.x86_64.img
}

一般,升级内核后会自动添加一个菜单项(在第0个位置)。默认,Grub取哪个菜单引导,取决于/boot/grub2/grubenv中的saved_entry配置:

saved_entry=0

这样表示取排在第0个位置的菜单作为默认引导。

也可以直接是菜单项名称,比如:

saved_entry=CentOS Linux (4.10.12-1.el7.elrepo.x86_64) 7 (Core)

可以直接编辑/boot/grub2/grubenv中的saved_entry,也可以使用工具grub2-editenv来编辑/boot/grub2/grubenv,不过如果仅仅想改变saved_entry这个环境变量,则可以使用grub2-set-default来进行,比如grub2-set-default 0就是把/boot/grub2/grubenv中的saved_entry设置为0。

为了防止载入不确定的内核(比如编辑了菜单),一般不建议使用索引号,可以如下设置,锁定默认到指定菜单:

grub2-set-default 'CentOS Linux (4.10.12-1.el7.elrepo.x86_64) 7 (Core)'