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:
- 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://18.104.22.168/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://22.214.171.124/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-126.96.36.199_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-188.8.131.52-2.1.el6.noarch -iwl3945-firmware-184.108.40.206-4.el6.noarch -rt73usb-firmware-1.8-7.el6.noarch -iwl5150-firmware-220.127.116.11-1.el6.noarch -iwl6050-firmware-18.104.22.168-2.el6.noarch -iwl6000g2a-firmware-22.214.171.124-1.el6.noarch -iwl6000-firmware-126.96.36.199-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-188.8.131.52-2.el6.noarch -iwl100-firmware-184.108.40.206-1.el6.noarch -aic94xx-firmware-30-2.el6.noarch -iwl1000-firmware-220.127.116.11-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://18.104.22.168/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://22.214.171.124/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 126.96.36.199 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://188.8.131.52/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.
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!