As of Jan 2020, I manage 65 Linux + ZFS servers. Normally, I prefer to reboot each server after updating its kernel (according to Ret Hat, most updates are related to security fix). Without ZFS, it is not a big issue because rebooting a basic Linux server takes about 30 seconds. However with ZFS, it can take more than 60 seconds if the ZFS dataset is large (It takes time to unload and load the ZFS configurations). So I decide to experiment a new idea: Updating the kernel without rebooting the server. Keep in mind that this is not magic. This method will still introduce downtime, but it is much shorter comparing to rebooting the server. Base on my experience, it cuts about half of the downtime.
Before you try it on a production server, I highly recommend you to try it on a test server/VM first. If your server is a VM host, please be aware of the VM guests may get shut down after upgrade. You will need to wait the system to rebuild the VM modules with the new kernel headers first, then restart the VM guests.
We will use kexec:
sudo yum install kexec-tools -y
Update the kernel, ZFS and DKMS modules
sudo yum update -y
Assuming that you are running an older kernel:
uname -a 3.10.0-1062.4.1.el7.x86_64
If you open /boot/, you will notice that there are many newer kernels available:
ls -al /boot/ | grep x86_64 -rw-r--r-- 1 root root 150K Oct 18 12:19 config-3.10.0-1062.4.1.el7.x86_64 -rw-r--r-- 1 root root 150K Nov 13 18:02 config-3.10.0-1062.4.3.el7.x86_64 -rw-r--r-- 1 root root 150K Dec 2 11:37 config-3.10.0-1062.7.1.el7.x86_64 -rw-r--r-- 1 root root 150K Dec 6 09:53 config-3.10.0-1062.9.1.el7.x86_64 -rw------- 1 root root 30M Dec 13 00:03 initramfs-3.10.0-1062.4.1.el7.x86_64.img -rw------- 1 root root 13M Oct 22 15:41 initramfs-3.10.0-1062.4.1.el7.x86_64kdump.img -rw------- 1 root root 30M Nov 16 00:07 initramfs-3.10.0-1062.4.3.el7.x86_64.img -rw------- 1 root root 30M Dec 4 00:10 initramfs-3.10.0-1062.7.1.el7.x86_64.img -rw------- 1 root root 30M Dec 7 00:14 initramfs-3.10.0-1062.9.1.el7.x86_64.img -rw-r--r-- 1 root root 312K Oct 18 12:19 symvers-3.10.0-1062.4.1.el7.x86_64.gz -rw-r--r-- 1 root root 312K Nov 13 18:03 symvers-3.10.0-1062.4.3.el7.x86_64.gz -rw-r--r-- 1 root root 312K Dec 2 11:37 symvers-3.10.0-1062.7.1.el7.x86_64.gz -rw-r--r-- 1 root root 312K Dec 6 09:53 symvers-3.10.0-1062.9.1.el7.x86_64.gz -rw------- 1 root root 3.5M Oct 18 12:19 System.map-3.10.0-1062.4.1.el7.x86_64 -rw------- 1 root root 3.5M Nov 13 18:02 System.map-3.10.0-1062.4.3.el7.x86_64 -rw------- 1 root root 3.5M Dec 2 11:37 System.map-3.10.0-1062.7.1.el7.x86_64 -rw------- 1 root root 3.5M Dec 6 09:53 System.map-3.10.0-1062.9.1.el7.x86_64 -rwxr-xr-x 1 root root 6.5M Oct 18 12:19 vmlinuz-3.10.0-1062.4.1.el7.x86_64 -rw-r--r-- 1 root root 171 Oct 18 12:19 .vmlinuz-3.10.0-1062.4.1.el7.x86_64.hmac -rwxr-xr-x 1 root root 6.5M Nov 13 18:02 vmlinuz-3.10.0-1062.4.3.el7.x86_64 -rw-r--r-- 1 root root 171 Nov 13 18:02 .vmlinuz-3.10.0-1062.4.3.el7.x86_64.hmac -rwxr-xr-x 1 root root 6.5M Dec 2 11:37 vmlinuz-3.10.0-1062.7.1.el7.x86_64 -rw-r--r-- 1 root root 171 Dec 2 11:37 .vmlinuz-3.10.0-1062.7.1.el7.x86_64.hmac -rwxr-xr-x 1 root root 6.5M Dec 6 09:53 vmlinuz-3.10.0-1062.9.1.el7.x86_64 -rw-r--r-- 1 root root 171 Dec 6 09:53 .vmlinuz-3.10.0-1062.9.1.el7.x86_64.hmac
Pick the newest one. In the other words, we will do the following:
From: 3.10.0-1062.4.1.el7.x86_64 To: 3.10.0-1062.9.1.el7.x86_64
Before we begin, we want to make sure that all of the ZFS / dkms modules have been installed. Make sure that the latest one (3.10.0-1062.9.1.el7) is available:
sudo dkms status zfs, 0.8.2, 3.10.0-1062.4.1.el7.x86_64, x86_64: installed zfs, 0.8.2, 3.10.0-1062.4.3.el7.x86_64, x86_64: installed zfs, 0.8.2, 3.10.0-1062.7.1.el7.x86_64, x86_64: installed zfs, 0.8.2, 3.10.0-1062.9.1.el7.x86_64, x86_64: installed
Keep in mind that my current system is still running the old kernel (3.10.0-1062.4.1.el7.x86_64):
uname -a 3.10.0-1062.4.1.el7.x86_64 modinfo zfs | grep version version: 0.8.2-1 rhelversion: 7.7 srcversion: 29C160FF878154256C93164 vermagic: 3.10.0-1062.4.1.el7.x86_64 SMP mod_unload modversions
Now, we will use kexec to load the new kernel. Please replace the kernel version with the latest one in your system.
sudo kexec -u sudo kexec -l /boot/vmlinuz-3.10.0-1062.9.1.el7.x86_64 --initrd=/boot/initramfs-3.10.0-1062.9.1.el7.x86_64.img --reuse-cmdline
After running the following command, it will introduce downtime. Based on my experience, it should be no longer than 30 seconds. However, I recommend you to test it using a non-production server first.
sudo systemctl kexec
During the update, your remote session may be ended. After waiting for 15-30s, try to connect to server again.
Verify the kernel has been updated:
uname -a 3.10.0-1062.9.1.el7.x86_64 modinfo zfs | grep version version: 0.8.2-1 rhelversion: 7.7 srcversion: 29C160FF878154256C93164 vermagic: 3.10.0-1062.9.1.el7.x86_64 SMP mod_unload modversions
Clean up the old kernels:
sudo package-cleanup --oldkernels --count=1 -y; sudo dkms remove zfs/0.8.2 -k 3.10.0-1062.4.1.el7.x86_64; sudo dkms remove zfs/0.8.2 -k 3.10.0-1062.4.3.el7.x86_64; sudo dkms remove zfs/0.8.2 -k 3.10.0-1062.7.1.el7.x86_64; sudo dkms status;
Now your system is good to go.
Our sponsors: