Thursday, April 12, 2012

How to use OS customization for CentOS 6 in vCenter 5

Do you have a VMWare vCenter 5 Server with a CentOS 6 template, just to discover that you cannot use OS customizations on it, like you can with Ubuntu and most Windows OS's?

This is the solution for you.
(warning: there is an easier way to do it, look at the comments section)

Background:
If you don't know what I am talking about, the goal is this:
You have spent a lot of time of creating a great VM, with OS and maybe some applications as well, to be used as a master copy that you would like your new VM's to be a copy of. That stuff works great in Windows OS's and a few Linux OS's (like Ubuntu and RedHat), but not with CentOS. CentOS is based on RedHat and is very popular in the IT hosting industry.

Now the problem is that you could make it work in CentOS 5 with a little manual editing, but kernel changes in CentOS 6 broke that old solution.
Note: This step-by-step guide is not supported by VMWare or is support, so use it at your own risk!
This only works in vCenter 5, if you want to achieve the same in vCenter 4.1, you have to change the OS setting on the VM to RedHat.

What happens when you clone a Template in vCenter on a template with CentOS 6 ?
The answer is that the device manager (udev) in the kernel 2.6.13 and above remembers the NIC settings from the template, so you end up with 2 NIC's in your cloned VM. Note that you have to edit the VM template to be a RedHat server (not CentOS!) in order to use a Guest Customization in vCenter, otherwise you will receive an error message in vCenter. (hint: convert the template to a VM and than edit settings to change OS type)

Here is an example:


[root@centostemplate ~]# cat /etc/udev/rules.d/70-persistent-net.rules
# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.
# PCI device 0x15ad:0x07b0 (vmxnet3) (custom name provided by external tool)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:56:42:02:2f", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
# PCI device 0x15ad:0x07b0 (vmxnet3)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:56:42:ef:34", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

What you end up with, is 2 nic's on the clones VM, eth0 being a clone of the original nic and eth1 being the new nic in your VM.

This is problematic as eht0 is not shown at all if you do a ifconfig, it will only show eth1 with DHCP and even if you set a static IP (in the Customization Wizard), it will not work.

Now for the solution:
Remove the section of eth0 on this file /etc/udev/rules.d/70-persistent-net.rules
Example (remove everything in red):



# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.
# PCI device 0x15ad:0x07b0 (vmxnet3) (custom name provided by external tool)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:56:42:02:2f", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
# PCI device 0x15ad:0x07b0 (vmxnet3)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:56:42:ef:34", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"


And than change NAME from eth1 to eth0.

Now you have a working nic, but with wrong config.

To correct the config:

[root@centostemplate ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="static"
HWADDR="00:50:56:42:ef:34"
IPV6INIT="no"
IPV6_AUTOCONF="no"
NM_CONTROLLED="no"
ONBOOT="yes"
IPADDR="192.168.10.125"
NETMASK="255.255.255.0"
NETWORK="192.168.10.0"
BROADCAST="192.168.10.255"


Note that you have to edit the HWADDR to match the new nic's mac address. If you are unsure what is the correct mac address, just edit the VM and look on the network card mac settings.

Reboot the server and your done!
That's it, maybe a little extra work, but on the other hand, now you can use Guest Customizations on vCenter, which saves a lot of work hours!

Credit to http://aaronwalrath.wordpress.com/2011/02/26/cloned-red-hatcentosscientific-linux-virtual-machines-and-device-eth0-does-not-seem-to-be-present-message/ for getting me in the rightt direction!

8 comments:

  1. This can be easily fix with this kind of script :

    # Annoying bug in vmware guest centos6
    # eth0 doesn't exist

    ifconfig eth0 2>/dev/null >/dev/null
    if [ $? -ne 0 ] ; then
    # Rename eth1 with eth0
    echo "UDEV Config..."
    rm /etc/udev/rules.d/70-persistent-net.rules

    # Change ifcfg-eth0 with hostname address (in /etc/hosts)
    echo "Changing eth0 address..."
    mac=`ifconfig eth1 | grep eth1 | awk '{ print $5}'`
    hostname=`hostname`
    ip=`grep $hostname /etc/hosts|cut -s -f 1`
    rm -f /etc/sysconfig/network-scripts/ifcfg-eth1
    cfg=`grep -v IPADDR /etc/sysconfig/network-scripts/ifcfg-eth0 |grep -v HWADDR`
    echo "$cfg" > /etc/sysconfig/network-scripts/ifcfg-eth0
    echo "HWADDR=\"$mac\"" >> /etc/sysconfig/network-scripts/ifcfg-eth0
    echo "IPADDR=\"$ip\"" >> /etc/sysconfig/network-scripts/ifcfg-eth0

    # Apply changes
    echo "Applying changes..."
    service network stop
    service NetworkManager stop
    ifconfig eth1 down
    udevadm trigger
    udevadm control --reload-rules
    service network start
    service NetworkManager start
    fi

    I had it in a .conf file /etc/init/.
    I hope it helps...

    ReplyDelete
  2. Thanks!
    Actually I found another easier solution, that does not require scripting or editing any files.

    In vCenter5, when you deploy a new VM from the CentOS template (marked as RedHat in vCenter), choose to "Use the Customization wizard to temporarily adjust specifications....". On the network part, I deleted the nic and added a new nic during the wizard.

    And thats all that I needed to do.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. There's actually an even easier way to do this. In your template simply comment out the lines in /etc/udev/rules.d/70-persistent-net.rules and mark the file immutable.

    chattr +i /etc/udev/rules.d/70-persistent-net.rules

    ReplyDelete
  5. Thanks for the article. Just as a heads up I jst set up a template using CentOS6.4x64 minimal install, and Im on ESX 5.1u1a. I am able to use the customization successfully without doing any of the above bu changing the OS in the VMX file to Redhat6x64. works like a charm :)

    ReplyDelete
  6. Thanks for the article.
    This is the simplest way:
    1- Delete/Comment all the eth related lines inside /etc/udev/rules.d/70-persistent-net.rules
    2- rm /etc/sysconfig/network-scripts/ifcfg-eth*
    3- rm /etc/sysconfig/network-scripts/route-eth*
    4- Power off the VM and convert to Template
    Just make sure the guest OS type is one of RHEL ones
    clone and enjoy

    ReplyDelete
  7. Hi guys,

    Great suggestions. However none of these are working for me. I'm using CentOS 6.5.

    I need to be able to get a DHCP address, yet set a static DNS server. However it only works on the source VM that I used. Any other ideas?

    ReplyDelete
  8. Paul, use this
    http://vbyron.com/blog/30-minute-deploy-001-centos-6-5-vm-template/

    ReplyDelete