Change default kernel in Ubuntu 18.04

I have been asked few times, how do you set specific kernel to be always loaded without manually selecting it either from the menu or avoiding setting it as a number which will differ in next kernel update via GRUB_DEFAULT=2 etc..

Current state of play:

root@lab1:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic

root@lab1:~# uname -a
Linux lab1 4.15.0-47-generic #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

root@lab1:~# ll /boot/
total 130069
drwxr-xr-x 4 root root 4096 Apr 3 07:49 ./
drwxr-xr-x 23 root root 4096 Apr 3 07:52 ../
-rw------- 1 root root 4040419 Jul 26 2018 System.map-4.15.0-30-generic
-rw------- 1 root root 4048025 Nov 15 19:01 System.map-4.15.0-42-generic
-rw------- 1 root root 4050115 Feb 6 04:57 System.map-4.15.0-46-generic
-rw------- 1 root root 4050630 Mar 13 04:37 System.map-4.15.0-47-generic
-rw-r--r-- 1 root root 1537161 Jul 26 2018 abi-4.15.0-30-generic
-rw-r--r-- 1 root root 1538114 Nov 15 19:01 abi-4.15.0-42-generic
-rw-r--r-- 1 root root 216807 Jul 26 2018 config-4.15.0-30-generic
-rw-r--r-- 1 root root 217018 Nov 15 19:01 config-4.15.0-42-generic
-rw-r--r-- 1 root root 216996 Feb 6 04:57 config-4.15.0-46-generic
-rw-r--r-- 1 root root 216996 Mar 13 04:37 config-4.15.0-47-generic
drwxr-xr-x 4 root root 512 Jan 1 1970 efi/
drwxr-xr-x 6 root root 4096 Apr 3 07:52 grub/
-rw-r--r-- 1 root root 19973939 Apr 2 14:33 initrd.img-4.15.0-30-generic
-rw-r--r-- 1 root root 19981260 Apr 3 07:49 initrd.img-4.15.0-42-generic
-rw-r--r-- 1 root root 19979337 Apr 2 14:25 initrd.img-4.15.0-46-generic
-rw-r--r-- 1 root root 19981637 Apr 3 07:42 initrd.img-4.15.0-47-generic
-rw-r--r-- 1 root root 0 Jul 26 2018 retpoline-4.15.0-30-generic
-rw-r--r-- 1 root root 0 Nov 15 19:01 retpoline-4.15.0-42-generic
-rw------- 1 root root 8257272 Jul 27 2018 vmlinuz-4.15.0-30-generic
-rw------- 1 root root 8277752 Nov 15 19:04 vmlinuz-4.15.0-42-generic
-rw------- 1 root root 8281848 Feb 6 05:16 vmlinuz-4.15.0-46-generic
-rw------- 1 root root 8290040 Mar 13 04:43 vmlinuz-4.15.0-47-generic

As you can see above I am currently running 4.15.0-47-generic and have a couple of other kernels. I want to use a specific one vmlinuz-4.15.0-30-generic and have it always booting without selecting it on the GRUB menu. I also didn’t want to use GRUB_DEFAULT=2 as during updates this placement of my kernel might change. A bit more control that way. OK. Lets get to it.

To start we want to run grep gnulinux /boot/grub/grub.cfg

Below I am selecting info that I will need to update my /etc/default/grub

root@lab1:~# grep gnulinux /boot/grub/grub.cfg 
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-47-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-47-generic-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-47-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-47-generic-recovery-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-46-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-46-generic-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-46-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-46-generic-recovery-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-42-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-42-generic-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-42-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-42-generic-recovery-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-30-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-30-generic-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {
menuentry 'Ubuntu, with Linux 4.15.0-30-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.15.0-30-generic-recovery-ef5d1337-ed70-436c-a4b2-31580b42e4b8' {

Combining both of them into gnulinux-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8>gnulinux-4.15.0-30-generic-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8

and adding this to /etc/default/grub . We only changing one line, in my example to look like that :

GRUB_DEFAULT="gnulinux-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8>gnulinux-4.15.0-30-generic-advanced-ef5d1337-ed70-436c-a4b2-31580b42e4b8"

Next we need to run update-grub to recreate config file

root@lab1:~# update-grub
Sourcing file /etc/default/grub' Sourcing file/etc/default/grub.d/50-cloudimg-settings.cfg'
Generating grub configuration file …
Found linux image: /boot/vmlinuz-4.15.0-47-generic
Found initrd image: /boot/initrd.img-4.15.0-47-generic
Found linux image: /boot/vmlinuz-4.15.0-46-generic
Found initrd image: /boot/initrd.img-4.15.0-46-generic
Found linux image: /boot/vmlinuz-4.15.0-42-generic
Found initrd image: /boot/initrd.img-4.15.0-42-generic
Found linux image: /boot/vmlinuz-4.15.0-30-generic
Found initrd image: /boot/initrd.img-4.15.0-30-generic
done

and reboot our machine. As soon as it is back, log back in and verify if all OK by running:

root@lab1:~# uname -a
Linux lab1 4.15.0-30-generic #32-Ubuntu SMP Thu Jul 26 17:42:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux