前言:
近些年一直听着 虚拟化、云计算、公有云、私有云、混合云这些个概念,一直想着....这些概念要用什么技术实现?
一、云计算的概念
1.传统IDC机房面都会临什么问题?
任何新事物都是由需求催生的,之前网站上线基本上会有以下几种选择:
IDC托管:买台服务托管到IDC机房---》安装系统----》部署应用---》域名备案------》上线
IDC租用:租用IDC机房提供的服务器
VPS:虚拟专用主机
以上传统的网站上线的模式有什么重大缺陷呢?
A.成本高 (IDC托管、租用费用费用很高)
B.自动化能力差 事多、麻烦(买了/租了服务器还要装系统、部署代码,是否会被网络攻击)
2.云计算是什么?
把总多服务器的资源通过虚拟化的技术手段熔化成一个资源池 (云)
用户以网络的方式 按需获取资源池中的服务器资源,服务商按用户使用量公平收费; (计算)
是一种资源整合、按需消费、按需收费的商业模式; 让企业使用服务器资源就像 居民平时用水、用电一样简单;
3.云计算的层次
根据云提供的服务分为以下几个层次
Infrastructure as a service iaas Platforn as a service paas Software as a service saas
PS:也许你会听说过vaas(Video-as-a-service) 是建立在这3层之上的典型代表有乐视云;
4.云计算的分类
根据云面向的人群分为以下几类:
公有云:面向公众提供虚拟机、开发环境、服务(阿里云) 优点:技术安全可靠 缺陷:数据不安全
私有用:仅对一部分人/自己/公司内部员工使用(阿根云) 缺陷:技术问题自己解决 优点:数据安全
混合云:既使用公有云 也有自己的私有云(我们公司的) (综合私有云、公有云的优缺点)
二、虚拟化的概念
1.什么是虚拟化?
首先声 明 云计算 != 虚拟化,云计算的实现使用到了虚拟化这种技术手段;
虚拟化是指通过软件技术 把1个计算机的CPU、硬件 虚拟出很多虚拟机,这些虚拟机寄生在宿主机之上,功能和宿主机的功能无异, 但是彼此之间是隔离的;
三、KVM
KVM:需要硬件支持的虚拟化技术,从硬件层面实现隔离;(openstack默认使用的虚拟化技术就是KVM)
QEMU:QEMU和KVM一样是一种虚拟化软件;
QUEMU和KVM的区别:由于KVM是内核级虚拟化软件(能虚拟化出CPU和内存),磁盘、网卡虚拟不出来,于是KVM就是结合了QEMU实现了用户态的虚拟化;
1.虚拟环境准备
[root@localhost ~]# grep -E \'(vmx|svm)\' /proc/cpuinfo flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch arat tpr_shadow vnmi ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec
[root@localhost ~]# yum list|grep kvm Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast libvirt-daemon-kvm.x86_64 2.0.0-10.el7 @anaconda qemu-kvm.x86_64 10:1.5.3-126.el7 @anaconda qemu-kvm-common.x86_64 10:1.5.3-126.el7 @anaconda libvirt-daemon-kvm.x86_64 3.2.0-14.el7_4.5 updates oci-kvm-hook.x86_64 0.2-2.el7 epel pcp-pmda-kvm.x86_64 3.11.8-7.el7 base qemu-kvm.x86_64 10:1.5.3-141.el7_4.4 updates qemu-kvm-common.x86_64 10:1.5.3-141.el7_4.4 updates qemu-kvm-tools.x86_64 10:1.5.3-141.el7_4.4 updates
2.安装KVM
[root@localhost ~]# yum -y install qemu-kvm qemu-kvm-tools libvirt virt-install
3.启动librbd服务
libvirtd是管理KVM虚拟机的工具
[root@localhost ~]# yum update librbd1 [root@localhost ~]# systemctl start libvirtd [root@localhost ~]# systemctl enable libvirtd
当libvertd服务启动之后
系统会自动创建一个名为virbr0的桥接网卡,ip地址默认为192.168.122.1;
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255 ether 52:54:00:31:bf:a8 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
系统 自动启动dnsmasq进程该进程有DNS和DHCP的功能,给虚拟机动态分配IP地址并提供域名解析服务;
[root@localhost zhanggen]# ps -aux | grep dnsmasq nobody 1433 0.0 0.0 49532 1072 ? S 23:12 0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper root 1436 0.0 0.0 49504 348 ? S 23:12 0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper root 3727 0.0 0.0 112664 972 pts/0 R+ 23:19 0:00 grep --color=auto dnsmasq [root@localhost zhanggen]#
4.创建虚拟机
使用qemu-img给KVM虚拟机创建虚拟镜像文件
[root@localhost kvm_img]# qemu-img create -f raw /kvm_img/Centos-7-x86.raw 10G Formatting \'/kvm_img/Centos-7-x86.raw\', fmt=raw size=10737418240
新建了虚拟镜像文件就可以安装虚拟机了
virt-install --virt-type kvm --name Centos-7-x86_64 --ram 2048 --cdrom=/centos7iso/CentOS-7-x86_64-DVD-1611.iso --disk path=/kvm_img/Centos-7-x86.raw --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
然后使用TightVNC连接到服务器上给kvm虚拟机安装系统
在宿主机查看当前KVM实例列表
[root@localhost centos7iso]# virsh list --all Id 名称 状态 ---------------------------------------------------- 1 Centos-7-x86_64 running
通过宿主机启动1个 kvm实例
[root@localhost centos7iso]# virsh start Centos-7-x86_64 域 Centos-7-x86_64 已开始
kvm虚拟机启动之后,其实就是宿主机中的一个进程
[root@localhost zhanggen]# ps -ef | grep kvm root 482 2 0 3月15 ? 00:00:00 [kvm-irqfd-clean] qemu 8000 1 7 01:27 ? 00:01:53 /usr/libexec/qemu-kvm -name Centos-7-x86_64 -S -machine pc-i440fx-rhel7.0.0,accel=kvm,usb=off,dump-guest-core=off -cpu Broadwell,-hle,-rtm -m 2048 -realtime mlock=off -smp 1,sockets=1,cores=1,threads=1 -uuid fc152f09-9b09-4890-a316-3c2a5afb0e68 -no-user-config -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-2-Centos-7-x86_64/monitor.sock,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x5 -drive file=/kvm_img/Centos-7-x86.raw,format=raw,if=none,id=drive-virtio-disk0 -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -drive if=none,id=drive-ide0-0-0,readonly=on -device ide-cd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -netdev tap,fd=26,id=hostnet0,vhost=on,vhostfd=28 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:ca:24:4f,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -chardev socket,id=charchannel0,path=/var/lib/libvirt/qemu/channel/target/domain-2-Centos-7-x86_64/org.qemu.guest_agent.0,server,nowait -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 -device usb-tablet,id=input0,bus=usb.0,port=1 -vnc 0.0.0.0:0 -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 -msg timestamp=on
5.管理KVM虚拟机
在宿主机里面创建好了kvm实例,接下来就是对它们进行管理了,Red Hat引入了libvirt库作为管理平台虚拟化(hypervisor和VM)的一个API,openstack就是调用libvirt的API来管理KVM虚拟机的,
virsh是调用libvirt的客户端。
看到这里我有点兴奋,其实我用Python去调用libvert的API,也可以写一套类似openstack的虚拟机管理工具;
PS:openstack挂了 kvm虚拟机也会挂吗?你的老板挂了你会挂吗?
5.1.KVM虚拟机是通过什么定义的?
[root@localhost qemu]# cat Centos-7-x86_64.xml <!-- WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE OVERWRITTEN AND LOST. Changes to this xml configuration should be made using: virsh edit Centos-7-x86_64 or other application using the libvirt API. --> <domain type=\'kvm\'> <name>Centos-7-x86_64</name> <uuid>fc152f09-9b09-4890-a316-3c2a5afb0e68</uuid> <memory unit=\'KiB\'>2097152</memory> <currentMemory unit=\'KiB\'>2097152</currentMemory> <vcpu placement=\'static\'>1</vcpu> <os> <type arch=\'x86_64\' machine=\'pc-i440fx-rhel7.0.0\'>hvm</type> <boot dev=\'hd\'/> </os> <features> <acpi/> <apic/> </features> <cpu mode=\'custom\' match=\'exact\' check=\'partial\'> <model fallback=\'allow\'>Broadwell-noTSX</model> </cpu> <clock offset=\'utc\'> <timer name=\'rtc\' tickpolicy=\'catchup\'/> <timer name=\'pit\' tickpolicy=\'delay\'/> <timer name=\'hpet\' present=\'no\'/> </clock> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <pm> <suspend-to-mem enabled=\'no\'/> <suspend-to-disk enabled=\'no\'/> </pm> <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type=\'file\' device=\'disk\'> <driver name=\'qemu\' type=\'raw\'/> <source file=\'/kvm_img/Centos-7-x86.raw\'/> <target dev=\'vda\' bus=\'virtio\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x06\' function=\'0x0\'/> </disk> <disk type=\'file\' device=\'cdrom\'> <driver name=\'qemu\' type=\'raw\'/> <target dev=\'hda\' bus=\'ide\'/> <readonly/> <address type=\'drive\' controller=\'0\' bus=\'0\' target=\'0\' unit=\'0\'/> </disk> <controller type=\'usb\' index=\'0\' model=\'ich9-ehci1\'> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x04\' function=\'0x7\'/> </controller> <controller type=\'usb\' index=\'0\' model=\'ich9-uhci1\'> <master startport=\'0\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x04\' function=\'0x0\' multifunction=\'on\'/> </controller> <controller type=\'usb\' index=\'0\' model=\'ich9-uhci2\'> <master startport=\'2\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x04\' function=\'0x1\'/> </controller> <controller type=\'usb\' index=\'0\' model=\'ich9-uhci3\'> <master startport=\'4\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x04\' function=\'0x2\'/> </controller> <controller type=\'pci\' index=\'0\' model=\'pci-root\'/> <controller type=\'ide\' index=\'0\'> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x01\' function=\'0x1\'/> </controller> <controller type=\'virtio-serial\' index=\'0\'> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x05\' function=\'0x0\'/> </controller> <interface type=\'network\'> <mac address=\'52:54:00:ca:24:4f\'/> <source network=\'default\'/> <model type=\'virtio\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x03\' function=\'0x0\'/> </interface> <serial type=\'pty\'> <target type=\'isa-serial\' port=\'0\'> <model name=\'isa-serial\'/> </target> </serial> <console type=\'pty\'> <target type=\'serial\' port=\'0\'/> </console> <channel type=\'unix\'> <target type=\'virtio\' name=\'org.qemu.guest_agent.0\'/> <address type=\'virtio-serial\' controller=\'0\' bus=\'0\' port=\'1\'/> </channel> <input type=\'tablet\' bus=\'usb\'> <address type=\'usb\' bus=\'0\' port=\'1\'/> </input> <input type=\'mouse\' bus=\'ps2\'/> <input type=\'keyboard\' bus=\'ps2\'/> <graphics type=\'vnc\' port=\'-1\' autoport=\'yes\' listen=\'0.0.0.0\'> <listen type=\'address\' address=\'0.0.0.0\'/> </graphics> <video> <model type=\'cirrus\' vram=\'16384\' heads=\'1\' primary=\'yes\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x02\' function=\'0x0\'/> </video> <memballoon model=\'virtio\'> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x07\' function=\'0x0\'/> </memballoon> </devices> </domain>
所有的虚拟机都是由这个目录下的 xml文件定义的 其中包含:CPU、内存、硬盘...参数,对它的修改也就是对KVM虚拟机的动态调整
5.2.virsh管理命令
如上图所示 vish 是虚拟机管理服务(libvert)的客户端,那么如何使用virsh来对KVM虚拟机进行管理呢?
virsh list #查看虚拟机列表
qemu-img convert -f raw -O qcow2 /var/lib/libvirt/images/xuegod63-kvm2.img /var/lib/libvirt/images/xuegod63-kvm2.qcow2 #转换格式(将raw格式转换为qcow2格式):
virsh dumpxml Centos-7-x86_64 > back.xml #备份虚拟机定义文件
virsh defined back.xml #通过备份的.xml文件还原虚拟机
virsh reboot Centos-7-x86_64 #重启虚拟机
virsh shutdown Centos-7-x86_64 #关闭虚拟机
virsh start Centos-7-x86_64 #开启虚拟机
virsh suspend Centos-7-x86_64 #挂起虚拟机 virsh resume Centos-7-x86_64 #恢复虚拟机
virsh snapshot-list Centos-7-x86_64 #查看本虚拟机的快照 virsh snapshot-create-as Centos-7-x86_64 mysnapshot #创建快照
virsh snapshot-revert Centos-7-x86_64 mysnapshot #恢复快照
virsh snapshot-delete Centos-7-x86_64 mysnapshot #删除快照
5.3.virsh edit命令
该命名可以对 /etc/libvirt/qemu下的xml虚拟机定义文件进行修改,进而对虚拟机的硬件参数进行在线调整;
调整CPU个数
<vcpu placement=\'auto\' current=\'1\'>4</vcpu>
virsh setvcpus Centos-7-x86_64 2 --live #在线修改为2个CPU
调整内存大小
virsh qemu-monitor-command Centos-7-x86_64 --hmp --cmd balloon 1024 #设置内存大小
virsh qemu-monitor-command Centos-7-x86_64 --hmp --cmd info balloon #查看内存大小
硬盘相关
QUME使用的镜像文件分为:qcow2和raw格式
qcow2格式:支持快照功能、性能慢、动态占用
raw格式:不支持快照功能、性能快、指定多多空间占用多大,可以转换成其他格式
qemu-img info Centos-7-x86.raw #查看KVM镜像文件格式
qemu-img convert -f raw -O qcow2 Centos-7-x86.raw test.qcow2 #转换镜像文件的格式
KVM网络架构调整(把所有KVM虚假 桥接到虚拟网桥br0上)
KVM虚假默认是通过NAT转换的方式上网的,但是NAT转换有网络平静,所有我可在宿主机上创建 一些虚拟网桥,让一堆堆的虚拟机桥接到宿主机的各个网桥上,达到网络负载均衡的效果;
brctl show #查看网桥:通过virbr0网桥做NAT IP地址转换 分配给虚拟机
stepA:宿主机新增虚拟网桥(以免增加网桥的操作过程中宿主机网络中断,所以一定通过脚本的形式进行操作。)
#!/usr/bin/bash ip addr del dev ens33 192.168.226.151/24 #剥夺、删除ens33的IP地址 brctl addbr br0 #添加虚拟机网桥 br0 ifconfig br0 192.168.226.151/24 up #给网桥设置IP地址 brctl addif br0 ens33 #将br0桥接到ens22物理网卡 route add default gw 192.168.226.2 #添加网关出口
stepB:设置KVM.xml 让虚拟机连接到宿主机新增的网桥上
<interface type=\'bridge\'> <mac address=\'52:54:00:ca:24:4f\'/> <source bridge=\'br0\'/> <model type=\'virtio\'/> <address type=\'pci\' domain=\'0x0000\' bus=\'0x00\' slot=\'0x03\' function=\'0x0\'/> </interface>
stepC:KVM虚拟机桥接到宿主机之后,重启KVM(重启不能用reboot否则不生效!), 然后登陆KVM给KVM配置静态IP、网关、DNS
KVM网卡配置 (/etc/sysconfig/network-scripts/ifcfg-eth0) BOOTPROTO=static ONBOOT=yes IPADDR=192.168.226.18 NETMASK=255.255.255.0 GATEWAY=192.168.226.2 KVMDNS配置 /etc/resolv.conf nameserver 192.168.226.2
6.KVM性能优化
6.1:减少CachMiss
每个kvm虚拟机都对应宿主机中的一个进程,为了减少CachMiss,可以把某些运行重要业务的kvm绑定到一颗CPU上;
[root@localhost zhanggen]# taskset -cp 0 8000 #0:CPU 800:进程ID pid 8000\'s current affinity list: 0 pid 8000\'s new affinity list: 0
6.2.使用大页内存,减少内存碎片,加速内存寻址(默认已开启);
[root@localhost zhanggen]# cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never
6.3.Linux的IO调度算法
四、python3调用libvirtd API
如果你想通过python3调用宿主机的libvirtd API 管理KVM虚拟机,必须要 pip 安装libvirt-python模块 然后在libvirtd 宿主机端开启API 端口,就可以了;
1.libvert-python模块安装
yum install -y libvirt-devel yum install python-devel pip3 install psutil pip3 install ioctl_opt 下载python-libvirt包#https://pypi.org/project/libvirt-python/3.7.0/ python setup.py build python setup.py install 效果 [root@cmdb libvirt-python-3.7.0]# python Python 3.6.1 (default, Feb 22 2019, 15:18:59) [GCC 4.4.7 20120313 (Red Hat 4.4.7-18)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import libvirt >>>
2.设置LIBVIRTD_PATH环境变量
export LIBVIRTD_PATH=/usr/sbin/
以上是python端的准备工作,如果python想要连接到KVM宿主机的libverd API 就需要配置 libvirtd的开放端口;
3.配置libvirtd API 端口
LIBVIRTD_CONFIG=/etc/libvirt/libvirtd.conf LIBVIRTD_ARGS="--listen"
listen_tls = 0 listen_tcp = 1 tcp_port = "16509" listen_addr = "0.0.0.0" auth_tcp = "none"
LISTEN 0 128 *:16509 *:*
4、代码
用了半天时间 搭建libvirtd API 环境 、pip libvert-python模块 ,要运维干嘛?............终于可以用python连进来写会儿代码了。
[root@localhost libvirt]# python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import libvirt >>> conn = libvirt.open("qemu+tcp://192.168.226.151/system") >>>
参考:
https://www.cnblogs.com/psv-fuyang/articles/8598240.html