Installing CentOS without CentOS

DISCLAIMER: This is a log of what I’ve done while trying to get something to work. Not a tutorial. Follow this at your own peril.

Recently, I was looking for a new Dedicated server host that is affordable, and relatively un-managed. The provider I chose to try will remain nameless, as it’s not important.

I want CentOS8, but they don’t have a working centos 8 image, so I installed centos 7, thinking I could upgrade. When logging in to the shell for the first time, I notice that the 3 2tb hard drives are all together in a single raid1 array. I don’t need redundancy on this machine, as I have backups that run hourly saving the difference efficiently in borg-backup. Data-loss on this server is not a concern.

Rebooting my machine into rescue mode launches a PXE ramboot of debian buster. With this, I could get the right architecture for a stable server while maximizing my storage space. Ensure your partitions include the bios_grub flag on the very first partition (about 2mb) if you are using gpt on a bios system.

I need to use YUM on debian?

Yes. Debian did not seem to have a version of dnf I could use, so I had to use YUM to bootstrap my system.

apt update && apt install -y yum

Pretty straight forward. No surprises so far.

In order to use YUM, I needed to configure the base centos repo. Luckily, since I have many such servers at home, I was able to get the right format and location of the mirror reference.

mkdir -pv /etc/yum.repos.d
vi /etc/yum.repos.d/centos.repo


# CentOS-Base.repo
 # The mirror system uses the connecting IP address of the client and the
 # update status of each mirror to pick mirrors that are updated to and
 # geographically close to the client.  You should use this for CentOS updates
 # unless you are manually picking other mirrors.
 #  If the mirrorlist= does not work for you, as a fall back you can try the
 # remarked out baseurl= line instead.

 name=CentOS-$releasever - Base

Now the astute (not me) will notice right away that there is a problem with this. YUM on debian doesn’t have a ‘$releasever’ setting. Lucky for us, we can define that, along with an install root, using yum itself.

I also had to populate the contents of the referenced GPG key, which again, as a straight copy from one of my home servers.

Let’s not also forget to install what is needed for a chroot to finish the install:

yum --installroot=/mnt --releasever=8 install basesystem dnf bash openssh openssh-server

Then, I had to prepare the chroot by binding /dev from the host, and mounting /proc and /sys in the chroot. Once prepared, it’s a simple:

# chroot /mnt /bin/bash
# export LANG=en_CA.UTF-8
# dnf -y --releasever=8 groupinstall "Minimal Install"
# dnf -y install kernel-core

It’s then time to install the bootloader, in this case it’s grub2:

# grub2-install /dev/sda
grub2-install: error: /usr/lib/grub/i386-pc/ doesn't exist. Please specify --target or --directory.

Whoops. That’s not what I expected. Turns out, to do an auto install, it needs an extra package called ‘grub2-pc-modules’:

# dnf -y install grub2-pc-modules

Now, let’s try it again:

# grub2-install /dev/sda

Next, I have to make sure the ssh server starts on boot, and that my root user can login via password for now. I can’t stress enough, this is for now, until I get my ssh key in place.

Next, we have to make sure fstab is in place properly. I suggest UUID’s where possible, and lv names when available.

Once you have all your tools installed as needed, password set, fstab created and grub2 installed and configured, force dracut to create a new initrd.

# ls /boot/initramfs-*

We aren’t going to worry about the rescue image, leaving the initramfs with ‘4.18.0-147.5.1.el8_1.x86_64’ as the version string. This matches the kernel, and will need to be passed to dracut.

Next, backup the original initramfs and generate the new one:

dracut -f /boot/initramfs-4.18.0-147.5.1.el8_1.x86_64.img 4.18.0-147.5.1.el8_1.x86_64

Once the new image is created, cross your fingers and pray you didn’t miss anything. After I confirmed the reboot, I started pinging the IP address to wait for it to come up. I gave it about 5 minutes before giving up.

Without an IPMI console, or some form of remote attaching to the actual install process or machine display (like OVH’s IPMI over IP), this is a reach to far.

Any advice?