Lately, dedicated servers come with Remote management consoles like IPMI KVM or iLO, or DRAC, but they are still slow to initiate the process of installing a system.
Consider a server (dedicated or not) should be installed in a remote colocation with the help of only the server’s network. The system administrator just receives an administrative shell access and nothing more and the server should be installed with the proper and secured software, in this case, the CentOS Stream 9. Using kexec the user can boot a new kernel from a different Linux Distribution and initiate automated network installation of the system and it is not needed any Remote management consoles. The only thing needed is the ability of the current system/kernel to be able to use kexec, which is pretty standard for 8 to 10 years old Linux systems. There is a good chance the colocations’ rescue CD/DVD/USB flash drives or the PXE rescue images support kexec, because they tend to upgrade their rescue systems, which the user may boot if he has problems.
Still, using kexec to initiate another kernel or Linux Distribution like CentOS Stream 9 with VNC installer, for example, it a powerful tool to safely replace a currently running system with only shell access.
This article has chosen to start the CentOS Stream 9 VNC installer just for demonstration purposes. Booting a downloaded kernel may be used for just anything from booting a system over the network, booting an installer, booting an unattended automation installation, and so on. There are a couple of simple things to check before booting the new kernel.
This article will show just one use case – reinstalling a system with CentOS Stream 9 over the network using the CentOS VNC Install. The purpose is to show how simple, fast, and easy is to install a modern Linux system only by having console access. No scripts are required if manual installation is performed.
To boot a CentOS Stream 9 VNC Installer the kexec command needs the following options.
The kexec commands need the following options:
- Networking – device interface name, IP, netmask, gateway and DNS servers
- Kernel options – these options will initiate scripts from the initramfs.
- inst.vnc – a kernel option, which will start a VNC server with no password on the default port and network device. Using it with another inst.vncpassword=[PASSWORD] the VNC server will require the password – [PASSWORD]. The password should be a maximum of 8 characters because the VNC server will not start if it is with more!
- inst.repo=[HTTP/HTTPS://repository] – a kernel option, which sets the CentOS HTTP/HTTPS repository.
The kexec command to boot the CentOS Stream 9 VNC Installer is:
kexec --initrd=./initrd.img -l ./vmlinuz --command-line="bootdev=eno1 ip=10.10.10.20::10.10.10.1:24:srv.example.com:eno1:none nameserver=8.8.8.8 inst.vnc inst.vncpassword=cha3hae4 inst.repo=https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/"
The kernel (i.e. vmlinuz) and the initramfs (i.e. initrd.img) should be downloaded in the current directory before executing the above command. The above line will order the kernel to load the new kernel, but to boot it another command must be executed:
kexec -e
Here is how to prepare and use the kexec command to boot another kernel from a rescue boot system.
STEP 2) Check the current network configuration.
Using iproute tool to find out the network configuration and the udevadm to ensure the real network device name.
root@rescue ~ # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether c8:60:00:bd:35:0e brd ff:ff:ff:ff:ff:ff altname enp3s0 inet 10.10.10.26/27 scope global eth0 valid_lft forever preferred_lft forever inet6 2a01:555:666:7777::2/64 scope global valid_lft forever preferred_lft forever inet6 fe80::ca60:ff:febd:350e/64 scope link valid_lft forever preferred_lft forever root@rescue ~ # ip ro default via 10.10.10.1 dev eth0 10.10.10.0/27 via 10.10.10.1 dev eth0 10.10.10.1 dev eth0 scope link root@rescue ~ # udevadm test-builtin net_id /sys/class/net/eth0 Load module index Network interface NamePolicy= disabled on kernel command line, ignoring. Parsed configuration file /usr/lib/systemd/network/99-default.link Parsed configuration file /usr/lib/systemd/network/73-usb-net-by-mac.link Created link configuration context. Using default interface naming scheme 'v247'. ID_NET_NAMING_SCHEME=v247 ID_NET_NAME_MAC=enxc86000bd350e ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC. ID_NET_NAME_PATH=enp3s0 Unload module index Unloaded link configuration context.
So the current networking configuration is – network device name: enp3s0, IP: 10.10.10.20, network mask: 27, gateway: 10.10.10.1.
STEP 2) Install KEXEC if unavailable.
Install the kexec-tools if they are not available. The name kexec-tools is universal for Ubuntu and CentOS world, so it might be the same for the rest Linux Distros.
root@rescue ~ # cat /etc/*release PRETTY_NAME="Debian GNU/Linux 11 (bullseye)" NAME="Debian GNU/Linux" VERSION_ID="11" VERSION="11 (bullseye)" VERSION_CODENAME=bullseye ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" root@rescue ~ # apt update Hit:1 http://mirror.hetzner.com/debian/packages bullseye InRelease Get:2 http://mirror.hetzner.com/debian/packages bullseye-updates InRelease [44.1 kB] Get:3 http://mirror.hetzner.com/debian/security bullseye-security InRelease [48.4 kB] Hit:4 http://mirror.hetzner.com/tools/Dell/openmanage/openmanage/1001/focal focal InRelease Hit:5 http://deb.debian.org/debian bullseye InRelease Get:6 http://security.debian.org bullseye-security InRelease [48.4 kB] Get:7 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB] Get:8 http://mirror.hetzner.com/debian/packages bullseye-updates/main amd64 Packages [14.8 kB] Get:9 http://mirror.hetzner.com/debian/security bullseye-security/main amd64 Packages [245 kB] Get:10 http://security.debian.org bullseye-security/main Sources [201 kB] Get:11 http://security.debian.org bullseye-security/main amd64 Packages [245 kB] Get:12 http://deb.debian.org/debian bullseye-updates/main Sources [5084 B] Get:13 http://deb.debian.org/debian bullseye-updates/main amd64 Packages [14.8 kB] Fetched 909 kB in 1s (1273 kB/s) Reading package lists... Done Building dependency tree... Done Reading state information... Done 2 packages can be upgraded. Run 'apt list --upgradable' to see them. root@rescue ~ # apt install kexec-tools Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: kexec-tools 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded. Need to get 83.7 kB of archives. After this operation, 285 kB of additional disk space will be used. Get:1 http://mirror.hetzner.com/debian/packages bullseye/main amd64 kexec-tools amd64 1:2.0.20-2.1 [83.7 kB] Fetched 83.7 kB in 0s (7291 kB/s) perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LC_TIME = "bg_BG.UTF-8", LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to a fallback locale ("en_US.UTF-8"). Preconfiguring packages ... Selecting previously unselected package kexec-tools. (Reading database ... 63757 files and directories currently installed.) Preparing to unpack .../kexec-tools_1%3a2.0.20-2.1_amd64.deb ... Unpacking kexec-tools (1:2.0.20-2.1) ... Setting up kexec-tools (1:2.0.20-2.1) ... Generating /etc/default/kexec... Processing triggers for man-db (2.9.4-2) ...
STEP 3) Use the KEXEC to boot the CentOS Stream 9 VNC Installer.
First, download the kernel and initramfs. They are part of the installation disk and of the repository. The kernel is https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/vmlinuz and the initramfs is https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/initrd.img
root@rescue ~ # wget https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/vmlinuz --2023-05-31 13:38:32-- https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/vmlinuz Resolving mirror.stream.centos.org (mirror.stream.centos.org)... 2600:9000:206f:8800:6:ec71:f900:93a1, 2600:9000:206f:4600:6:ec71:f900:93a1, 2600:9000:206f:4a00:6:ec71:f900:93a1, ... Connecting to mirror.stream.centos.org (mirror.stream.centos.org)|2600:9000:206f:8800:6:ec71:f900:93a1|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 12482312 (12M) Saving to: 'vmlinuz' vmlinuz 100%[=========================================>] 11.90M --.-KB/s in 0.1s 2023-05-31 13:38:32 (94.0 MB/s) - 'vmlinuz' saved [12482312/12482312] root@rescue ~ # wget https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/initrd.img --2023-05-31 13:38:36-- https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/isolinux/initrd.img Resolving mirror.stream.centos.org (mirror.stream.centos.org)... 2600:9000:206f:8800:6:ec71:f900:93a1, 2600:9000:206f:4600:6:ec71:f900:93a1, 2600:9000:206f:4a00:6:ec71:f900:93a1, ... Connecting to mirror.stream.centos.org (mirror.stream.centos.org)|2600:9000:206f:8800:6:ec71:f900:93a1|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 99411964 (95M) [application/octet-stream] Saving to: 'initrd.img' initrd.img 100%[=========================================>] 94.81M 107MB/s in 0.9s 2023-05-31 13:38:37 (107 MB/s) - 'initrd.img' saved [99411964/99411964]
Then use the networking information and replace it with the user’s current one and boot up the new kernel:
root@rescue ~ # kexec --initrd=./initrd.img -l ./vmlinuz --command-line="bootdev=enp3s0 ip=10.10.10.20::10.10.10.1:24:srv.example.com:eno1:none nameserver=8.8.8.8 inst.vnc inst.vncpassword=cha3hae4 inst.repo=https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/" root@rescue ~ # kexec -e client_loop: send disconnect: Broken pipe myuser@mydesktop ~ $
The ssh session brokes after a couple of seconds, right after the new kernel boots and the network is initialized. There is ping to the 10.10.10.20.
Using the VNC viewer of the user’s choice will show the first step of the CentOS Stream 9 network installer:
myuser@mydesktop ~ $ vncviewer 10.10.10.26:1 TigerVNC Viewer 64-bit v1.9.0 Built on: 2021-09-30 01:44 Copyright (C) 1999-2018 TigerVNC Team and many others (see README.rst) See http://www.tigervnc.org for information on TigerVNC. Wed May 31 15:01:20 2023 DecodeManager: Detected 4 CPU core(s) DecodeManager: Creating 4 decoder thread(s) CConn: connected to host 5.9.60.26 port 5901 CConnection: Server supports RFB protocol version 3.8 CConnection: Using RFB protocol version 3.8 CConnection: Choosing security type VncAuth(2) Wed May 31 15:01:33 2023 CConn: Using pixel format depth 24 (32bpp) little-endian rgb888 CConn: Using Tight encoding CConn: Enabling continuous updates