During my presentation at Loadays 2015 , I was mentioning some tips and tricks around Anaconda and kickstart, and so how to deploy CentOS , fully automated. I asked the audience about where to store the kickstart, that would be used then by anaconda to install CentOS (same works for RHEL/Fedora), and I got several answers, like "on the http server", or "on the ftp server", which is where most people will put their kickstart files. Some would generate those files files "dynamically" (through $cfgmgmt - I use Ansible with Jinja2 template for this - ) as a bonus point.

But it's not mandatory to host your kickstart file on a publicly available http/ftp/nfs server, and surely not when having to reinstall nodes not in the same DC. Within the CentOS.org infra, I sometimes have to reinstall remote nodes ("donated" to the Project) that are running CentOS 5 or 6 to 7. That's how injecting your ks file directly into the initrd.img really helps. (yes, so network server needed). Just as an intro, here is how you can remotely trigger a CentOS install, without any medium/iso/pxe environment : basically you just need to download the pxeboot images (so vmlinuz and initrd.img), provide some default settings for Anaconda (for the network config, and how to grab stage2 image, and so where is the install tree) On the machine to be reinstalled :

cd /boot/
wget http://mirror.centos.org/centos/7/os/x86_64/images/pxeboot/{vmlinuz,initrd.img}

Now you can generate and copy your kickstart file for that node and send it to the remote node (with scp, etc ..) Next step on that remote node is to "inject" the kickstart directly in the initrd.img :

#assuming we have copied the ks file as ks.cfg in /boot already
echo ks.cfg | cpio -c -o >> initrd.img

So now we have a kernel/initrd.img, containing the kickstart file. You can modify grub(2) to add a new menu entry, make it the default one for next reboot and enjoy. But I usually prefer not doing that, if you need someone to reset that node remotely if something wrong happens, so instead of modifying grub(2), I just use kexec to reboot directly with the new kernel (without having to power cycle the node) :

# can be changed to something else, if for example node is running another distro not using yum as package manager
yum install -y wget kexec-tools 
kexec -l vmlinuz --append='net.ifnames=0 biosdevname=0 ksdevice=eth0 inst.ks=file:/ks.cfg inst.lang=en_GB inst.keymap=be-latin1 ip=your.ip netmask=your.netmask gateway=your.gw dns=your.dns' --initrd=initrd.img && kexec -e

As you can see in the append line, I just tell anaconda/kernel to not use the new nic naming (default now in CentOS 7, and sometimes hard to guess in advance), assuming that eth0 is the one to use (verify carefully that !), and the traditional ks= line in fact now just points to /ks.cfg ( initrd.img being / ). The rest is self-explained.

The other cool stuff, is that you can use the same "inject" technique but for Virtual Machines installed through virt-install : it supports injecting directly files in the initrd.img, so easier than for bare metal nodes : you just have to use two parameters for virt-install :

  • --initrd-inject=/path/to/your/ks.cfg
  • --extra-args "console=ttyS0 ks=file:/ks.cfg”

Hope this helps