kvm比起vmware來講最沒有的功能就是用模板部署虛擬機的時候能夠自定義ip地址,這對於大量建立vm的場景來講你須要一臺臺vnc的登陸改動ip,顯然是很累的,最近我就遇到這種場景(大型的cloudstack和openstack架構不說)linux
想到了一個方法,就是用一臺關了機的虛擬機做爲模板,複製它的xml文件能夠改mac地址,這樣就能夠經過mac地址的惟一性而在模板虛擬機中加入一個腳原本根據一個寫好在虛擬機中的列表文件來設定相應的ip地址和服務器名。
這種方法要求如下步驟centos
1.模板虛擬機中有開機啓動的腳本,該腳本會根據列表文件設定本身的ip和服務器名,並在設定後創建鎖文件,以避免再次重啓後從新設定。
2.列表文件寫在模板虛擬機中,這就限制了靈活場景的時候,只有在預先設定好的虛擬機建立場景中才有效,若是要臨時添加虛擬機,而且數量很少(一兩臺)的時候,你還花功能去從新更新模板虛擬機中的列表文件顯得很費力。
3.kvm建立的虛擬機mac地址要和模板虛擬機中的列表文件保持一致。bash
模板虛擬機須要完成的任務主要有如下
1.跟kvm建立虛擬機用的模板虛擬機路徑相同
2./etc/rc.local中有相應的啓動設定腳本
3.列表文件服務器
開機啓動腳本架構
[root@linux-host2 ~]# cat init_setting.sh #!/bin/bash setting_list="/root/setting_list" if [ ! -f $setting_list ];then echo "[$setting_list] not exist" exit 1 fi lock_file="/root/setting_lock" if [ -f $lock_file ];then echo "this vm has been set.exit" exit 0 fi myeth0mac=`ip a|awk '/eth0/{getline;print}'|grep 'link/ether'|awk '{print $2}'|awk -F':' '{print $4":"$5":"$6}'` myinfoline=`cat $setting_list|grep $myeth0mac` #if [ ! -f "$myinfoline" ];then # echo "sorry,can't fine info from [$setting_list]" # exit 1 #fi myip=`echo $myinfoline|awk '{print $2}'` myhostname=`echo $myinfoline|awk '{print $3}'` sed -ir "s/IPADDR=.*/IPADDR=$myip/" /etc/sysconfig/network-scripts/ifcfg-eth0 systemctl restart network hostnamectl set-hostname $myhostname echo "this vm has been set">$lock_file
把以上腳本加入開機啓動ide
echo "/root/init_setting.sh > /root/init.log 2>&1" >>/etc/rc.local chmod 755 /etc/rc.d/rc.local
/root/setting_list文件示例,如下對應的爲mac地址的後三位 ip 主機名,你問mac地址怎麼生成,用如下命令生成,我這邊只作了三位ui
openssl rand -hex 3 | sed -r 's/..\B/&:/g'
4a:b7:01 xxx.xx.xx.201 vm1 71:5b:32 xxx.xx.xx.202 vm2 28:34:18 xxx.xx.xx.203 vm3
而後將該虛擬機關機,供kvm克隆使用this
[root@localhost ~]# cat lxd/kvm3.sh #!/bin/bash #建立單個虛擬機(須要電腦中存在模板虛擬機) #獲取新虛擬機名稱(單個建立模式) get_newname(){ while true do read -p "請輸入新虛擬機名稱:" newname if [ $newname ];then break else echo "************" echo "請輸入姓名!" echo "************" fi done } get_newmemary(){ while true do current_free_mem=`free -m|awk '/^-/{print $4}'` mem_total=`free -g|awk '/^Mem/{print $2}'` echo "目前本機內存總大小:${mem_total} G" echo "當前空閒內存大小爲:${current_free_mem} MB" read -p "請輸入新虛擬機內存大小(單位G):" newmemary if [ $newmemary ];then if [[ $newmemary -le $mem_total ]];then break else echo "**********************************" echo "輸入的數值必須小於當前內存總大小!" echo "**********************************" fi else echo "********************" echo "請輸入新虛擬機內存!" echo "********************" fi done } get_newcpu(){ while true do core=`cat /proc/cpuinfo| grep "processor"| wc -l` echo "可用core個數:${core}" read -p "請輸入新虛擬機處理器核數:" newcpu if [ $newcpu ];then if [ $newcpu -le $core ];then break else echo "******************************" echo "不能超過可用個數或者輸入錯誤!" echo "******************************" fi else echo "**************" echo "輸入不能爲空!" echo "**************" fi done } #設置虛擬機名稱(自定義建立多個虛擬機) set_group_name(){ #虛擬機個數 read -p "新虛擬機個數:" vir_num free_vir=$vir_num #功能分組 echo "**********************************************************************************" echo "設置好組名以後,虛擬機將每組下的虛擬機自動用【組名0一、組名0一、組名0三、...】的形式命名" echo "**********************************************************************************" read -p "須要分幾種功能類型(大於1):" vir_type if [ ${vir_type} -gt ${vir_num} ];then echo "輸入不符合規則!" exit fi #設置名字,組名+數字 k=1 for((i=1;i<=${vir_type};i++)) do read -p "第${i}組組名:" group[$i] read -p "分配新虛擬機個數:" group_num_vir #檢測輸入 free_vir=$((${free_vir}-${group_num_vir})) if [ ${group_num_vir} -gt ${vir_num} ];then echo "輸入錯誤,超過自定義虛擬機個數!" exit elif [ ${free_vir} -lt $((${vir_type}-${i})) ];then echo "分配不均,請從新分配!" exit fi #記錄組內虛擬機個數 for((j=1;j<=${group_num_vir};j++)) do name_n="${group[$i]}${j}" name[${k}]=${name_n} k=$(($k+1)) done done echo "準備建立以下虛擬機:" for((i=1;i<=${vir_num};i++)) do echo ${name[${i}]} done } #設置xml所需參數 set_xml_args_single(){ uuid=`uuidgen` src_path=/opt/kvm/images/rh7-1.qcow2 src_xml=/etc/libvirt/qemu/master.xml new_path=/opt/kvm/images/${newname}.qcow2 new_path_sed="\/opt\/kvm\/images\/${newname}.qcow2" new_xml=/etc/libvirt/qemu/${newname}.xml } #設置xml所需參數(多個),例如:【set_xml_args ${name[${i}]} $new_memary $new_cpu】 set_xml_args(){ newname=$1 newmemary=$2 newcpu=$3 uuid=`uuidgen` src_path=/mnt/lv2/centos7.0.qcow2 src_xml=/etc/libvirt/qemu/centos7.0.xml new_path=/mnt/lv1/${newname}.qcow2 new_path_sed="\/mnt\/lv1\/${newname}.qcow2" new_xml=/etc/libvirt/qemu/${newname}.xml } #複製模板、xml copy_model_xml(){ cp $src_path $new_path cp $src_xml $new_xml } #修改xml文件 modification_xml(){ sed -ri "s/(<name>).*(<\/name>)/\1${newname}\2/" $new_xml sed -ri "s/(<uuid>).*(<\/uuid>)/\1${uuid}\2/" $new_xml mem_kb=$((${newmemary}*1024*1024)) sed -ri "s/(<memory.*>).*(<\/memory>)/\1${mem_kb}\2/" $new_xml sed -ri "s/(<currentMemory.*>).*(<\/currentMemory>)/\1${mem_kb}\2/" $new_xml sed -ri "s/(<vcpu.*>).*(<\/vcpu>)/\1${newcpu}\2/" $new_xml sed -ri "s/(<source file=').*('\/>)/\1${new_path_sed}\2/" $new_xml mac_addr=26:ce:02 sed -ri "s/(<mac address='..:..:..:).*('\/>)/\1${mac_addr}\2/" $new_xml } #define define_vir_single(){ virsh define $new_xml echo "**********" echo "${newname}建完成!" echo "**********" } #------------運行分界線------------------------------------ echo "1)single" echo "2)group" read -p "選擇你的操做:" str case $str in single) get_newname get_newmemary get_newcpu set_xml_args_single copy_model_xml modification_xml sed -ri "s/(<mac address='..:..:..:).*('\/>)/\1$1\2/" $new_xml define_vir_single ;; group) set_group_name get_newmemary get_newcpu for((i=1;i<=${vir_num};i++)) do set_xml_args ${name[${i}]} $newmemary $newcpu copy_model_xml modification_xml define_vir_single done ;; *) exit ;; esac
運行方法centos7
bash /root/lxd/kvm3.sh e9:44:1e mac地址要和模板虛擬機的mac地址保持一致