向日葵 | 2019-01-9
kvm实现主要基于Intel-V或者AMD-V提供的虚拟化平台,利用普通的Linux进程运行于虚拟态的指令集,模拟虚拟机监视器和CPU。kvm不提供硬件虚拟化操作,其IO操作等都借助QEMU来完成。关于kvm虚拟化的概念和kvm虚拟化如何搭建是什么很多人都不了解。本文小编将为您详细介绍kvm虚拟化。
kvm 全称 kernel-based virtual machine,由Qumranet公司发起,2008年被RedHat收购。
kvm有如下特点:
guest作为一个普通进程运行于宿主机
guest的CPU(vCPU)作为进程的线程存在,并受到宿主机内核的调度
guest继承了宿主机内核的一些属性,比如huge pages(大页表)
guest的磁盘IO和网络IO会受到宿主机的设置的影响
guest通过宿主机上的虚拟网桥与外部相连。
虚拟CPU
guest的所有用户级别(user)的指令集,都会直接由宿主机线程执行,此线程会调用kvm的ioctl方式提供的接口加载guest的指令并在特殊的CPU模式下运行,不需要经过CPU指令集的软件模拟转换,大大的减少了虚拟化成本,这也是kvm优于其他虚拟化方式的点之一。
kvm向外提供了一个虚拟设备/dev/kvm,通过ioctl(IO设备带外管理接口)来对kvm进行操作,包括虚拟机的初始化,分配内存,指令加载等等。
虚拟IO设备
guest作为一个进程存在,当然他的内核的所有驱动等都存在,只是硬件被QEMU所模拟(后面介绍virtio的时候特殊)。guest的所有硬件操作都会有QEMU来接管,QEMU负责与真实的宿主机硬件打交道。
虚拟内存
guest的内存在host上由emulator提供,对emulator来说,guest访问的内存就是他的虚拟地址空间,guest上需要经过一次虚拟地址到物理地址的转换,转换到guest的物理地址其实也就是emulator的虚拟地址,emulator再次经过一次转换,转换为host的物理地址。后面会有介绍各种虚拟化的优化手段,这里只是做一个overview。
虚拟机启动过程
第一步,获取到kvm句柄
kvmfd = open("/dev/kvm", O_RDWR);
第二步,创建虚拟机,获取到虚拟机句柄。
vmfd = ioctl(kvmfd, kvm_CREATE_VM, 0);
第三步,为虚拟机映射内存,还有其他的PCI,信号处理的初始化。
ioctl(kvmfd, kvm_SET_USER_MEMORY_REGION, &mem);
第四步,将虚拟机镜像映射到内存,相当于物理机的boot过程,把镜像映射到内存。
第五步,创建vCPU,并为vCPU分配内存空间。
ioctl(kvmfd, kvm_CREATE_VCPU, vcpuid);
vcpu->kvm_run_mmap_size = ioctl(kvm->dev_fd, kvm_GET_VCPU_MMAP_SIZE, 0);
第五步,创建vCPU个数的线程并运行虚拟机。
ioctl(kvm->vcpus->vcpu_fd, kvm_RUN, 0);
第六步,线程进入循环,并捕获虚拟机退出原因,做相应的处理。
这里的退出并不一定是虚拟机关机,虚拟机如果遇到IO操作,访问硬件设备,缺页中断等都会退出执行,退出执行可以理解为将CPU执行上下文返回到QEMU。
open("/dev/kvm")
ioctl(kvm_CREATE_VM)
ioctl(kvm_CREATE_VCPU)
for (;;) {
ioctl(kvm_RUN)
switch (exit_reason) {
case kvm_EXIT_IO: / ... /
case kvm_EXIT_HLT: / ... /
}
}
关于kvm_CREATE_VM参数的描述,创建的VM是没有cpu和内存的,需要QEMU进程利用mmap系统调用映射一块内存给VM的描述符,其实也就是给VM创建内存的过程。
“向日葵控控A2”目前具有远程桌面和远程监控的功能,可通过移动端、web端、PC端远程控制异地主机,实现远程控制kvm的功能。它区别于软件的优势在于,以物理性远程的手段,完全脱离主机和系统的限制,适配所有系统,甚至Windows CE、DOS等,以及各种有视频输出与USB控制输入接口的设备,如智能电脑、广告机等。即使主机屏蓝屏、死机、断网,都能直达Bios界面控制操作。并且,支持1920*1080高清分辨率,即插即用,傻瓜式操作。
升级后的向日葵控控,连接一个支持热键切换的KVM切换器,组成多口IPKVM,还能控制多台主机,可以满足更多使用场景。这样,无论家庭,还是企业,尤其是机房、实验室等需要维护、监控局域网多台主机的时候,控控都有用武之地。