第一眼看到 KubeVirt 这个词,对技术有些了解的人基本都会知道,Kube 代表了 Kubernetes 容器化平台,而 Virt 则是以 OpenStack 为代表的虚拟化平台及虚拟化的缩写。近几年Kubernetes 的大热,相伴随的是 OpenStack 虚拟化平台的落寞,KubeVirt 的出现,似乎有一种重整旧山河,王者归来的霸气。
前几年 Kubernetes 与 OpenStack 各自大行其道时,鉴于容器的安全性、网络隔离等问题,有很多方案在探讨如何在虚拟机上运行容器,典型的如 Magnum,可以通过成熟的多租户以及网络虚拟化来更好地控制容器的生命周期。而 KubeVirt 反其道而行,用 Kubernetes 平台来管理虚拟机。
01 KubeVirt 是什么?
KubeVirt 是一个 Kubernetes 插件,由 Redhat 开源,在调度容器之余也可以调度传统的虚拟机。它通过使用自定义资源(CRD)和其它 Kubernetes 功能来无缝扩展现有的集群,以提供一组可用于管理虚拟机的 API 。
KubeVirt 并不是虚拟化平台的替代品,它只是利用 Kubernetes 的整体框架以及 CRD 来管理 VM,底层调用的依旧是基于 libvirt 的机制,类比为 OpenStack 中的 Nova,并不涉及网络、存储等相关内容。
除了 KubeVirt,近几年来也涌现出不少类似的技术,例如 Virtlet,Kata 等。Virtlet 是将 POD、VM 两个并不完全匹配的概念映射在了一起,结果导致在 virtlet 中并不存在迁移等概念,所以也就不是一个标准的 VM ;Kata 则有着更快的速度以及更好的安全性,但依旧不是一个完整的 VM 管理方案。
K8S 容器平台是未来业务容器化平台的主流方向,但虚拟机 VM 依然会长期存在,对于那些因为历史代码、操作系统老旧等问题而无法迁移到容器平台的业务,KubeVirt 给出了完美的解决方案,有了 KubeVirt,虚拟机可以与容器无缝地衔接在一起。Rancher 还基于 K8S、KubeVirt 发布了开源的超融合基础架构软件 Harvester。
至此,容器与 IaaS 殊途同归。
列项 | KubeVirt | Kata-container | virtlet |
支持虚拟机系统 | Linux, windows | Linux | 社区已经不活跃 |
安全程度 | 虚拟机安全 | 虚拟机安全 | |
启动速度 | 虚拟机启动速度 | 接近容器启动速度 | |
虚拟机完整功能 | 支持 | 不支持 |
功能对比图
02 KubeVirt 结构
KubeVirt 主要包括4个组件 irt-api、Virt-controller、Virt-handler、Virt-launcher ,并且利用 CRD 的功能,定义了若干种资源对象。
- VirtualMachineInstance(VMI):类似于 Kubernetes Pod,是管理虚拟机的最小资源。一个 VirtualMachineInstance 对象即表示一台正在运行的虚拟机实例,包含一个虚拟机所需要的各种配置。
- VirtualMachine(VM):为群集内的 VirtualMachineInstance 提供管理功能,例如开机/关机/重启虚拟机,确保虚拟机实例的启动状态,与虚拟机实例是 1:1 的关系,类似与 spec.replica 为 1 的 StatefulSet。
- VirtualMachineInstanceMigrations:提供虚拟机迁移的能力,虽然并不会指定具体迁移的目的节点,但要求提供的存储支持 RWX 读写模式。
- VirtualMachineInstanceReplicaSet:类似ReplicaSet,可以启动指定数量的 VirtualMachineInstance,并且保证指定数量的 VirtualMachineInstance 运行,可以配置 HPA。
组件 | 功能 |
virt-api | 类似于 kube-api , 提供 http restful , 虚拟化操作的入口,包括常规的 CRD 更新验证以及 vm start、stop 。 |
virt-controlller | 是 Kubernetes 的控制器,用于管理集群中的 VM 生命周期 ,会根据 VMI CRD ,生成对应的 virt-launcher pod ,并维护 CRD 的状态 。 |
virt-handler | Virt-handler 会以 Daemonset 形式部署在每个节点上,负责监控节点上每个虚拟机实例状态变化,一旦检测到状态变化,会进行响应并确保相应操作能达到所需(理想)状态。Virt-handler 保持集群级 VMI Spec 与相应 libvirt 域之间的同步,报告 Libvirt 域状态和集群 Spec 的变化,调用以节点为中心的插件以满足 VMI Spec 定义的网络和存储要求。 |
virt-launcher | 每个 virt-launcher pod 对应着一个 VMI , kubelet 只是负责 virt-launcher pod 运行状态,不会去关心 VMI 创建情况。virt-handler 会根据 CRD 参数配置去通知 virt-launcher 使用本地 libvirtd 实例来启动 VMI ,pod 生命周期结束,virt-launcher 也会去通知 VMI 去终止。每个 virt-launcher pod 对应一个 libvirtd ,virt-launcher 通过 libvirtd 去管理 VM 的生命周期,不再是以前虚拟机的做法,一个 libvirtd 去管理多个 VM 。 |
KubeVirt 结构各组件功能
03 KubeVirt 存储
KubeVirt 中提供多种方式的虚拟机磁盘,磁盘使用方式非常灵活。以下列出几种比较常用的:
- CloudInitNoCloud/CloudInitConfigDrive :用于提供 cloud-init 初始化所需要的 user-data,使用 configmap 作为数据源。
- PersistentVolumeClain:使用 PVC 作为后端存储,适用于数据持久化;PV 类型可以为块存储或者文件系统(filesystem),使用 filesystem 时,会使用 PVC 上的 /disk.img,格式为 RAW 的文件作为硬盘。
- ContainerDisk:镜像中包含虚拟机启动需要的所有内容,可以将它们推送到 registry,使用时拉取镜像,直接使用 containerDisk 作为 VMI 的磁盘,但数据无法持久化。
04 KubeVirt With YRCloudFile
首先在一个 Working 的 K8S + YRCloudFile CSI 的环境上,我们来安装 KubeVirt。
有了以上的基础内容,我们就可以用 ISO 来装一个虚拟机了,我们以 CentOS 为例,首先将ISO 上传到 PVC 供后续安装使用。
在上述文件中,我们利用 YRCloudFile PV 来承载 CDROM ISO 以及虚拟机的系统盘。随后使用上述 yaml 文件创建虚拟机:
安装完重启后,我们可以登录到虚拟机内,完整的虚拟机即可呈现在眼前。
那么虚拟机是如何被创建出来的呢?我们可以到对应的 virt-launcher POD 内一探究竟,首先观察一下 virt-launcher 的日志:
进入到 virt-launcher 进一步深挖,我们看到每个 virt-launcher 创建了一个虚拟机,虚拟机定义文件内所配置的 disk 路径即为在 launcher 容器内挂载的 YRCloudFile PVC 内对应的磁盘文件。
到这里,我们共同见证了 KubeVirt 与 YRCloudFile 完美结合的过程, 而这完美的结合也成功的运用到了实际的案例场景中。
日前, 秒云与焱融科技强强联手成功落地电力设计行业云原生超融合虚拟化场景,秒云容器云平台的云原生虚拟化功能是基于 Kubernetes+Kubevirt 等云原生开源组件,可在一套平台上同时管理容器和虚拟机,结合焱融 YRCloudFile 云原生分布式文件系统,实现了基于云原生技术的 GPU 云桌面超融合部署方案,为用户提供了高性能的基于容器的 GPU 云桌面平台,降低投入成本,实现了存储资源的自动化调度和使用。
KubeVirt + YRCloudFile 联合解决方案对电网、能源等行业的设计规划业务是一次重要的创新,解决了用户对 GPU 设计平台更高效利用,以及高性能数据访问的实际问题。