[kvm]学习笔记4:KVM高级功能详解

[kvm]学习笔记4:KVM高级功能详解

2023年6月29日发(作者:)

[kvm]学习笔记4:KVM⾼级功能详解1. 半虚拟化驱动1.1 virtio 概述KVM 是必须使⽤硬件虚拟化辅助技术(如 Intel VT-x 、AMD-V)的 Hypervisor,在CPU 运⾏效率⽅⾯有硬件⽀持,其效率是⽐较⾼的;在有 Intel EPT 特性⽀持的平台上,内存虚拟化的效率也较⾼。 QEMU/KVM 提供了全虚拟化环境,可以让客户机不经过任何修改就能运⾏在 KVM 环境中。不过 KVM 在 I/O虚拟化⽅⾯,传统的⽅式是使⽤ QEMU 纯软件的⽅式来模拟 I/O 设备(如⽹卡、磁盘、显卡等),其效率并不⾮常⾼。  CPU 和 内存的虚拟化由KVM内核模块提供,I/O设备虚拟化由QEMU负责实现。在KVM中,可以在客户机中使⽤半虚拟化驱动的⽅式是采⽤ Virtio 这个 Linux 上的设备驱动标准框架。

完全虚拟化:GuestOS 运⾏在物理机上的 Hypervisor 之上,GuestOS 并不知道它已经被虚拟化,并不需要任何修改就能⼯作;半虚拟化:GuestOS 不仅知道它运⾏在 Hypervisor 之上,还包括让 GuestOS 更⾼效的过度到 Hypervisor 的代码。

在完全虚拟化模式中,hypervisor 必须模拟设备硬件,它是在会话的最低级别进⾏模拟的,尽管在该抽象中模拟很⼲净,但它同时也是最低效的,最复杂的。在半虚拟化中,GuestOS 和 hypervisor 能够共同合作,让模拟更加⾼效,缺点是操作系统知道它被虚拟化,并且需要修改才能⼯作。

左图在传统的完全虚拟化环境中,hypervisor必须捕捉这些请求,然后模拟物理硬件的⾏为。尽管这也做提供很⼤的灵活性(即运⾏未更改的操作系统),但它的效率⽐较低.右图,半虚拟化,来宾操作系统知道它运⾏在hypervisor之上,并包含了充当当前的驱动程序.hypervisor为特定的设备模拟实现后端驱动程序.通过在这些前端和后端驱动程序中的virtio,为开发模拟设备提供标准化接⼝,从⽽增加代码的跨平台重⽤率并提⾼效率.

QEMU模拟 I/O 设备基本原理和优缺点

使⽤QEMU模拟 I/O 的情况下:  (1)当客户机中的设备驱动程序(device driver)发起 I/O 操作请求时,KVM模块中的 I/O 操作捕获代码会拦截这次 I/O 请求;  (2)经过处理后将本次 I/O 请求的信息存放到 I/O 共享页,并通知⽤户控件中的 QEMU 程序;  (3)QEMU 模拟程序获得 I/O 操作的具体信息之后,交由硬件模拟代码来模拟出本次的 I/O 操作;  (4)完成之后,将结果放回到 I/O 共享页,并通知KVM 模块中的 I/O 操作捕获代码;  (5)由 KVM 模块中的捕获代码读取 I/O 共享页中的操作结果,并把结果返回到客户机中。在这个过程中,QEMU进程在等待I/O时被阻塞,当客户机通过 DMA 访问⼤块 I/O时,QEMU模拟程序将不会把操作结果放到I/O共享页中,⽽是通过内存映射的⽅式将结果直接写到客户机的内存中去,然后通过KVM模块告诉客户机DMA操作已经完成。QEMU 模拟 I/O 设备的⽅式,其优点是可以通过软件模拟出各种各样的硬件设备,包括⼀些不常⽤的或者很⽼很经典的设备,⽽且它不⽤修改客户机操作系统,就可以实现模拟设备在客户机中正常⼯作。 在KVM客户机中使⽤这种⽅式,对于解决⼿上没有⾜够设备的软件开发及调试有⾮常⼤的好处。⽽它的缺点是,每次 I/O 操作的路径⽐较长,有较多的 VMEntry、VMExit发⽣,需要多次上下⽂切换(context switch),也需要多次数据复制,所以它的性能较差。

半虚拟化 virtio 的基本原理和优缺点其中前端驱动(frondend,如 virtio-blk、virtio-net等)是在客户机中存在的驱动程序模块,⽽后端处理程序(backend)是在 QEMU中实现的。在这前后端驱动之间,还定义了两层来⽀持客户机与 QEMU 之间的通信:  virtio:虚拟队列接⼝,在概念上将前端驱动程序附加到后端处理程序,⼀个前端驱动程序可以使⽤ 0 个或 多个队列,具体数据取决于需求;  例如:virtio-net ⽹络驱动程序使⽤两个虚拟队列(⼀个⽤于接收、另⼀个⽤于发送),⽽virtio-blk块驱动程序仅使⽤⼀个虚拟队列。虚拟队列实际上被实现为跨越客户机操作系统和hypervisor的衔接点,但它可以通过任意⽅式实现,前提是客户机操作系统和virtio后端程序都遵循⼀定的标准,以相互匹配的⽅式实现它。  virtio-ring:实现了环形缓冲区(ring buffer),⽤于保存前端驱动和后端处理程序执⾏的信息,并且它们可以⼀次性保存前端驱动的多次I/O请求,并且交由后端去批量处理,最后实际调⽤宿主机中设备驱动实现物理上的I/O操作,这样做就可以根据约定实现批量处理⽽不是客户机中每次I/O请求都需要处理⼀次,从⽽提⾼客户机与hypervisor信息交换的效率。virtio 半虚拟化驱动的⽅式,可以获得很好的I/O性能,其性能⼏乎可以达到和 native(⾮虚拟化环境中的原⽣系统)差不多的I/O性能。所以,在使⽤ kvm 时,如果宿主机内核和客户机都⽀持 virtio的情况下,⼀般推荐使⽤ virtio 达到更好的性能。

virtio 缺点:  必须要安装特定的virtio驱动使其知道是运⾏在虚拟化环境中,且按照 virtio 的规定格式进⾏数据传输,不过客户机中可能有⼀些⽼的Linux系统不⽀持virtio 和主流windows系统需要安装特定的驱动才⽀持 virtio,不过,较新的⼀些Linux发⾏版(如RHEL 6.3、Fedora 17等)默认都将virtio相关驱动编译为模块,可直接作为客户机使⽤virtio,⽽且对于主流Windows系统都有对应的virtio驱动程序可供下载使⽤。virtio是对半虚拟化hypervisor中的⼀组通⽤模拟设备的抽象.该设置还允许hypervisor导出⼀组通⽤的模拟设备,并通过⼀个通⽤的应⽤程序接⼝(API)让它们变得可⽤.有了半虚拟化hypervisor之后,来宾操作系统能够实现⼀组通⽤的接⼝,在⼀组后端驱动程序之后采⽤特定的设备模拟.后端驱动程序不需要是通⽤的,因为它们只实现前端所需的⾏为.注意,在现实中(尽管不需要),设备模拟发⽣在使⽤ QEMU 的空间,因此后端驱动程序与 hypervisor 的⽤户空间交互,以通过 QEMU 为 I/O 提供便利。QEMU 是⼀个系统模拟器,它不仅提供来宾操作系统虚拟化平台,还提供整个系统(PCI 主机控制器、磁盘、⽹络、视频硬件、USB 控制器和其他硬件元素)的模拟。

1.2 安装 virtio 驱动Linux 2.6 及以上版本内核都是⽀持 virtio 的。由于 virtio 的后端处理程序是在位于⽤户空间的 QEMU 中实现的,所以,在宿主机中只需要⽐较新的内核即可,不需要特别的编译与 virtio 相关的驱动。

1.2.1 Linux 中的 virtio 驱动[root@192.168.118.14 ~]#lsmod | egrep virtvirtio_balloon 13664 0

virtio_blk 18156 3

virtio_console 28114 0

virtio_net 28024 0

virtio_pci 22913 0

virtio_ring 21524 5 virtio_blk,virtio_net,virtio_pci,virtio_balloon,virtio_consolevirtio 15008 5 virtio_blk,virtio_net,virtio_pci,virtio_balloon,virtio_console其中,virtio,virtio_ring、virtio_pci 等驱动程序提供了对 virtio API 的基本⽀持,是使⽤任何 virtio 前端驱动都必须使⽤的,⽽且它们的加载还有⼀定的顺序,应该按照virtio、virtio_ring、virtio_pci 的顺序加载,⽽ virtio_net、virtio_blk 这样的驱动可以根据实际需要进⾏选择性的编译和加载。

1.3 使⽤ virtio_balloon

(1)ballooning 简介通常来说,要改变客户机占⽤的宿主机内存,要先关闭客户机,修改启动的内存配置,然后重启客户机才能实现。⽽内存的 ballooning (⽓球)技术可以在客户机运⾏时动态的调整它所占⽤的宿主机内存资源,⽽不需要关闭客户机。ballooning 技术形象的在客户机占⽤的内存中引⼊⽓球(balloon)的概念。⽓球中的内存是可以供宿主机使⽤的,所以,当宿主机内存紧张,空余内存不多时,可以请求客户机回收利⽤已分配给客户机的部分内存,客户机就会释放其空闲的内存,此时若客户机空闲内存不⾜,可能还会回收部分使⽤中的内存,可能会将部分内存换出到客户机的交换分区(swap)中,从⽽使内存⽓球充⽓膨胀,进⽽使宿主机回收⽓球中的内存⽤于其他进程。反之,当客户机中内存不⾜时,也可以让宿主机的内存⽓球压缩,释放出内存⽓球中的部分内存,让客户机使⽤更多的内存。⽬前很多虚拟机,如KVM 、Xen、VMware 等,都对 ballooning 技术提供了⽀持。

(2)KVM 中 ballooning 的原理及优劣势KVM 中 ballooning 的⼯作过程主要有如下⼏步:  1. Hypervisor 发送请求到客户机操作系统让其归还⼀定数量的内存给 Hypervisor;  2. 客户机操作系统中 virtio_balloon 驱动接收到 Hypervisor;  3. virtio_balloon 驱动使客户机的内存⽓球膨胀,⽓球中的内存就不能被客户机访问。如果此时客户机中内存剩余量不多,并且不能让内存⽓球膨胀到⾜够⼤的以满⾜Hypervisor 的请求,那么 virtio_balloon 驱动也会尽可能多的提供内存使⽓球膨胀,尽量去满⾜ Hypervisor 的请求中的内存数量;  4. 客户机操作系统归还⽓球中的内存给 Hypervisor;  5. Hypervisor 可以将从⽓球中得来的内存分配到任何需要的地⽅;  6. 即使从⽓球中得到的内存没有处于使⽤中,Hypervisor 也可以将内存返还给客户机中,这个过程为:Hypervisor 发请求到客户机的 virtio_balloon 驱动;这个请求使客户机操作系统压缩内存⽓球;在⽓球中的内存被释放出来,重新由客户机访问和使⽤。

ballooning 在节约内存和灵活分配内存⽅⾯有明显的优势:  1. 因为ballooning 能够被控制和监控,所以能够潜在的节约⼤量的内存;  2. ballooning 对内存的调节很灵活,即可以精细的请求少量内存,⼜可以粗旷的请求⼤量的内存;  3. Hypervisor 使⽤ ballooning 让客户机归还部分内存,从⽽缓解其内存压⼒。⽽且从⽓球中回收的内存也不要求⼀定要被分配给另外某个进程。

从另⼀⽅⾯来说,KVM 中 ballooning的使⽤不⽅便、不完善的地⽅也是存在的,其缺点如下:  1. ballooning 需要客户机操作系统加载 virt_balloon 驱动,然⽽并⾮每个客户机系统都有该驱动;  2. 如果有⼤量内存需要从客户机系统中回收,那么 ballooning 可能会降低客户机操作系统运⾏的性能。⼀⽅⾯,内存的减少可能会让客户机中作为磁盘数据缓存的内存被放到⽓球中,从⽽使客户机中的磁盘I/O访问增加;另⼀⽅⾯,如果处理机制不够好,也可能让客户机中正在运⾏的进程由于内存不⾜⽽执⾏失败;  3. ⽬前没有⽐较⽅便的、⾃动化的机制来管理 ballooning,⼀般采⽤在 QEMU monitor 中执⾏ balloon 命令来实现 ballooning。没有对客户机的有效监控,没有⾃动化的ballooning 机制,这可能会使在⽣产环境中实现⼤规模⾃动化部署不是很⽅便。  4. 内存的动态增加或减少,可能会使内存被过度碎⽚化,从⽽降低内存使⽤时的性能。

(3)KVM 中 ballooning 使⽤⽰例1. 创建虚拟机[root@192.168.118.14 ~]#qemu-kvm -smp 1 -m 1024 -balloon virtio /images/ --nographic2. 查看 PCI 设备是否加载# lspci -k00:00.0 Class 0600: 8086:123700:01.0 Class 0601: 8086:700000:01.1 Class 0101: 8086:7010 ata_piix00:01.3 Class 0680: 8086:711300:02.0 Class 0300: 1013:00b800:03.0 Class 0200: 8086:100e e100000:04.0 Class 00ff: 1af4:1002 virtio-pci可以发现,00:04.0 Class 00ff: 1af4:1002 virtio-pci 就是 virtio-pci 设备3. 通过 balloon 调整内存⼤⼩原内存# free -m

total used free shared buffersMem: 1001 12 988 0 0-/+ buffers: 12 989Swap: 0 0 0使⽤ qemu-monitor 减少内存⼤⼩(qemu) info balloonballoon: actual=1024(qemu) balloon 512(qemu) info balloonballoon: actual=5124. 查看调整后的内存⼤⼩# free -m

total used free shared buffersMem: 489 12 477 0 0-/+ buffers: 12 234Swap: 0 0 0

总的来说,对于 ballooning 技术,⽬前还没有完全成熟的管理控制⼯具,⼤规模部署⾮常不⽅便,⽽且性能没有很⼤的提升,建议慎⽤。 1.4 使⽤ virtio_net在选择KVM中的⽹络设备时,⼀般来说优先选择半虚拟化的⽹络设备⽽不是模拟纯软件模拟的设备使⽤ virtio_net 半虚拟化驱动,可以提⾼⽹络吞吐量和降低⽹络延迟,从⽽让客户机中⽹络达到⼏乎和⾮虚拟化系统中使⽤原⽣⽹卡的⽹络差不多的性能。(1)检查 QEMU 是否⽀持 virtio 类型的⽹卡# qemu-kvm -smp 2 -m 512m -net nic,model=?qemu: Supported NIC models: ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio(2)启动客户机时,指定分配 virtio ⽹卡设备# qemu-kvm -smp 2 -m 512m -drive file=/root/,if=virtio -net nic,model=virtio -net tap,name=tap0,script=no -daemonize

使⽤ virtio_net 依然是较低的性能,可以检查宿主机系统中对 GSO 和 TSO 特性的设置。关闭 GSO 和 TSO 可以使⽤半虚拟化⽹络驱动的性能更加优化。ethtool -K eno1 gso offethtool -K eno1 tso off

⽤ vhost_net 后端驱动前⾯提到 virtio 在宿主机中的后端处理程序(backend)⼀般是由⽤户空间的 QEMU 提供的,然⽽,如果对于⽹络 IO 请求的后端处理能够在内核空间来完成,则效率更⾼,会提⾼⽹络吞吐量和减少⽹络延迟。在⽐较新的内核中有⼀个叫做 “vhost_net”的驱动模块,它作为⼀个内核级别的后端处理程序,将 virtio-net的后端处理任务放到内核空间执⾏,从⽽提⾼效率。qemu-kvm -smp 2 -m 512m -drive file=/root/,if=virtio -net nic,model=virtio,macaddr=52:54:00:ac:0f:11 -net tap,name=tap0,vnet_hdr=on,vhost=on,script=no -daemonize⼀般来说,使⽤ vhost-net 作为后端处理驱动可以提⾼⽹络的性能。不过,对于⼀些使⽤ vhost-net 作为后端的⽹络负载类型,可能使其性能不升反降。特别是从宿主机到其客户机之间的 UDP 流量,如果客户机处理接受数据的速度⽐宿主机发送的速度要慢,这时就容易出现性能下降。在这种情况下,使⽤ vhost-net 将会使 UDP socket 的接受缓冲区更快的溢出,从⽽导致更多的数据包丢失。因此在这种情况下不使⽤vhost-net,让传输速度稍慢⼀点,反⽽会提⾼整体的性能。

1.5 使⽤ virtio_blkvirtio_blk 驱动使⽤ virtio API 为客户机提供了⼀个⾼效访问块设备 I/O ⽅法。在 QEMU/KVM 中对块设备使⽤ virtio,需要在两⽅⾯进⾏配置:客户机中的前端驱动模块virtio_blk 编译为内核模块,可以作为客户机直接使⽤ virtio_blk。启动⼀个使⽤ virtio_blk 作为磁盘驱动的客户机,其 qemu-kvm 命令⾏如下:[root@192.168.118.14 ~]#qemu-kvm -smp 2 -m 512m -drive file=/images/,if=virtio未使⽤ virtio 模块的虚拟机# lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTsda 8:0 0 39.2M 0 disk

`-sda1 8:1 0 31.4M 0 part /使⽤ virtio 模块的虚拟机# lsblk

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTvda 253:0 0 39.2M 0 disk

`-vda1 253:1 0 31.4M 0 part /

2. 动态迁移

2.1 动态迁移概念迁移(migration)包括系统整体的迁移和某个⼯作负载的迁移。系统整体迁移,是将系统上的所有软件完全复制到另⼀台物理硬件机器上。⽽⼯作负载的迁移,是将系统上的某个⼯作负载转移到另⼀台物理机上继续运⾏。服务器系统迁移的作⽤在于简化了系统维护管理,提⾼了系统负载均衡,增强了系统容错性并优化了系统电源管理。在虚拟化环境中的迁移,⼜分为 静态迁移(static migration)和动态迁移(live migration) 静态迁移和动态迁移最⼤的区别:静态迁移有明显⼀段时间客户机中的服务不可⽤,⽽动态迁移则没有明显的服务暂停时间。虚拟化中的静态迁移,也可以分为两种,⼀种是关闭客户机后,将其硬盘镜像复制到另⼀台宿主机上然后恢复启动起来,这种迁移不能保留客户机中运⾏的⼯作负载;另⼀种是两台宿主机共享存储系统,只需要暂停客户机后,复制其内存镜像到另⼀台宿主机中恢复启动,这种迁移可以保持客户机迁移前的内存状态和系统运⾏的⼯作负载。动态迁移,是指在保证客户机上应⽤服务正常运⾏的同时,让客户机在不同的宿主机之间进⾏迁移,其逻辑步骤与前⾯静态迁移⼏乎⼀致,有硬盘存储和内存都复制的动态迁移,也有仅复制内存镜像的动态迁移。不同的是,为了保证迁移过程中客户机服务的可⽤性,迁移过程仅有⾮常短暂的停机时间。动态迁移允许系统管理员将客户机在不同物理机上迁移,同时不会断开访问客户机中服务的客户端或应⽤程序的连接。⼀个成功的动态迁移,需要保证客户机的内存、硬盘存储、⽹络连接在迁移到⽬的的主机后依然保持不变,⽽且迁移过程的服务暂停时间较短。

2.2 动态迁移的效率和应⽤场景虚拟机迁移主要增强了系统的可维护性,其主要⽬标是在客户没有感觉的情况下,将客户机迁移到了另⼀台物理机上,并保证其各个服务都正常使⽤。可以从如下⼏个⽅⾯来衡量虚拟机的迁移的效率:(1)整体迁移时间:从源主机中迁移操作开始到客户机被迁移到⽬的主机并恢复其服务所花费的时间;(2)服务器停机时间:在迁移过程中,源主机和⽬的主机上客户机的服务都处于不可⽤状态的时间,此时源主机上客户机已暂停服务,⽬的主机上客户机还未恢复服务;(3)对服务的性能影响:不仅包括迁移后的客户机中应⽤程序的性能与迁移前相⽐是否有所下降,还包括迁移后对⽬的主机上的其他服务的性能影响。

动态迁移的好处⾮常明显,动态迁移的⼏个场景:(1)负载均衡:当⼀台物理服务器的负载较⾼时,可以将其上运⾏的客户机动态迁移到负载较低的宿主机服务器中,以保证客户机的服务质量(QoS)。(2)解除硬件依赖:升级主机,添加某些硬件设备时,可以将宿主机上运⾏的客户机⾮常安全⾼效的动态迁移到其他宿主机上。(3)节约能源:通过动态迁移将宿主机上的客户机集中迁移到其中⼏台服务器上。(4)实现客户机地理位置上的远程迁移:⽐如跨地域性的迁移。

2.3 KVM 动态迁移原理与实践在KVM 中,即⽀持离线的静态迁移,⼜⽀持在线的动态迁移。对于静态迁移,可以在源宿主机上某客户机的 QEMU monitor中,⽤ "savevm my_tag" 命令来保存⼀个完整的客户机镜像快照(标记为 my_tag),然后在源宿主机中关闭或暂停该客户机,然后将该客户机的镜像⽂件复制到另外⼀台宿主机中,⽤于源主机中启动客户机时以相同的命令启动复制过来的镜像,在其 QEMU monitor 中⽤ "loadvm my_tag" 命令来恢复刚才保存的快照即可完全加载保存快照时的客户机状态。这⾥的 "savevm" 命令保存的完整客户机状态包括:CPU 状态、内存、设备状态、可写磁盘中的内容。注意:这种保存快照的⽅法需要 qcow2、qed 等格式的磁盘镜像⽂件,因为只有它们才⽀持快照这个特性。如果源宿主机和⽬的宿主机共享存储系统,则只需要通过⽹络发送客户机的vCPU 执⾏状态、内存中的内容、虚拟设备的状态到⽬的主机上。否则,还需要将客户机的磁盘存储发送到⽬的主机上去。

在不考虑磁盘存储复制的情况下(基于共享存储系统),KVM 动态迁移的具体迁移过程为:在客户机动态迁移开始后,客户机依然在原宿主机上运⾏,与此同时,客户机的内存页被传输到⽬的主机之上。QEMU/KVM 会监控并记录下迁移过程中所有已被传输的内存页的任何修改,并在所有的内存页都被传输完成后即开始传输在前⾯过程中内存页的更改内容。QEMU/KVM 也会估计迁移过程中的传输速度,当剩余的内存数据量能够在⼀个可设定的时间周期内传输完成之时,QEMU/KVM 将会关闭源宿主机上的客户机,再将剩余的数据量传输到⽬的主机上去,最后传输过来的内存内容在⽬的宿主机上恢复客户机的运⾏状态。⾄此,KVM的⼀个动态迁移操作就完成了。当客户机中内存使⽤量⾮常⼤且修改频繁,内存中数据被不断修改的速度⼤于 KVM 能够传输的内存速度之时,动态迁移过程是不会完成的,这时要进⾏迁移只能进⾏静态迁移。

对于 KVM 动态迁移,有如下⼏点建议和注意事项:  (1)源宿主机和⽬的宿主机之间尽量⽤⽹络共享的存储系统来保存客户机镜像,尽管KVM动态迁移也⽀持连通磁盘镜像⼀起复制。共享存储(如NFS)在源宿主机和⽬的宿主机上的挂载位置必须⼀致;  (2)为了提⾼动态迁移的成功率,尽量在同类型 CPU 的主机上⾯进⾏动态迁移;  (3)64 位的客户机只能在 64位宿主机之间迁移,⽽ 32 位客户机可以在 32 位宿主机和 64 位宿主机之间迁移;  (4)动态迁移的源宿主机和⽬的宿主机对 NX 位的设置是相同的,要么关闭状态,要么打开状态;  (5)在进⾏动态迁移时,被迁移客户机的名称是唯⼀的,在⽬的宿主机上不能与源宿主机中被迁移客户机同名的客户机存在;  (6)⽬的宿主机和源宿主机的软件配置尽可能是相同,例如,为了保证动态迁移后客户机中⽹络依然正常⼯作,需要在⽬的宿主机上配置和源宿主机相同名称⽹桥,并让客户机以桥接的⽅式使⽤⽹络。

⽰例:使⽤ qemu-kvm 动态迁移

NFS 主机配置:[root@192.168.118.16 ~]#mkdir /images[root@192.168.118.16 ~]#mv /images/[root@192.168.118.16 ~]#yum install nfs-utils -y[root@192.168.118.16 ~]#cat /etc/exports/images *(rw,async,no_root_squash)[root@192.168.118.16 ~]#systemctl start rpcbind[root@192.168.118.16 ~]#systemctl start nfs-server

源宿主机配置:[root@192.168.118.14 ~]#yum install nfs-utils -y[root@192.168.118.14 ~]#mount 192.168.118.16:/images /images/[root@192.168.118.14 ~]#qemu-kvm -smp 2 -m 512m /images/ -monitor stdio⽬的迁移主机操作如下:[root@192.168.118.15 ~]#yum install nfs-utils -y[root@192.168.118.15 ~]#mount 192.168.118.16:/images /images/[root@192.168.118.15 ~]#qemu-kvm -smp 2 -m 512m /images/ -incoming tcp:0:6666通过 tigervnc 连接:

到此,在源宿主机执⾏:(qemu) migrate -d tcp:192.168.118.15:6666

再次查看,被迁移的主机:被迁移主机完成后,也存在运⾏top命令,迁移完成。

QEMU/KVM 中也⽀持增量复制磁盘修改部分数据(使⽤相同的后端镜像时)的动态迁移,以及直接复制整个客户机磁盘镜像的动态迁移。使⽤相同后端镜像⽂件的动态迁移过程如下,与前⾯直接使⽤NFS共享存储⾮常类似。(1)在源宿主机上,根据⼀个后端镜像⽂件,创建⼀个 qcow2 格式的镜像⽂件,并启动客户机,命令如下:[root@192.168.118.14 /images]#qemu-img create -f qcow2 -o backing_file=/images/,size=20G 2[root@192.168.118.14 ~]#qemu-kvm -smp 2 -m 512m /root/2 -monitor stdio(2)在⽬的宿主机上,也建⽴相同的 qcow2 格式的客户机镜像,并带有 "-incoming" 参数来启动客户机使其处于迁移监听状态:[root@192.168.118.15 ~]#qemu-img create -f qcow2 -o backing_file=/images/,size=20G 2[root@192.168.118.15 ~]#qemu-kvm -smp 2 -m 512m /root/2 -incoming tcp:0:6666(3)在源宿主机上的客户机的 QEMU monitor 中,运⾏ "migrate -i tcp:192.168.118.15:6666"注意:有些 qemu-kvm 并不⽀持 -i 增量迁移,可以直接使⽤:migrate tcp:192.168.118.15:6666(qemu) migrate tcp:192.168.118.15:6666

⾄此,基于相同后端镜像的磁盘动态迁移就完成,在⽬的宿主机上可以看到迁移过来的客户机已经处于和源客户机⼀样的状态。

3. KSM 技术在现代操作系统中,共享内存是⼀个很普遍应⽤的概念。如在 Linux 系统中,当使⽤ fork 函数创建⼀个进程时,⼦进程与⽗进程共享全部的内存,⽽当⼦进程或⽗进程试图修改它们的共享内存区域时,内核会分配⼀块新的内存区域,并将试图修改的共享内存区域复制到新的内存区域上,然后让进程去修改复制的内存。这就是著名的“写时复制”(copy-on-write)技术。⽽ KSM技术却与这种内存共享概念有点相反。KSM 是“Kernel SamePage Merging”缩写,中⽂可称为“内核同页合并”。KSM 允许内核在两个或多个进程之间共享完全相同的内存页。KSM 让内核扫描检查正在运⾏中的程序并⽐较它们的内存,如果发现它们有内存区域或内存页是完全相同的,就将相同的内存合并为⼀个单⼀的内存页,并将其标识为“写时复制”。这样可以起到节省系统内存使⽤量的作⽤。之后,如果有进程试图去修改被标识为“写时复制”的合并的内存页时,就为该进程复制出⼀个新的内存页供其使⽤。在 QEMU/KVM 中,⼀个虚拟客户机就是⼀个 QEMU 进程,所以使⽤ KSM 也可以实现多个客户机之间的相同内存合并。⽽且,如果在同⼀宿主机上的多个客户机运⾏的是相同的操作系统或应⽤程序,则客户机之间的相同内存页数量就可能还⽐较⼤,这种情况下KSM的作⽤就更加显著。在KVM环境下使⽤ KSM ,KSM还允许KVM 请求哪些相同的内存页是可以被共享合并的,所以KSM只会识别并合并哪些不会⼲扰客户机运⾏,不会影响宿主机或客户机的安全内存页。可见,在KVM 虚拟化环境中,KSM 能够提⾼内存的速度和使⽤效率,具体可以从以下两个⽅⾯来理解:(1)在 KSM 的帮助下,相同的内存页被合并了,减少了客户机的内存使⽤量,⼀⽅⾯,内存中的内存更容易被保存到CPU 的缓存中;另⼀⽅⾯,有更多的内存可⽤于缓存⼀些磁盘中的数据。因此,不管是内存的缓存命中率,还是磁盘数据的缓存命中率都会提⾼,从⽽提⾼了 KVM 客户机中操作系统或应⽤的运⾏速度;(2)KSM 是内存过载使⽤的⼀种较好的⽅式。KSM 通过减少每个客户机实际占⽤的内存数,就可以让多个客户机分配的内存数量之和⼤于物理内存数量。⽽对于使⽤相同的内存量的客户机,在物理内存量不变的情况下,可以在⼀个宿主机中创建更多客户机,提⾼了虚拟化客户机部署的密度,提⾼了物理资源的利⽤效率。

KSM 是在 Linux 内核 2.6中被加⼊到内核主代码中去的,⽬前多数流⾏的 Linux 发⾏版都已经将 KSM 的⽀持编译到内核中了,其内核配置⽂件中有 “CONFIG_KSM=y”项:[root@192.168.118.14 ~]#egrep -i ksm /boot/7.x86_64

CONFIG_KSM=yLinux 系统的内核进程 ksmd 负责扫描后合并进程的相同内存页,从⽽实现 KSM 功能。root ⽤户可以通过 "/sys/kernel/mm/ksm/" ⽬录下的⽂件来配置和监控 ksmd 这个守护进程。KSM 只会去扫描和试图合并那些应⽤程序建议为可合并的内存页。KSM 最初就是为 KVM 虚拟化中的使⽤⽽开发的,不过它对⾮虚拟化的系统依然⾮常有⽤。KSM 可以在KVM 虚拟化环境中⾮常有效的降低内存使⽤量,在KSM的帮助下,有⼈在物理内存为 16GB 的机器上,⽤KVM 成功运⾏了多达 52 个 1GB 内存的windows xp 客户机。由于KSM 对 KVM 宿主机中的内存使⽤有较⼤的效率和性能的提⾼,所以⼀般建议打开 KSM 功能。,可是,由于KSM必须有⼀个或多个进程去检测和找出哪些内存页是完全相同可以⽤于合并的。因此,KSM 让内存使⽤量降低了,但是 CPU 使⽤率会有⼀定程度的升⾼,也可能会带来隐蔽的性能问题,需要在实际使⽤环境中进⾏适当配置KSM 的使⽤,以便达到较好的平衡。KSM对内存合并⽽节省内存的数量与客户机操作系统及其上运⾏的应⽤程序有关,如果宿主机上的客户操作系统及其上的应⽤程序也类似,节省内存的效果就会很显著,甚⾄节省超过 50%的内存都有可能的。反之,如果客户机操作系统不同,且运⾏的应⽤程序也⼤不相同,KSM 节省内存效率不好,可能连 5%都不到。另外,在使⽤ KSM 实现内存过载使⽤时,最好保证系统的交换空间(swap space)⾜够⼤,因为 KSM 将不同客户机的相同内存页合并⽽减少了内存使⽤量,但是客户机可能由于需要修改被KSM合并的内存页,从⽽使这些被修改的内存被重新复制出来占⽤内存空间,因此可能会导致系统内存不⾜,这是需要⾜够的交换空间来保证系统的正常运⾏。 3.1 KSM 操作实践内核 KSM 守护进程是 ksmd,配置和监控 ksmd 的⽂件在 "/sys/kernel/mm/ksm/" ⽬录下:[root@192.168.118.14 ~]#ll /sys/kernel/mm/ksm/total 0-r--r--r--. 1 root root 4096 Jul 9 08:21 full_scans-rw-r--r--. 1 root root 4096 Jul 9 08:21 merge_across_nodes-r--r--r--. 1 root root 4096 Jul 9 08:21 pages_shared-r--r--r--. 1 root root 4096 Jul 9 08:21 pages_sharing-rw-r--r--. 1 root root 4096 Jul 9 08:21 pages_to_scan-r--r--r--. 1 root root 4096 Jul 9 08:21 pages_unshared-r--r--r--. 1 root root 4096 Jul 9 08:21 pages_volatile-rw-r--r--. 1 root root 4096 Jul 9 08:21 run-rw-r--r--. 1 root root 4096 Jul 9 08:21 sleep_millisecs说明:full_scans:记录已经对所有可合并的内存区域扫描过的次数;pages_shared:记录着正在使⽤中的共享内存页的数量;pages_sharing:记录着有多少数量的内存页正在使⽤被合并的共享页,不包括合并的内存页本⾝。这就是实际节省的内存页数量;pages_unshared:记录了守护进程去检查并试图合并,却发现了并没有重复内容⽽不能被合并的内存页数量;pages_volatile:记录了因为其内容很容易变化⽽不被合并的内存页;pages_to_scan:在KSM进程休眠之前会去扫描的内存数量;sleep_millisecs:ksmd 进程休眠的时间(单位:毫秒),ksmd 的两次运⾏之间的间隔;run:控制 ksmd 进程是否运⾏的参数,默认值为0,要激活 ksm 必须要设置其参数为 1,设置为0,表⽰停⽌运⾏ ksmd 但保持它已经合并的内存页;设置为1,   表⽰马上运⾏ ksmd进程;设置为2 表⽰停⽌运⾏ ksmd,并分离已经合并的所有内存页,但是保持已经注册为合并的内存区域给下⼀次运⾏使⽤.

通过权限可以看出, 只有 pages_to_scan , sleep_millisecs, run 这 3 个⽂件对 root ⽤户是可读可写的,其余 5 个⽂件都是 只读的,可以向 pages_to_scan 、sleep_millisecs、 run 这三个⽂件中写⼊⾃定义的值以便控制 ksmd的运⾏。例如:echo 1200 > /sys/kernel/mm/ksm/pages_to_scan ⽤来调整每次扫描的内存页数量echo 10 > /sys/kernel/mm/ksm/sleep_millisecs ⽤来设置ksmd两次运⾏的时间间隔echo 1 > /sys/kernel/mm/ksm/run ⽤来激活ksmd 的运⾏

pages_sharing 的值越⼤,说明 KSM 节省的内存越多,KSM 效果越好,如下命令计算了节省的内存数量:[root@mongodb ~]# echo "KSM saved: $(($(cat /sys/kernel/mm/ksm/pages_sharing) * $(getconf PAGESIZE) / 1024 / 1024))MB"KSM saved: 1159MB

在 CentOS 7 系统中,提供了两个服务 ksm 和 ksmtuned 来动态调节 KSM 的运⾏情况,这两个服务都包含在 qemu-kvm-common 这个 RPM 安装包中。[root@192.168.118.14 ~]#systemctl status ksm● e - Kernel Samepage Merging Loaded: loaded (/usr/lib/systemd/system/e; enabled; vendor preset: enabled) Active: active (exited) since Tue 2019-07-09 09:59:40 CST; 21s ago Process: 668 ExecStart=/usr/libexec/ksmctl start (code=exited, status=0/SUCCESS) Main PID: 668 (code=exited, status=0/SUCCESS) CGroup: //eJul 09 09:59:40 omain systemd[1]: Starting Kernel Jul 09 09:59:40 omain systemd[1]: Started Kernel Samepage Merging.[root@192.168.118.14 ~]#systemctl status ksmtuned● e - Kernel Samepage Merging (KSM) Tuning Daemon Loaded: loaded (/usr/lib/systemd/system/e; enabled; vendor preset: enabled) Active: active (running) since Tue 2019-07-09 09:59:40 CST; 25s ago Process: 680 ExecStart=/usr/sbin/ksmtuned (code=exited, status=0/SUCCESS) Main PID: 685 (ksmtuned) CGroup: //e ├─685 /bin/bash /usr/sbin/ksmtuned └─686 sleep 60Jul 09 09:59:40 omain systemd[1]: Starting Kernel Samepage Merging (KSM) Jul 09 09:59:40 omain systemd[1]: Started Kernel Samepage Merging (KSM) Tuning Daemon.当 ksm 服务启动时: run ⽂件为 1[root@192.168.118.14 ~]#cat /sys/kernel/mm/ksm/run

1在 KSM 服务启动后,KSM 能够共享最多达到系统物理内存⼀半的内存页。⽽ ksmtuned 服务⼀直保持循环执⾏,以调⽤ ksm 服务的运⾏,其配置⽂件的/etc/ ,默认配置如下:[root@192.168.118.14 ~]#cat /etc/

# Configuration file for ksmtuned.# How long ksmtuned should sleep between tuning adjustments# KSM_MONITOR_INTERVAL=60# Millisecond sleep between ksm scans for 16Gb server.# Smaller servers sleep more, bigger sleep less.# KSM_SLEEP_MSEC=10# KSM_NPAGES_BOOST=300# KSM_NPAGES_DECAY=-50# KSM_NPAGES_MIN=64# KSM_NPAGES_MAX=1250# KSM_THRES_COEF=20# KSM_THRES_CONST=2048# uncomment the following if you want ksmtuned debug info# LOGFILE=/var/log/ksmtuned# DEBUG=1

在主机内存为 8 GB 的系统上,使⽤ Linux 3.10 内核的 CentOS 7 系统作为宿主机,开始将 ksm 和 ksmtuned 服务暂停,"/sys/kernel/mm/ksm/run" 的默认值为 0 ,KSM 不⽣效,然后启动每个内存为 1GB 的 4 个 cirros 客户机,再次启动 KSM 和 ksmtuned服务,5分钟后检查系统内存的使⽤情况以确定 KSM 效果。脚本及执⾏如下:[root@192.168.118.14 ~]#cat

#!/bin/bashecho "stop ksm"systemctl stop ksmsystemctl stop ksmtunedecho "---free -m---"free -mfor i in {1..3};do qemu-img create -f qcow2 -o backing_file="/images/" /images/cirros-${i}.qcow2 echo "starting the No. ${i} " qemu-kvm -smp 1 -m 1024m /images/cirros-${i}.qcow2 -daemonize sleep 20doneecho "---free -m---"sleep 10free -mecho "---starting services: ksm "systemctl start ksmsystemctl start ksmtunedsleep 300echo "---free -m command output with ksm and ksmtuned running."free -mecho "KSM saved: $(($(cat /sys/kernel/mm/ksm/pages_sharing) * $(getconf PAGESIZE) / 1024 / 1024))MB"*****************执⾏如下*****************[root@192.168.118.14 ~]#./

stop ksm---free -m--- total used free shared buff/cache availableMem: 7823 115 7565 8 142 7537Swap: 8063 0 8063Formatting '/images/2', fmt=qcow2 size=41126400 backing_file='/images/' encryption=off cluster_size=65536 lazy_refcounts=off

starting the No. VNC server running on `::1:5900'Formatting '/images/2', fmt=qcow2 size=41126400 backing_file='/images/' encryption=off cluster_size=65536 lazy_refcounts=off

starting the No. VNC server running on `::1:5901'Formatting '/images/2', fmt=qcow2 size=41126400 backing_file='/images/' encryption=off cluster_size=65536 lazy_refcounts=off

starting the No. VNC server running on `::1:5902'---free -m--- total used free shared buff/cache availableMem: 7823 368 7266 8 188 7261Swap: 8063 0 8063---starting services: ksm ---free -m command output with ksm and ksmtuned running. total used free shared buff/cache availableMem: 7823 248 7382 8 191 7377Swap: 8063 0 8063KSM saved: 121MB

以上输出中,从 KSM、ksmtuned 服务开始运⾏之前和之后的 "free -m" 命令看出 used 从 368 降低到 248,明显节约了系统内存。

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688025725a67892.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信