KVM应用
1、克隆
nginx
tomcat
mysql
…
方案1:
node完成初始化的centos7,满足公司内部环境的需求;
满足线上条件,还需要做安全方面的设置。
使用node克隆出所有的虚拟机,然后使用服务的一键安装脚本进行软件部署。
方案2:用这个!
node–第一代模板机
克隆
nginx-temp tomcat-temp mysql-temp …
第二代模板机
用第二代模板机,克隆出需要的节点
操作步骤:
(1)制作二代模板机
(2)使用二代模板机克隆出需要的节点
修改虚拟机的IP 主机名
修改虚拟机的CPU和内存
(3)单机一键启动和关闭
(4)分发虚拟机
(5)虚拟机的启动控制脚本
sshpass
(1)制作二代模板机
手动克隆:virt-clone -o 模板机名字 -n 虚拟机名字 -f 虚拟机的存储文件的绝对路径
虚拟机必须是关机状态!!!
[[email protected] ~]# virsh shutdown node
[[email protected] ~]# virsh list
[[email protected] ~]# virt-clone -o node -n nginx-temp -f /kvm/nginx-temp.qcow2
[[email protected] ~]# virt-clone -o node -n tomcat-temp -f /kvm/tomcat-temp.qcow2
[[email protected] ~]# virt-clone -o node -n mysql-temp -f /kvm/mysql-temp.qcow2
[[email protected] ~]# virsh start nginx-temp
[[email protected] ~]# virsh start tomcat-temp
[[email protected] ~]# virsh start mysql-temp
console连接,修改IP
xshell连接,运行nginx、tomcat、mysql的一键安装脚本。
使用二代模板机之前,你要把所有需要准备的东西都想好。
[[email protected] ~]# virsh list --all
Id Name State
----------------------------------------------------
- mysql-temp shut off
- nginx-temp shut off
- node shut off
- tomcat-temp shut off
(2)使用二代模板机克隆出需要的节点
修改虚拟机的IP 主机名
修改虚拟机的CPU和内存
构建一个节点信息表格。
虚拟机的命名
阶段-功能IP地址最后一位
阶段:DEV UAT PDT
nginx11
nginx12
开始克隆:
脚本1:批量克隆
#!/bin/bash
##批量克隆
rundir=`pwd`
file="${rundir}/vmfile.txt"
qcowdir="/kvm"
while read line
do
vmname=$(echo $line | awk '{print $1}')
defaultname=$(echo $line | awk '{print $2}')
virt-clone -o ${defaultname} -n ${vmname} -f ${qcowdir}/${vmname}.qcow2
done < ${file}
#同步写入,讲内存中的存入硬盘
sync
sleep 2
virsh list --all
vmfile.txt
这个文件的内容
UAT-nginx120 nginx-default
UAT-nginx121 nginx-default
UAT-tomcat130 tomcat-default
UAT-tomcat131 tomcat-default
UAT-MySQLA mysql-default
UAT-MySQLB mysql-default
UAT-NFS1 node
UAT-NFS2 node
脚本2:批量修改硬件配置CPU内存
#!/bin/bash
##修改CPU内存等
rundir=`pwd`
file="${rundir}/vm-CPU.txt"
conf="/etc/libvirt/qemu"
#vm-CPU.txt文件内容
#虚拟机名字 CPU 内存
while read line
do
vmname=$( echo ${line} | awk '{print $1}')
vmcpu=$( echo ${line} | awk '{print $2}')
vmmemory=$( echo ${line} | awk '{print $3}')
#修改cpu
sed -r -i "/vcpu/s/[0-9]+/${vmcpu}/" ${conf}/${vmname}.xml
#修改内存
sed -r -i "/emory/s/K/G/" ${conf}/${vmname}.xml
sed -r -i "/emory/s/[0-9]+/${vmmemory}/" ${conf}/${vmname}.xml
#重启
virsh define ${conf}/${vmname}.xml
done < vm-CPU.txt
vm-CPU.txt
文件内容
UAT-nginx120 2 1
UAT-nginx121 2 1
UAT-tomcat130 2 1
UAT-tomcat131 2 1
UAT-MySQLA 1 2
UAT-MySQLB 1 2
UAT-NFS1 1 2
UAT-NFS2 1 2
脚本3:批量修改IP主机名
两种方法实现:
:方法1:guestmount
#!/bin/bash
#修改IP
mountdir="/mnt/gmount"
rundir=`pwd`
vmfiles="${rundir}/vmiphost.txt"
#vmiphost.txt文件的内容
#虚拟机名 虚拟机hostname 虚拟机IP
if [ ! -f ${vmfiles} ]
then
echo "主机列表文件不存在"
exit
fi
#创建挂载点
[ ! -d ${mountdir} ] && mkdir ${mountdir}
#关机
while read line
do
vmname=$(echo $line | awk '{print $1}')
virsh shutdown ${vmname} &> /dev/null
done < ${vmfiles}
echo "关机完成"
#挂载 并修IP主机名
while read line2
do
vmname2=$(echo $line2 | awk '{print $1}')
vmhost=$(echo $line2 | awk '{print $2}')
vmIP=$(echo $line2 | awk '{print $3}')
[ "${rundir}" == "${mountdir}" ]
if [ $? -ne 0 ]
then
umount ${mountdir} &> /dev/null
echo "取消挂载完成。"
fi
#挂载
guestmount -d ${vmname2} -i ${mountdir}
#修改IP
sed -i '/IPADDR/d' ${mountdir}/etc/sysconfig/network-scripts/ifcfg-ens3
sed -i '/NETMASK/iIPADDR='"${vmIP}"'' ${mountdir}/etc/sysconfig/network-scripts/ifcfg-ens3
echo "IP ok!"
#修改主机名
echo "${vmhost}" > ${mountdir}/etc/hostname
echo "hostname ok"
umount ${mountdir}
done < ${vmfiles}
vmiphost.txt
内容
UAT-nginx120 UAT-nginx120 172.16.12.120
UAT-nginx121 UAT-nginx121 172.16.12.121
UAT-tomcat130 UAT-tomcat130 172.16.12.130
UAT-tomcat131 UAT-tomcat131 172.16.12.131
UAT-MySQLA UAT-MySQLA 172.16.12.140
UAT-MySQLB UAT-MySQLB 172.16.12.141
UAT-NFS1 UAT-NFS1 172.16.12.150
UAT-NFS2 UAT-NFS2 172.16.12.151
guestmount原理,其实虽然要关机操作,但是实际上guestmount启动了一个名字叫guestfs的虚拟机
[[email protected] chiphost]# virsh list
Id Name State
----------------------------------------------------
4 guestfs-9zmmx8rerf26wdle running
然后它的文件系统就在挂载点下了。
[[email protected] chiphost]# mount | grep /mnt/gmount
/dev/fuse on /mnt/gmount type fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
[[email protected] chiphost]# cd /mnt/gmount/
[[email protected] gmount]# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
这个就是根目录嘛。。
取消挂载后自动关掉guest虚拟机
[[email protected] mnt]# umount /mnt/gmount/
[[email protected] mnt]# virsh list
Id Name State
----------------------------------------------------
方法2:virt-copy-in
这个方法就完全是冷处理里,非开机状态。
#!/bin/bash
##用virt的方法修改IP和主机名
rundir=`pwd`
vmfile="${rundir}/vm-iphostlist.txt"
ipfile="${rundir}/ifcfg-ens3"
hostfile="${rundir}/hostname"
qcow2dir="/kvm"
#vm-iphostlist.txt文件内容
#虚拟机名字 虚拟机hostname 虚拟机IP
count=$(wc -l < ${vmfile})
echo "项目有${count}个虚拟机"
num=1
while read line
do
vmname=$(echo $line | awk '{print $1}')
vmhost=$(echo $line | awk '{print $2}')
vmip=$(echo $line | awk '{print $3}')
echo "修改第${num}个主机--${vmname}。"
#主机名
echo ${vmname} > ${hostfile}
virt-copy-in ${hostfile} -a ${qcow2dir}/${vmname}.qcow2 /etc/
#IP
sed -r -i "/^IPADDR/s/IPADDR=.*/IPADDR=${vmip}/" ${ipfile}
virt-copy-in ${ipfile} -a ${qcow2dir}/${vmname}.qcow2 /etc/sysconfig/network-scripts/
let num++
done < ${vmfile}
vm-iphostlist.txt
内容
UAT-nginx120 UAT-nginx120 172.16.12.120
UAT-nginx121 UAT-nginx121 172.16.12.121
UAT-tomcat130 UAT-tomcat130 172.16.12.130
UAT-tomcat131 UAT-tomcat131 172.16.12.131
UAT-MySQLA UAT-MySQLA 172.16.12.140
UAT-MySQLB UAT-MySQLB 172.16.12.141
UAT-NFS1 UAT-NFS1 172.16.12.150
UAT-NFS2 UAT-NFS2 172.16.12.151
ifcfg-ens3
文件内容
# Generated by dracut initrd
NAME="ens3"
DEVICE="ens3"
ONBOOT=yes
NETBOOT=yes
IPV6INIT=yes
BOOTPROTO=static
TYPE=Ethernet
IPADDR=172.16.12.151
NETMASK=255.255.0.0
GATEWAY=172.16.0.254
DNS1=8.8.8.8
hostname
文件内容
UAT-NFS2
其实这个原理就很好解释了在宿主机写好配置文件,然后拷贝并覆盖KVM虚拟机的相应文件达到相应的效果。所以这个网卡配置文件和主机名配置文件内容都是随机改变的。
(3)单机一键启动和关闭
这个没什么好说的注意启动的顺序就好了。
启动
#!/bin/bash
##一键启动虚拟机集群
rundir=`pwd`
file="${rundir}/start.txt"
qcowdir="/kvm"
num=1
while read vmname
do
virsh start ${vmname} &> /dev/null
echo "第${num}个虚拟机${vmname}--start"
sleep 3
let num++
done < ${file}
start.txt
内容
UAT-NFS1
UAT-NFS2
UAT-MySQLA
UAT-MySQLB
UAT-tomcat130
UAT-tomcat131
UAT-nginx120
UAT-nginx121
关机
#!/bin/bash
##关闭虚拟机集群
rundir=`pwd`
file="${rundir}/shutdown.txt"
num=1
while read vmname
do
virsh shutdown ${vmname} &> /dev/null
echo "第${num}个虚拟机${vmname}--shutdown"
sleep 3
let num++
done < ${file}
shutdown.txt
内容
UAT-nginx120
UAT-nginx121
UAT-tomcat130
UAT-tomcat131
UAT-MySQLA
UAT-MySQLB
UAT-NFS1
UAT-NFS2
(4)分发虚拟机
冷迁移:在虚拟机处于关机状态进行迁移操作。
虚拟机的配置文件和存储文件 scp
qcow2格式的存储文件:
优点:用多少,占多少;
缺点:一直写新块。
解决:
细致化分区。
mysql /var – rpm 创建一个新的lv mount
/data – bin 创建一个新的lv mount
压缩存储文件:
[[email protected] kvm]# qemu-img convert -c -O qcow2 UAT-NFS2.qcow2 UAT-NFS2_Y.qcow2
convert 压缩
-c 创建新的文件
-O 指定格式
UAT-NFS2.qcow2 原始文件
UAT-NFS2_Y.qcow2 压缩后的文件
压缩需要一段时间
[[email protected] kvm]# ls -lh UAT-NFS2.qcow2 UAT-NFS2_Y.qcow2
-rw------- 1 root root 1.2G Dec 19 19:07 UAT-NFS2.qcow2
-rw-r--r-- 1 root root 536M Dec 20 02:32 UAT-NFS2_Y.qcow2
可以看到 新生成的小了很多。
变少的原因就是释放了块,因为qcow2会不断的写新的块,所以即使删除虚拟机的文件时使虚拟机整体的大小减少,也不能将宿主机上虚拟机文件的大小降低。
举个例子:安装完系统的虚拟机有1G,此时宿主机上qcow2文件有1G多点。虚拟机又下载了1个1G的文件,此时宿主机上qcow2文件大小变为了2G多点。然后删除虚拟机上的这个1G文件,虚拟机又变为1G了,但是宿主机上的qcow2文件依旧是2G多点,并不会清掉,因为是会写新的块。
然后修改下文件的名字并备份旧的:
[[email protected] kvm]# mv UAT-NFS2.qcow2 UAT-NFS2.qcow2.bak ; mv UAT-NFS2_Y.qcow2 UAT-NFS2.qcow2
[[email protected] kvm]# ls -lh UAT-NFS2.qcow2 UAT-NFS2.qcow2.bak
-rw-r--r-- 1 root root 536M Dec 20 02:32 UAT-NFS2.qcow2
-rw------- 1 root root 1.2G Dec 19 19:07 UAT-NFS2.qcow2.bak
然后启动UAT-NFS2虚拟机
[[email protected] kvm]# virsh start UAT-NFS2
[[email protected] kvm]# virsh console UAT-NFS2
压缩后的机器能正常登陆和做一些操作就是OK的
UAT-NFS2 login: root
Password:
Last login: Thu Dec 19 06:10:27 from 172.16.12.1
[[email protected] ~]#
[[email protected] ~]# ls
anaconda-ks.cfg original-ks.cfg
[[email protected] ~]# ifconfig
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.12.151 netmask 255.255.0.0 broadcast 172.16.255.255
然后就可以关掉机器删除旧的了。
[[email protected] kvm]# rm -f UAT-NFS2.qcow2.bak
开始分发:
把UAT-MySQLA从宿主机172.16.12.103迁移到宿主机172.16.12.102:
就拷贝2个文件就好了。
[[email protected] kvm]# scp /etc/libvirt/qemu/UAT-NFS2.xml 172.16.12.102:/etc/libvirt/qemu/
[[email protected] kvm]# scp UAT-NFS2.qcow2 172.16.12.102:/kvm/
对端机器要安装kvm要能修改kvm系列软件
[[email protected] qemu]# virsh define UAT-NFS2.xml
重新定义UAT-NFS2.xml配置文件
然后就可以直接启动了
[[email protected] qemu]# virsh start UAT-NFS2
[[email protected] qemu]# virsh console UAT-NFS2
注:MySQL的特殊处理
克隆是完完全全的一样,但是mysql有个UUID是唯一标识,所以要删除这个文件然后重启服务重新生成这个UUID才行
mysql
[[email protected] data]# cat auto.cnf
[auto]
server-uuid=b2f5956e-2161-11ea-bf03-525400b78919
克隆或冷迁移之后,这个文件要删掉!!!
克隆后虚拟机的UUID冲突:
虚拟机提示 UUID 冲突
[[email protected] qemu]# virsh define UAT-MySQLA.xml
error: Failed to define domain from UAT-MySQLA.xml
error: operation failed: domain 'UAT-MySQLA' already exists with uuid 43d902b6-2912-486b-89c2-436af326ad91
并且virsh edit
不能修改
[[email protected] qemu]# virsh edit UAT-MySQLA
error: operation failed: domain 'UAT-MySQLA' already exists with uuid 43d902b6-2912-486b-89c2-436af326ad91
Failed. Try again? [y,n,i,f,?]: 输入n
error: operation failed: domain 'UAT-MySQLA' already exists with uuid 43d902b6-2912-486b-89c2-436af326ad91
那就备份一下这个配置文件,然后undefine删除配置文件,拷回备份的文件,vim修改就好,然后再重新define定义。
[[email protected] qemu]# cp UAT-MySQLA.xml /tmp/
[[email protected] qemu]# virsh undefine UAT-MySQLA
[[email protected] qemu]# cp /tmp/UAT-MySQLA.xml .
[[email protected] qemu]# vim UAT-MySQLA.xml
将UUID改成和原来不一样就行。
[[email protected] qemu]# virsh define UAT-MySQLA.xml