- Kubevirt 是Redhat开源的以容器方式运行虚拟机的项目,以k8s add-on方式,利用k8s CRD为增加资源类型VirtualMachineInstance(VMI),使用容器的image registry去创建虚拟机并提供VM生命周期管理。
- kubevirt提供vm-import-operator可以支持从vmware导入虚机至kubevirt集群。
- 简单来说:kubevirt只是用k8s管vm,其中会复用k8s的cni和csi,所以只是用operator的方式来操作vm,他不去管网络和存储等。所以和OpenStack中包含nova,neutron,cinder等不一样,可以理解成kubevirt是一个k8s框架下的,用go写的nova vm管理组件。
一、Kubevirt的架构
- virt-api
kubevirt是以CRD形式去管理vm pod, virt-api就是所有虚拟化操作的入口,包括常规的CRD更新验证以及vm start、stop
- virt-controlller
Virt-controller会根据vmi CRD,生成对应的virt-lancher pod,并维护CRD的状态
- virt-handler
Virt-handler会以Daemonset形式部署在每个节点上,负责监控节点上每个虚拟机实例状态变化,一旦检测到状态变化,会进行响应并确保相应操作能达到所需(理想)状态。
Virt-handler保持集群级VMI Spec与相应libvirt域之间的同步;报告Libvirt域状态和集群Spec的变化;调用以节点为中心的插件以满足VMI Spec定义的网络和存储要求。
- virt-launcher
每个virt-lanuncher pod对应着一个VMI, kubelet只是负责virt-lanuncher pod运行状态,不会去关心VMI创建情况。
virt-handler会根据CRD参数配置去通知virt-lanuncher去使用本地libvirtd实例来启动VMI, virt-lanuncher就会如果pid去管理VMI,pod生命周期结束,virt-lanuncher也会去通知VMI去终止。
每个virt-lanuncher pod对应一个libvirtd,virt-lanuncher通过libvirtd去管理VM的生命周期,这样做到去中心化,不再是以前虚拟机那套做法,一个libvirtd去管理多个VM。
- virtctl
virctl 是kubevirt自带类似kubectl命令,它是越过virt-lancher pod这层去直接管理vm,可以控制vm 的start、stop、restart。
总结: kubevirt以CRD形式将VM管理接口接入到kubernetes,通过一个pod去使用libvirtd管理VM方式,实现pod与VM的一对一对应,做到如同容器一般去管理虚拟机,并且做到与容器一样的资源管理、调度规划,这个整体与企业iaas关系不大,也方便企业接入
二、Kubevirt如何管理虚拟机?
虚拟机镜像采用容器镜像形式存放在镜像仓库中。创建原理如上图所示,将Linux发行版本的镜像文件存放到基础镜像的/disk目录内,镜像格式支持qcow2、raw、img。通过Dockerfile文件将虚拟机镜像制作成容器镜像,然后分别推送到不同的registry镜像仓库中。客户在创建虚拟机时,根据配置的优先级策略拉取registry中的虚拟机容器镜像,如果其中一台registry故障,会另一台健康的registry拉取镜像。
虚拟机生命周期管理
KubeVirt虚拟机生命周期管理主要分为以下几种状态:
上述架构里其实已经部分简述了VM的创建流程,以下进行流程梳理:
- K8S API 创建VMI CRD对象
- virt-controller监听到VMI创建时,会根据VMI配置生成pod spec文件,创建virt-launcher pods
- virt-controller发现virt-launcher pod创建完毕后,更新VMI CRD状态
- virt-handler监听到VMI状态变更,通信virt-launcher去创建虚拟机,并负责虚拟机生命周期管理
虚拟机创建分为创建DataVolume和VMI两个流程:
- 创建DataVolume后,CDI组件创建对应的PVC并且关联到合适的PV,然后通过临时Importer Pod拉取虚拟机容器镜像绑定到DataVolume生成的PV中,并且将镜像转换成disk.img文件存储在PV中供虚拟机使用。
- 创建VMI后,等待disk.img转换成功,然后在对应的Node上启动Launcher Pod,并将CDI流程生成的PV挂载到Pod内,当做虚拟机启动的系统盘。Launcher根据VMI的定义生成定义虚拟机的XML文件,然后调用libvirt进程调用Qemu命令创建并且启动虚拟机。VMI会对Launcher Pod状态进行同步,反应VM运行的状态