前言

所思即所见,所见即所得,所得皆所想,技术从未停歇,也未曾缺乏。

目录

云计算

虚拟化技术入门

QEMU-KVM 基础

安装在CentOS

rpm -qa |grep qemu yum install qemu-kvm yum install libvirt -y yum install virt-install virt-manager

创建第一台虚拟机

// 创建系统盘镜像存储文件 dd if=/dev/zero of=kvm1.img bs=1M count=4096 ln -s /usr/libexec/qemu-kvm/sbin /sbin yum install tigervnc -y // 启动虚拟机并开始安装GuestOS qemu-kvm -hda kvm1.img -cdrom /xxxx.iso -boot order=cd,once=d -vnc 0.0.0.0:0 // 放行防火墙的访问端口 netstat -tupln firewall-cmd --list-all firewall-cmd --add-service=vnc-server // 在CentOS图形界面中,用vncviewer工具进入虚机操作界面 vncviewer :0

虚拟机的配置

cpu配置

// SMP多对称处理器:多个CPU通过一个总线访问内存,SMP支持的CPU个数有限 // NUMA独立内存多处理器:每个处理器有自己的内存,每个处理器也可以访问别的处理器内存 // GuestOS lscpu // n:VCPU数量,默认为1 // maxcpus:最大使用的cpu数量,配合cpu热插拔机制 // threads per core:每个core线程数量 // cores per socket:每个cpu的core数量 // sockets:cpu插槽数量 // VCPU=sockets*cores*threads qemu-kvm -smp 2,maxcpus=3,cores=1,sockets=1 -cpu SandyBridge test.qcow2 -monitor stdio -vnc 0.0.0.0:0 //不加任何CPU参数 lscpu // 内存配置,如果不加内存配置则默认为128M qemu-kvm -m 2048 test.qcow2 -monitor stdio -vnc 0.0.0.0:0 dmesg | grep Memory

存储配置

qemu-kvm -hda file -fda file -cdrom file // hda:指定虚拟机第一块硬盘,表现为/dev/hda或/dev/sda,对应可以为磁盘镜像文件,也可以为宿主机的存储设备文件 // hdb、hdc:指定虚拟机中的第二、第三块硬盘 // fda:指定虚拟机中的第一个软驱 // cdrom:指定虚拟机的光驱,是GuestOS中的第三个IDE设备,不能和hdc同时使用 // mtdblock:虚拟机中的flash存储器 // sd:虚拟机中的sd卡 qemu-kvm -drive option,[option],[option]....... qemu-kvm -m 2048 -drive file=kvm1.img snapshot=on -vnc 0.0.0.0:0 -monitor stdio // file= 指定磁盘镜像文件名,或存储设备文件名 // if= 指定存储驱动器的接口类型(如ide、scsi (目录qemu版本不支持)、virtio) // bus= 指定存储驱动器的总线编号 // unit= 指定存储驱动器的单元编号 // index= 同-一种接口驱动器的索引编号 // media= 设置存储驱动器中媒介的类型(disk、cdrom) // snapshot= 可选值为( on,ff),当值为on时,不会将更改、新增的数据回写到磁盘镜像文件中,而是写到一个临时文件中。默认为off. 可以在monitor中,使用commit命令强制回写 // format= 指定磁盘的格式,默认情况下由qemu自动识别。如: qcow2,vmdk,raw // serial= 分配给设备的序列号 // addr=存储控制器的PCI地址 // id=设置驱动器id // readonly= on|off 是否只读 // cache= cache访问方式,可先值为(none, write back, writethrough) // 默认值: writethrough, (直写模式)数据直接写入磁盘里,不使用缓存,在数据更新时,同时写入Guest os Pagecache和后端块设备。 // writeback: (回写模式)在数据更新时只写入Guest os和宿主机os的PageCache。只在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。此模式的优点是数据写入速度快,因为不需要写存,缺点是一旦更新后的数据未被写入存储时出现系统掉电的情况,数据将无法找回。 // none:这种模式作用在Guest OS Pagecache和物理磁盘Cache中,相当于虚拟机能直接访问宿主机的磁盘,性能不错! // 性能上:writeback > none > writethrough; 安全上:writeback < none < writethrough qemu-kvm -boot [order=drives],[once=drives],[menu=on|off] qemu-kvm -m 2048 -hdb kvml. ing -hda kvm2. img -hdd data.img -cdrom /root/kvmlab/iso/Cent0S-7-x86_64-DVD-2009.iso -vnc 0.0.0.0:0 -monitor stdio // drives:a:第一个软驱, b:第二个软驱, c:第一块硬盘, d:光驱,n:网络启动 // order:设定启动顺序,如设成order=dc,即先从光驱启动,再从第-块硬盘启动。 // once:设定第一次的启动顺序 , 重启后失效。 // menu:启用交互式启动菜单

磁盘镜像文件配置

// raw:原始磁盘镜像格式,qemu-img的默认格式 // qcow2:支持稀疏文件、AES加密与快照 // vdi:virtualbox的镜像文件格式 // vmdk:vmware的镜像文件格式 // vpc:微软的virtual pc镜像文件格式 qemu-img [command] [-o options] qemu-img create -f qcow2 test1.qcow2 qemu-img info test1.qcow2 qemu-img create -f qcow2 -b test1.qcow2 test2.qcow2 qemu-img commit test2.qcow2 qemu-img convert -O qcow2 kvmlab.vmdk kvmlab1.qcow2 qemu-img snapshot -c snap1 test1.qcow2 qemu-img snapshot -l test1.qcow2 qemu-img snapshot -a sanp1 test1.qcow2 qemu-img resize test1.qcow2 +1G // check 对镜像文件进行检查,查找镜像文件中的错误,目前只支持qcow2、qed、vdi格式 // create [-f fmt][-o option] filename [size] 创建镜像文件,-f镜像文件格式(如raw、qcow2),-b指定backing_file(这个镜像文件只记录与backing_file差异的部分),-o选项(如backing_file),Size指定文件大小(如M、G、T) // commit [-f fmt] filename 提交filename中的内容到backing_file中 // convert [-c] [-f fmt] [-O output_fmt] [-o option] filename outputfilename镜像文件格式转换,-c:压缩,-f:源文件格式,-0:输出文件格式,Filename:源文件名,Ouputfilename:输出文件名 // info filename 显示镜像文件信息 // snapshot [-l|-a snapshot |-c snapshot |-d snapshot] filename,-l列出所有快照,-a使用一个快照,-c创建一个快照,-d删除一个快照 // resize filename [+|-]size,增加、减小镜像文件的大小(qcow2格式不支持减小空间)

网络配置

1.桥接(bridge) 将虚拟机的网卡桥接到宿主机的物理网卡。虚拟机和宿主机处于同一个网络内,使用同一个网段。相当于将虚拟机的网卡和宿主机的网卡接在同一台二层交换机上

yum install bridge-utils tunctl lsmod |grep tun modprobe tun brctl show

新建一个bridge(br0)

// vim /etc/sysconfig/network-scripts/ifcfg-br0 // Ifcfg-br0文件配置内容 DEVICE=brO TYPE=Bridge BOOTPROTO=static IPADDR=192.168.0.198 PREFIX=24 GATEWAY=192.168.0.1 DNS=114.114.114.114 ONBOOT=yes

修改宿主机物理网卡配置

// vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no BOOTPROTO=static DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=yes IPV6_AUTOCONF=yes IPV6_DEFROUTE=yes IPV6_FAILURE_FATAL=no IPV6_ADDR_GEN_MODE=stable-privacy NAME=ens33 UUlD=ac25a1e2-258c-42c9-aa11-f5565b3474d9 DEVICE=ens33 ONBOOT=yes #IPADDR=192.168.0.197 #将此行注释掉 #PREFIX=24 #将此行注释掉 #GATEWAY=192.168.0.1 #将此行注释掉 #DNS1=114.114.114.114 #将此行注释掉 BRIDGE=brO #新增此行 systemctl restart network

虚拟机配置命令

qemu-kvm -net nic -net tap,script=filename test1.qcow2 // -net tap: 添加一块tap虚拟网络设备(用于连接虚拟机的网卡) // -net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostforce=on|off] // vlan: 配置加入的vlan号 // ifname: 指定tap设备的名称 // script: 指定启动虚机时宿主机执行的脚本(默认为/etc/qemu-ifup)

创建/etc/qemu-ifup脚本

#!/bin/bash brctl addif br0 $1 // downscript: 虚拟机关闭时执行的脚本(非以要)

2.NAT 宿主机需要两块网卡,一块网卡连接物理网络,另一块网卡(通常是虚拟网卡)和虚拟机网卡做桥接。虚拟机需通过宿主机的NAT功能,转发数据包。这时宿主机相当一台NAT路由器

新建一个桥br1,用于连接虚拟机的网卡(跟桥接模式一样)

// vim /etc/sysconfig/network-script/ifcfg-br1 DEVICE=br1 TYPE=Bridge BOOTPROTO=static IPADDR=192.168.100.254 PREFIX=24 ONBOOT=yes // 修改br1的IP地址为192.168.100.254(根据环境不同自己配置) systemctl restart network ifconfig

宿主机安装DHCP软件(建议使用dnsmasq)

yum install dnsmasq // 配置/etc/dnsmasq.conf文件内容 Interface=br1 dhcp-range=192.168.100.100,192.168.100.200,255.255.255.0,12h dhcp-option=option:router,192.168.100.254 dhcp-option=option:dns-server,114.114.114.114 // 放通宿主机防火墙DHCP服务 firewall-cmd --add-service=dhcp

创建/etc/qemu-ifup-NAT脚本(参考桥接配置)

#!/bin/bash ip link set $1 up brctl addif br1 $1

启动虚拟机

qemu-kvm -m 2048 -net nic -net tap,script=/etc/qemu-ifup-NAT test1.qcow2 -vnc 0.0.0.0:0 // 此时虚拟机应该已成功获取到IP地址、网关、DNS,已经可以和宿主机br1连通。但是还无法访问外网。

开启宿主机的数据包转发功能

// vim /etc/sysctl.conf net inv4 in forward = 1 // 立即应用配置 sysctl -p

NAT配置

iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE // 将宿主机当成一个NAT网关,虚拟机只有通过宿主机地址转换后才能访问外网。

3.qemu内部的用户模式,完全由qemu模拟出来的一种网络模式,性能相对较差。

Libvirt 基础

// libvirt安装 yum install libvirt -y // 给node添加别名,vim /etc/libvirt/libvirt.conf uri_aliases = ["lib198=qemu+ssh://192.168.0.198/system","lib197=qemu+ssh://192.168.0.197/system"] // domain配置文件存储目录: /etc/libvirt/qemu/XX.xml // 安装图形化管理工具: virt-manager yum install virt-manager -y // 在图形界面里启动: virt-manager

virsh 常用命令

list -all :列出所有虚拟机 start xxx: 启动虚拟机 reboot xxx: 重启虚拟机 reset xxx: 强制重启虚拟机 shutdown xxx: 关闭虚拟机 destory <id>: 销毁一个虚拟机,相当于拨掉虚拟机的电源线 domstate --domain xxx: 列出指定域的运行状态 domstats --domain xxx: 列出指定域的详细信息 dominfo --domain xxx: 列出指定域的基本信息 dommemstat --domain xxx: 列出指定域的内存使用情况 setmem --domain xxx <size>: 设置指定域的内存大小 vcpuinfo --domain xxx: 列出指定域的VCPU信息 vcpupin --domain xxx <vcpu> <pcpu>: 将虚机的CPU绑定到物理CPU上 setvcpus --domain xxx <num>: 设定域的VCPU数量 vncdisplay --domain xxx: 获取VNc监听地址和端口 create <xml>: 根据xml创建一个新的域 save -domain xxx <xx.img>: 保存一个运行中的域的状态到一 个文件中 snapshot-create: 创建一个快照 snapshot-revert: 恢复到一个快照 restore <xx.img>: 从一个文件中恢复一个域的运行状态 migrate <id> <des-url>: 迁移一个域到其它节点 dumpxml <id>: 将一个域的配置文件输出到屏幕上 edit <id>: 编辑一个域的配置文件 sysinfo: 宿主机系统信息 nodeinfo: 节点基本信息

virt-install 应用

// 利用libvirt API接口创建虚拟机。

virt-install --connect URI <option> <option> ... virt-install \ --name test3 \ --memory 1024,maxmemory=2048 \ --vcpus 1,maxvcpus=2 \ --cdrom /root/kvmlab/ iso/Cent0S-7-x86_64-DVD-2009.iso \ --disk /root/kvmlab/img/test3.qcow2,size=10 \ --network bridge=br0 \ --graphics vnc,password=123,port=5900,listen=0.0.0.0 // --connect URI: 连接到指定虚拟化系统( qemu+ ssh://dest-ip/system) // --name xx: 虚拟机(域)的名称 // --memory xx,maxmemory=xxx: 配置内存和最大内存 // --vcpus xx,maxvcpus=x,cpuset=x,x,x,sockets=x,cores=x,threads=x,配置VCPU数量、最大数量、绑定的物理,sockets、cores、threads // --cdrom: 配置光驱 // --import: 使用一个已存在的磁盘镜像文件创建虚拟机 // --boot hd,cdrom: 配置虚拟机的启动顺序 // --disk(配置存储设备) size=xx(默认单位: G),<imgfile path>(镜像文件路径),device=disk|cdrom|floppy(指定设备类型,默认为disk) // --network(配置网络) bridge=(配置桥接到指定的桥),network=(指定虚拟网络),mode=e1000|rtl8139|virtio(指定网卡类型) // --graphics (配置图形接口) vnc,password=xxx,port=xxx,listen=xxx,使用vnc并配置登入密码,监听端口中,监听IP;spice,password=xxx,port=xxx,listen=xxx,使用vnc,并配置登入密码,监听端口中,监听IP // virt-top: 在宿主机上查看虚拟机的运行情况,资源利用率

virtio 应用

virtio基本概念

基于希望解决软件虚拟化性能上的损失,提出了一项解决方案,改动GuestOS的代码,使它以为自己是运行在虚拟化环境中,可于虚拟系统协同工作。这种方法称为准虚拟化(半虚拟化)。KVM系统是基于硬件虚拟化(如intel-VT AMD-V)的系统,CPU的运行效率是相当高的。如果硬件支持Intel EPT特性(扩展页表,intel第二代硬件虚拟化技术)的,内存的运行效率也会非常高。但其它I/O设备(如硬盘、网卡等),KVM系统是使用qemu纯软件模拟的方式,效率较为低下。KVM系统为解决I/0设备效率低下的问题,采用了virtio技术。virtio是一个半虚拟化技术,需要修改GuestOS代码。一般较新的linux系统都内置了virtio模块,但windows系统需另外安装virtio驱动。

Linux GuestOS virtio

查看宿主机是否已加载了virtio模块: find /lib/modules/3.10.0-1160.el7.x86_64/ -name "virtio*"

将网卡和磁盘类型设置成virtio

virsh edit xxx 修改 disk.target.bus=ide为virtio,disk.address.type=drive为pci,并删除后面的controller等(系统会自动生成) 修改 interface.model.type=rtl8139为virtio

进入虚拟机查看pci设备信息:lspci

Windows GuestOS virtio

在宿主机中安装windows virtio驱动:yum install virtio-win

在以下目录里会生成windows virtio驱动的iso包:/usr/share/virtio-win/virtio-win-0.1.171.iso

将windows virtio驱动iso包挂载到虚拟机的cdrom中

virsh edit xxx <source file='/usr/share/virtio-win/virtio-win-0.1.171.iso'/> 修改 disk.target.bus=ide为virtio,disk.address.type=drive为pci,并删除后面的controller等(系统会自动生成) 修改 interface.model.type=rtl8139为virtio

解决无法启动windows guestos问题的小技巧:

1.先将windows虚拟机的引导磁盘hda模式改回ide

2.另外添加一抉磁盘,把磁盘模式设为virtio

qemu-img create -f qcow2

edit xxx,在配置文件中添加这块新磁盘hdb,并将模式设为virtio

3.将virtio-win iso包挂载到虚拟机hdc中

attach-disk win7 /root/kvmlab/iso/virtio-win-0.1.171.iso hdc --type cdrom

4.启动系统,在guestos windows计算机管理的设备管理器中,其他设备(PCI设备、SCSI设备、以太网控制器设备)安装virtio驱动,更新驱动然后浏览cdrom

5.关机,再将引导磁盘改为virtio,即可正常启动系统

virt-install 安装一台新 guestos windows 自带 virtio 驱动
virt install \ name win7 \ --vcpus 3 \ --memory 4096 \ --disk /root/kvmlab/img/win7.qcow2,size=20,bus=virtio \ --cdrom /root/kvmlab/iso/windows7.iso \ --network bridge=br0,model=virtio \ --graphics vnc,port=5901,listen=0.0.0.0

替换windows iso安装包为 virtio iso安装包:attach-disk win7 /root/kvmlab/iso/virtio-win-0.1.171.iso hda --type cdrom

在windows安装界面加载驱动程序,在安装包的viostor文件夹中,w7/amd64/

安装完virtio驱动后,再替换为 windows iso包:attach-disk win7 /root/kvmlab/iso/windows.iso hda --type cdrom

继续剩下安装,分区等...

进入guest windows系统中,查看计算机管理-设备管理器,磁盘驱动器已经安装virtio,在其他设备中手动安装PCI设备和以太网控制器设备(再一次切换hda cdrom)

内存气球技术应用(balloon内存热插拔)

通常我们要修改虚拟机的内存大小,需要将虚拟机关机。balloon提供了一种在线调整虚拟机内存大小的机制。balloon需要在qemu-monitor中进行配置和监控。

查看balloon大小: virsh qemu-monitor-command <domain> --hmp info balloon

设置balloon大小: virsh qemu-monitor-command <domain> --hmp balloon <size>

设置balloon的最大内存无法超过maxmemory大小

虚拟机迁移

NFS作为共享存储的用例,节点规划

Node1: 192.168.0.197 安装KVM组件,挂载NFS共享存储

Node2: 192.168.0.198 安装KVM组件,挂载NFS共享存储

共享存储: 192.168.0.129 安装NFS,配置共享资源

// 安装NFS yum install nfs-utils // 创建共享目录 mkdir kvmpool // 配置并启动NFS vim /etc/exports /root/kvmpool *(rw,sync,no_root_squash) // 重启rpcbind服务,并将rpcbind服务设置为开机自启动 systemctl restart rpcbind systemctl enable rpcbind // 启动NFS服务,并将NFS服务设置为开机自启动 systemctl start nfs-server systemctl enable nfs-server // 放通防火墙相关服务 firewall-cmd --add-service=rpc-bind firewall-cmd --add-service=rpc-bind --permanent firewall-cmd --add-service=nfs firewall-cmd --add-service=nfs --permanent firewall-cmd --add-service=mountd firewall-cmd --add-service=mountd --permanent // 到node1和node2上查看NFS共享信息 showmount -e 192.168.0.129 #Export list for 192.168.0.129: #/root/kvmpool * // 在node1和node2_上创建用来挂载NFS的目录 mkdir nfs // 在node1和node2_上挂载NFS共享目 mount -t nfs 192.168.0.129:/root/kvmpool ./nfs // 让内核重新生成挂载信息 partprobe // 查看挂载情况 df -h // 将NFS共享挂载写入分区配置文件 vim /etc/fstab 192.168.0.129:/root/kvmpool /root/kvmlab/img/nfs nfs defaults 0 0 // 配置/etc/hosts 文件 192.168.0.198 kvm198 kvm198.localdomain 192.168.0.197 kvm197 kvm197.localdomain // 配置/etc/libvirt/libvirt.conf uri_aliases=["lib198=qemu+ssh://192.168.0.198/system","lib197=qemu+ssh://192.168.0.197/system"] // 在node1的nfs目录下创建一个虚拟机 virt-install ... 修改虚拟机的磁盘cache选项为none,writeback和writethrough模式不支持动态迁移 // 虚拟机迁移 virsh migrate <domain> --desturi <desturi> --persistent --undefinesource --offline // --desturi:迁移目的URI,如(qemu+ssh://192.168.0.198/system) // --persistent:永久迁移(会将虚拟机的配置文件复制到迁移目的节点) // --undefinesource:在源节点中反定义虚拟机(删除源节点中的虚拟机配置文件) // --live:虚拟机在线迁移(动态迁移) // --offlie:虚拟机离线迁移(静态迁移),必须跟上--persistent