我们建立了本地机房,购买了一定数量的物理服务器,每台服务器安装了Xenserver,并打算在上面创建虚拟机。之前我们一直通过的是XenCenter的方式,图形化的操作来创建我们遇到了一个问题,
那就是,每台新建的VM,其IP地址与主机名等在复制之后,不能自动更新。
我请教过一些同行,可能是他们并没有这样大规模的使用XCP/XenServer,所以都是在XenCenter里面创建好机器,然后通过console进去修改IP地址和主机名等等。
于是乎,我就在Google上反复搜索,最终找到了一个解决办法。那就是通过修改VM的内核引导程序,将自定义的参数传递给一个叫PV-args的内核参数,这样在VM启动之后就可以通过/proc/cmdline中获取到参数了,
在获取到之后,VM在第一次启动时,会执行一个Shell脚本,来根据自定义的参数更新IP地址和主机名等;这样,一台新创建好的VM就可以自动配置好hostname和ip,
后续方便Puppet这样的管理工具,可以接着再自动拉取最新的配置,完成整个服务器的自动化配置,然后上线。
环境介绍:
xenhost1 一台物理XCP/XenServer主机
vm-template 之前定义好的模板
vm-host-1 将要创建的VM
在vm-template中定义一个shell脚本,来根据自定义的参数更新IP地址和主机名,这样,使用该模板创建VM,
(1)、首先在创建VM时传入自定义的参数传递给一个叫PV-args的内核参数,
(2)、之后VM启动就可以通过/proc/cmdline中获取到参数,
(3)、最后自动执行一个Shell脚本,来根据自定义的参数更新IP地址和主机名。
获取vm-template的uuid
[root@xenhost1 ~]# xe vm-list | grep -B 1 vm-template
uuid ( RO) : c77040ae-3a50-9217-ff03-41992c34d1ec
2 name-label ( RW): vm-host-1
修改内核启动方式,并传递自定义参数
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec HVM-boot-policy=""
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec PV-bootloader="pygrub"
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec PV-args="_hostname=vm-template _ipaddr=192.168.1.121 _netmask=255.255.255.0 _gateway=192.168.1.1"
启动vm-template
[root@xenhost1 ~]# xe vm-start vm=vm-template
这里,我们用vm-template模板创建的VM,对这台VM进行配置(就是编写一个shell脚本,在vm启动时执行,)
获取自定义参数
[root@vm-template ~]# cat /proc/cmdline
view sourceprint?
1 ro root=/dev/mapper/vg_t-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_LVM_LV=vg_t/lv_root crashkernel=129M@0M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet _hostname=vm-template _ipaddr=192.168.1.121 _netmask=255.255.255.0 _gateway=192.168.1.1
定义初始化脚本
[root@vm-template ~]# cat /etc/rc.local
view sourceprint?
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
8 /root/bootstrap.sh
创建具体的脚本
[root@vm-template ~]# touch /root/bootstrap.sh
[root@vm-template ~]# chmod +x /root/bootstrap.sh
[root@vm-template ~]# vim /root/bootstrap.sh
查看脚本
[root@vm-template ~]# ls
anaconda-ks.cfg install.log.syslog bootstrap.sh install.log
退出vm-template
[root@vm-template ~]# exit
关闭vm-template
[root@xenhost1 ~]# xe vm-shutdown vm=vm-template
至此,在vm-template创建的VM完成shell脚本的配置
3)、拷贝VM并自动化配置VM的主机名,ip
获取xenhost1本地存储的uuid
[root@xenhost1 ~]# xe sr-list | grep -A 2 -B 3 xenhost1 | grep -A 4 -B 1 "Local Storage"
uuid ( RO) : 38e1ae16-6d5e-55af-5b55-8e26d30b13d7
name-label ( RW): Local storage
name-description ( RW):
host ( RO): xenhost1
type ( RO): lvm
content-type ( RO): user
复制创建新的VM vm-host-1
[root@xenhost1 ~]# xe vm-copy new-name-label=vm-host-1 vm=vm-template sr-uuid=38e1ae16-6d5e-55af-5b55-8e26d30b13d7
9529e2e5-e5b8-a22f-83da-6d3cd1be8101
获取vm-host-1的uuid
[root@xenhost1 ~]# xe vm-list | grep -A 1 9529e2e5-e5b8-a22f-83da-6d3cd1be8101
uuid ( RO) : 9529e2e5-e5b8-a22f-83da-6d3cd1be8101
name-label ( RW): vm-host-1
传递自定义参数
[root@xenhost1 ~]# xe vm-param-set uuid=9529e2e5-e5b8-a22f-83da-6d3cd1be8101 PV-args="_hostname=vm-host-1 _ipaddr=192.168.1.122 _netmask=255.255.255.0 _gateway=192.168.1.1"
启动vm-host-1
[root@xenhost1 ~]# xe vm-start vm=vm-host-1
登陆vm-host-1
[root@xenhost1 ~]# ssh root@192.168.1.122
The authenticity of host '192.168.1.122 (192.168.1.122)' can't be established.
RSA key fingerprint is 81:f9:a4:45:0e:95:36:c5:e5:3e:80:33:8a:3a:db:18.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.122' (RSA) to the list of known hosts.
root@192.168.1.122's password:
Last login: Thu Oct 24 05:49:24 2013 from 10.0.8.34
那就是,每台新建的VM,其IP地址与主机名等在复制之后,不能自动更新。
我请教过一些同行,可能是他们并没有这样大规模的使用XCP/XenServer,所以都是在XenCenter里面创建好机器,然后通过console进去修改IP地址和主机名等等。
于是乎,我就在Google上反复搜索,最终找到了一个解决办法。那就是通过修改VM的内核引导程序,将自定义的参数传递给一个叫PV-args的内核参数,这样在VM启动之后就可以通过/proc/cmdline中获取到参数了,
在获取到之后,VM在第一次启动时,会执行一个Shell脚本,来根据自定义的参数更新IP地址和主机名等;这样,一台新创建好的VM就可以自动配置好hostname和ip,
后续方便Puppet这样的管理工具,可以接着再自动拉取最新的配置,完成整个服务器的自动化配置,然后上线。
环境介绍:
xenhost1 一台物理XCP/XenServer主机
vm-template 之前定义好的模板
vm-host-1 将要创建的VM
在vm-template中定义一个shell脚本,来根据自定义的参数更新IP地址和主机名,这样,使用该模板创建VM,
(1)、首先在创建VM时传入自定义的参数传递给一个叫PV-args的内核参数,
(2)、之后VM启动就可以通过/proc/cmdline中获取到参数,
(3)、最后自动执行一个Shell脚本,来根据自定义的参数更新IP地址和主机名。
获取vm-template的uuid
[root@xenhost1 ~]# xe vm-list | grep -B 1 vm-template
uuid ( RO) : c77040ae-3a50-9217-ff03-41992c34d1ec
2 name-label ( RW): vm-host-1
修改内核启动方式,并传递自定义参数
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec HVM-boot-policy=""
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec PV-bootloader="pygrub"
[root@xenhost1 ~]# xe vm-param-set uuid=c77040ae-3a50-9217-ff03-41992c34d1ec PV-args="_hostname=vm-template _ipaddr=192.168.1.121 _netmask=255.255.255.0 _gateway=192.168.1.1"
启动vm-template
[root@xenhost1 ~]# xe vm-start vm=vm-template
这里,我们用vm-template模板创建的VM,对这台VM进行配置(就是编写一个shell脚本,在vm启动时执行,)
获取自定义参数
[root@vm-template ~]# cat /proc/cmdline
view sourceprint?
1 ro root=/dev/mapper/vg_t-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_LVM_LV=vg_t/lv_root crashkernel=129M@0M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet _hostname=vm-template _ipaddr=192.168.1.121 _netmask=255.255.255.0 _gateway=192.168.1.1
定义初始化脚本
[root@vm-template ~]# cat /etc/rc.local
view sourceprint?
1 #!/bin/sh
2 #
3 # This script will be executed *after* all the other init scripts.
4 # You can put your own initialization stuff in here if you don't
5 # want to do the full Sys V style init stuff.
6
7 touch /var/lock/subsys/local
8 /root/bootstrap.sh
创建具体的脚本
[root@vm-template ~]# touch /root/bootstrap.sh
[root@vm-template ~]# chmod +x /root/bootstrap.sh
[root@vm-template ~]# vim /root/bootstrap.sh
#!/bin/bash
#
# Bootstrap Script for Hostname,Network...
#
# Author: Dong Guo
# Last Modified: 2013/10/24 by Dong Guo
options=$(cat /proc/cmdline|sed 's/.*rhgb quiet //g')
config=/etc/sysconfig/network-scripts/ifcfg-eth0
failed=/root/bootstrap.failed
function check_root(){
if [ $EUID -ne 0 ]; then
echo "This script must be run as root"
exit 1
fi
}
function configure_os(){
echo "DEVICE=eth0" > $config
echo "ONBOOT=yes" >> $config
echo "BOOTPROTO=none" >> $config
for i in $options
do
option=$(echo $i|cut -d "=" -f 1)
value=$(echo $i|cut -d "=" -f 2)
if [ "${option:0:1}" = "_" ]; then
case "$option" in
_hostname)
oldname=$(hostname)
newname=$value
sed -i s/"$oldname"/"$newname"/g /etc/sysconfig/network
hostname $newname
;;
_ipaddr)
echo "IPADDR=$value" >> $config
;;
_netmask)
echo "NETMASK=$value" >> $config
;;
_gateway)
echo "GATEWAY=$value" >> $config
;;
esac
fi
done
}
function restart_network(){
/etc/init.d/network restart
}
function check_status(){
gateway=$(grep -w GATEWAY $config|cut -d "=" -f 2)
route -n | grep -wq $gateway
if [ $? -eq 0 ]; then
sed -i /bootstrap/d /etc/rc.local
if [ -a $failed ]; then
rm -f $failed
fi
else
touch $failed
fi
}
check_root
configure_os
restart_network
check_status
查看脚本
[root@vm-template ~]# ls
anaconda-ks.cfg install.log.syslog bootstrap.sh install.log
退出vm-template
[root@vm-template ~]# exit
关闭vm-template
[root@xenhost1 ~]# xe vm-shutdown vm=vm-template
至此,在vm-template创建的VM完成shell脚本的配置
3)、拷贝VM并自动化配置VM的主机名,ip
获取xenhost1本地存储的uuid
[root@xenhost1 ~]# xe sr-list | grep -A 2 -B 3 xenhost1 | grep -A 4 -B 1 "Local Storage"
uuid ( RO) : 38e1ae16-6d5e-55af-5b55-8e26d30b13d7
name-label ( RW): Local storage
name-description ( RW):
host ( RO): xenhost1
type ( RO): lvm
content-type ( RO): user
复制创建新的VM vm-host-1
[root@xenhost1 ~]# xe vm-copy new-name-label=vm-host-1 vm=vm-template sr-uuid=38e1ae16-6d5e-55af-5b55-8e26d30b13d7
9529e2e5-e5b8-a22f-83da-6d3cd1be8101
获取vm-host-1的uuid
[root@xenhost1 ~]# xe vm-list | grep -A 1 9529e2e5-e5b8-a22f-83da-6d3cd1be8101
uuid ( RO) : 9529e2e5-e5b8-a22f-83da-6d3cd1be8101
name-label ( RW): vm-host-1
传递自定义参数
[root@xenhost1 ~]# xe vm-param-set uuid=9529e2e5-e5b8-a22f-83da-6d3cd1be8101 PV-args="_hostname=vm-host-1 _ipaddr=192.168.1.122 _netmask=255.255.255.0 _gateway=192.168.1.1"
启动vm-host-1
[root@xenhost1 ~]# xe vm-start vm=vm-host-1
登陆vm-host-1
[root@xenhost1 ~]# ssh root@192.168.1.122
The authenticity of host '192.168.1.122 (192.168.1.122)' can't be established.
RSA key fingerprint is 81:f9:a4:45:0e:95:36:c5:e5:3e:80:33:8a:3a:db:18.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.122' (RSA) to the list of known hosts.
root@192.168.1.122's password:
Last login: Thu Oct 24 05:49:24 2013 from 10.0.8.34