Kickstart your CentOS Template, EL6 Edition

Note: This article uses Enterprise Linux 6. If you are looking for Enterprise Linux 7, check out the new edition!

A few days ago, I started my Puppet series. I described how to manually build a brand new golden image or how to add puppet to an existing image. I also said that I hoped everyone had that process automated, for example with kickstart. If you don’t have an automated process in place, I’ll show you how to get started with kickstart.

Kickstart is a tool for creating repeatable, but customized, installations. There is lots of documentation available (Fedora and RHEL sites, for example). There are a few methods to make a kickstart file available, but we’re going to focus on using the network. Here’s what you’ll need to get started:

  • vCenter
  • A DHCP server in the network where the VM will be deployed.
  • Firewall rules and routing allowing the provisioned VM to communicate with the web server.
  • A web server to host the kickstart file.
  • A CentOS netinstall ISO in your vSphere infrastructure, download from a mirror.
  • Ability to create VMs in your vSphere infrastructure.

If you don’t have vCenter, you cannot create templates. While the kickstart process might still be useful to you, it’s not going to provide the same return as templates, IMO.

You need to ensure your site’s networking fits the first two criteria: DHCP, firewall, and routing. If it’s available, have an existing VM in the target network access the web server. If that VM uses DHCP, then you can check off both requirements. If you do not have access, however, you’re going to have to figure out on your own – troubleshooting your network is a bit beyond the scope of this article.

Next up is a web server. This instance can be very simple. We’re going to serve a single kickstart file, a copy of the CentOS repo, VMware Tools, and our site banner. The repo can be acquired in a number of ways, such as downloading CentOS-6.5-x86_64-bin-DVD1.iso, mounting it on the web server,and running rsync -a /mnt/ /var/www/html/CentOS/.Load the correct VMware tools tarball (I mounted the VMware tools iso and copied the tarball to vmwaretools.tgz) and name the banner issue. Put all of these objects in the root of the webserver and don’t forget to verify that files are readable by the web server user.

The netinstall ISO should be downloaded and added to your ISO datastore.

The last thing we need is permissions in vCenter to create a VM, attach an ISO, power the VM on, and access the console. Here’s the VM specs we’re going to create:

  • Name: centos-template
  • Location: <installation specific>
  • CPU: 1
  • Memory: 512 MB
  • Hard Disk 1: 60 GB
  • Network Adapter 1: <installation specific, where DHCP is available>
  • CD/DVD drive 1: <path to netinstall ISO>, connect at startup
  • Guest OS: Linux
  • Guest OS Version: Red Hat Enterprise 6 (64-bit) (you heard that right, do NOT choose CentOS 4/5/6 or you won’t be able to use a customization spec)
  • Other options as specified by your VM creation process.

Create the VM, but do not start it yet. Now it’s time to circle back to the kickstart file. Here are the contents for a minimal CentOS install plus puppet open source. I’ll explain some of the details afterward.

#Centos Kickstart for net install
#version=<VERSION>

install
url  --url http://1.2.3.4/CentOS
lang en_US.UTF-8
keyboard us
#text
cmdline
network --onboot yes --device eth0 --bootproto dhcp --noipv6 --hostname centos-template.your.domain
rootpw  --iscrypted <encrypted password>
firewall --service=ssh
authconfig --enableshadow --passalgo=sha512
selinux --enforcing
timezone --utc Etc/UTC
bootloader --location=mbr --driveorder=sda --append="crashkernel=auto rhgb quiet"

zerombr
clearpart --all --drives=sda --initlabel

part /boot --fstype=ext4 --size=500
part pv.008002 --grow --size=200

volgroup vg_template --pesize=4096 pv.008002
logvol /home --fstype=ext4 --name=lv_home --vgname=vg_template --size=15000
logvol / --fstype=ext4 --name=lv_root --vgname=vg_template --size=5000
logvol swap --name=lv_swap --vgname=vg_template --size=4096
logvol /usr --fstype=ext4 --name=lv_usr --vgname=vg_template --size=15000
logvol /var --fstype=ext4 --name=lv_var --vgname=vg_template --size=15000

repo --name="CentOS"  --baseurl=http://1.2.3.4/CentOS --cost=100

%packages --nobase
@core
@server-policy
ntpdate
ntp
wget
screen
git
perl
openssh-clients
man
system-config-network-tui
mlocate
bind-utils
traceroute
mailx

#Remove these

-iwl5000-firmware-8.83.5.1_1-1.el6_1.1.noarch
-ivtv-firmware-20080701-20.2.noarch
-xorg-x11-drv-ati-firmware-7.1.0-3.el6.noarch
-atmel-firmware-1.3-7.el6.noarch
-iwl4965-firmware-228.61.2.24-2.1.el6.noarch
-iwl3945-firmware-15.32.2.9-4.el6.noarch
-rt73usb-firmware-1.8-7.el6.noarch
-iwl5150-firmware-8.24.2.2-1.el6.noarch
-iwl6050-firmware-41.28.5.1-2.el6.noarch
-iwl6000g2a-firmware-17.168.5.3-1.el6.noarch
-iwl6000-firmware-9.221.4.1-1.el6.noarch
-ql2400-firmware-7.00.01-1.el6.noarch
-ql2100-firmware-1.19.38-3.1.el6.noarch
-libertas-usb8388-firmware-5.110.22.p23-3.1.el6.noarch
-ql2500-firmware-7.00.01-1.el6.noarch
-zd1211-firmware-1.4-4.el6.noarch
-rt61pci-firmware-1.2-7.el6.noarch
-ql2200-firmware-2.02.08-3.1.el6.noarch
-ipw2100-firmware-1.3-11.el6.noarch
-ipw2200-firmware-3.1-4.el6.noarch
-bfa-firmware-3.2.21.1-2.el6.noarch
-iwl100-firmware-39.31.5.1-1.el6.noarch
-aic94xx-firmware-30-2.el6.noarch
-iwl1000-firmware-39.31.5.1-1.el6.noarch
%end

%post --log=/root/ks-post.log

rpm -ivh https://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-7.noarch.rpm
yum -y install puppet
yum -y update

chkconfig ntpd on

mkdir /lib/udev/rules.d/disabled
mv /lib/udev/rules.d/75-persistent-net-generator.rules /lib/udev/rules.d/disabled
mv /lib/udev/rules.d/75-cd-aliases-generator.rules /lib/udev/rules.d/disabled
rm -f /etc/udev/rules.d/*persistent*
echo "mv /lib/udev/rules.d/75-persistent-net-generator.rules /lib/udev/rules.d/disabled" >> /etc/rc.local
echo "mv /lib/udev/rules.d/75-cd-aliases-generator.rules /lib/udev/rules.d/disabled" >> /etc/rc.local
echo "rm -f /etc/udev/rules.d/*persistent*" >> /etc/rc.local

sed -i '/^NM_CONTROLLED/d' /etc/sysconfig/network-scripts/ifcfg-eth0
sed -i '/^HWADDR/d' /etc/sysconfig/network-scripts/ifcfg-eth0
sed -i '/^MTU/d' /etc/sysconfig/network-scripts/ifcfg-eth0
sed -i '/^UUID/d' /etc/sysconfig/network-scripts/ifcfg-eth0
sed -i '/^NAME/d' /etc/sysconfig/network-scripts/ifcfg-eth0

mkdir /root/postinstall
cd /root/postinstall
wget http://1.2.3.4/vmwaretools.tgz
tar -xzvf vmwaretools.tgz
cd vmware-tools-distrib/
./vmware-install.pl -d  --clobber-kernel-modules=vmmemctl,vmxnet3,pvscsi
cd /root/postinstall
rm -rf ./vmware-tools-distrib
rm -rf vmwaretools.tgz
wget http://1.2.3.4/issue
\cp -f issue /etc/issue
\cp -f /etc/issue /etc/issue.net
rm -rf ./issue 
echo "Banner /etc/issue.net" >> /etc/ssh/sshd_config
postconf -e relayhost=smtp.your.domain

%end

reboot

Name this file dhcp.ks. Let’s explain some of the options in it:

  • #version=<VERSION> – Put a version or label on your kickstart.
  • url – This is the URL to the CentOS mirror. If you skip this step it will use the official CentOS mirrors, which is likely slower than your local network. Change the IP/path to reflect your installation.
  • network – We’re specifying that the completed installation will use DHCP and have the hostname centos-template.your.domain. You can customize this as well. You can have a single dhcp.ks file for generic installs and create additional files with static IP assignments and hostnames if you like. If you plan to use vSphere templates, however, stick with DHCP, perhaps one per datacenter, and we’ll use vSphere for the customization.
  • rootpw – Explanatory
  • firewall – Our template will only allow inbound ssh
  • selinux – It’s sometimes a pain, but it’s best practice to enable SELinux.
  • timezone – I prefer UTC so that all servers have the same time and our central syslog timestamps match the times on the servers.
  • part, volgroup, and logvol – We are specifying how the 60 GB hard disk is allocated. You’ll see this leaves a little over 1 GB unallocated – we use thin provisioning so there’s no loss for us. If you use thick provisioning, I’ll show you how to eliminate that 1 GB overage.
    • NOTE: There is a bug in Puppet that modules with rspec tests do get copied properly from their /var staging area to /etc/puppet/modules properly in v3.4.3. Until PUP-1639 is resolved, I suggest creating / as a 20G partition and not creating a /var partition. Once it is resolved, I suggest 5GB and 15GB, respectively. As this process only occurs on a Puppet master, create a separate kickstart for those nodes.
  • %packages – The template will only have a minimal installation (core and server-policy packages) plus a few packages that we’ve determined we want on all our servers. Tune as needed.
    • Perl seems to be something people don’t want. It is required for VMware Tools. Even if you don’t want Perl, you do want VMware Tools.
    • I recently (20140828) added mailx. You could install this via puppet where needed, but I found it needed often enough that it made sense to put it in the template.
  • #Remove these – As we added packages above, here are packages we specifically do NOT want installed. Keep your attack surface trim, remove anything you do not need on every server.
  • %post – These are commands run after the CentOS install is completed:
    • rpm/yum – Install Puppet open source edition.
    • chkconfig – Enable ntpd.
    • mkdir/mv/echo/sed – In this section we’ll deal with a common issue with modern linux. The ethernet adapters are tied to the UUID/MAC on a VM. This will prevent us from deploying from a template successfully, as new VMs will get a new UUID/MAC and will have no network access. This is perfect for a single NIC VM, but may not work if you have multiple NICs. If that is the case, test thoroughly.
    • In the next section we download VMware tools and the banner and install them in the right location.
    • postconf – Provide a valid SMTP mail relay hostname.
  • reboot – By adding this, you can walk away and come back to a complete and booted template. If you leave it off, it just means you come back to a prompt to reboot the VM.

All you should need to change is the IP address 1.2.3.4 to your webserver IP, and maybe adjust some paths. Save the file in the web server’s root as dhcp.ks. Start your VM. Interrupt the boot process (hit ESC once or twice) and enter this startup statement:

linux ks=http://1.2.3.4/dhcp.ks ip=dhcp

At this point you should be able to walk away and come back to a CentOS VM that’s receiving DHCP, has a slightly modified minimal installation, and has puppet installed. Ensure the VM has network access and shut it down. Right click on it and convert it to a VM. When you deploy the template to a new VM and use a customization specification, it will receive the hostname and network configuration specified by the custspec, thus providing a standardized template for you to build on. In the Puppet series, we’ll discuss how to customize the deployed template further.

Note: If you decide to redo the template, it may be tempting to keep the same VM and just delete/create a new hard disk. If so, make sure to assign the new disk SCSI ID (0,0), or any new disk you add after post-install will receive ID (0,0) and prevent the VM from booting.

Further Customization

One last note, I mentioned above that you can customize the hard drive allocations to eliminate loss. The best way to do this is to perform a manual install of CentOS and customize the disk layout to your needs. After installation, the file /root/anaconda-ks.cfg is created. This is a kickstart file that represents the choices made during the install. You can grab the partition information and update dhcp.ks with it.

Any of the other configuration options can be customized either by reading the copious documentation for Kickstart or by performing a manual installation that is “just right” and taking some or all of the resultant kickstart file.

Lastly, this is just the surface of what kickstart can do. In my puppet series, I will rely on puppet for customization post-install, but pre-install customization is an option as well. You can dynamically build ISOs that include a customized KS file for one-stop deployment of fresh VMs in a single step. This will require some external tools to bring it all together, which is beyond the scope of this article, but it’s something worth exploring if you deploy VMs at a high rate.

Special thanks to Mike SoRelle for locking himself in a room for a few days and tweaking the kickstart to the absolute minimum packages required!

2 thoughts on “Kickstart your CentOS Template, EL6 Edition

  1. Pingback: Minecraft module for Puppet | rnelson0
  2. Pingback: Kickstart your CentOS Template, EL7 Edition | rnelson0

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s