根据Garnter的最新预测,到2022年将会有75%的生产应用全部跑在容器环境之上。基于这个预测,其实至少还有25%的架构由于技术原因或是认为原因都将仍然跑在旧的架构之上,这其中虚拟机又会占据其中的大部分份额。所以在容器技术尤其是Kubernetes诞生之初,就已经有开源的社区在为如何使用Kubernetes纳管虚拟机作为一个重要的功能在开发和贡献。

今天要介绍的主角就是Kube-virt,那么使用Kube-virt主要会帮我们解决以下两个问题:
🔹从技术层面,完全的虚拟机纳管,可以完美迁移因为内核版本过于陈旧以及语言问题而无法迁移到容器的部分应用
🔹从管理和运维层面,符合传统的运维工作方式,以前的SSH 等运维方式可以完美复用

架构

为什么kube-virt可以做到让虚拟机无缝的接入到K8S?
首先,先给大家介绍一下它的整体架构。
在这里插入图片描述

  • 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关系不大,也方便企业接入。

流程

上述架构里其实已经部分简述了VM的创建流程,以下进行流程梳理:

  1. K8S API 创建VMI CRD对象 virt-controller监听到VMI创建时,会根据VMI配置生成pod
  2. spec文件,创建virt-launcher pods virt-controller发现virt-launcher
  3. pod创建完毕后,更新VMI CRD状态
  4. virt-handler监听到VMI状态变更,通信virt-launcher去创建虚拟机,并负责虚拟机生命周期管理

存储

kubevirt 提供很多种存储方式,存储就决定了你使用虚拟机镜像到底什么内核、什么版本,以下主要讲述我看到三种比较常用的形式

  • registryDisk

定义image来创建虚拟机的root disk。virt-controller会在pod定义中创建registryVolume的container,container中的entry服务负责 将spec.volumes.registryDisk.image转化为qcow2格式,路径为pod根目录。
kubevirt 提供了registryDIsk的基础镜像:registry-disk-v1alpha, 根据Dockerfile形式去创建虚拟机镜像,以下是window镜像demo Dockerfile

FROM kubevirt/registry-disk-v1alpha COPY
Windows—server-2012-datacenter-64bit-cn-syspreped—2018-01-15.qcow2
/disk/windows2012dc.img

这个最终我们构建成镜像名:windows2012dc:latest , 最终在CRD表现形式是这样的:

kind: VirtualMachineInstance

spec:
domain:
devices:
disks:
- disk:
bus: virtio
name: registrydisk
volumeName: registryvolume … - name: registryvolume registryDisk:
image: windows2012dc:latest

  • PVC

PVC是持久化存储镜像的形式,它会被挂在到pod中,且格式必须满足/disk/*.img,这样kubevirt才能够实现虚拟机存储。

  • CDI

CDI是kubevirt自己提供的一种形式, 把registryDisk 转换为PVC,这个需要消耗时间去讲镜像转换为PVC持久化存储下来。

网络

虚拟机网络就是pod网络,virt-launcher pod网络的网卡不再挂有pod ip,而是作为虚拟机的虚拟网卡的与外部网络通信的交接物理网卡,virt-launcher实现了简单的单ip dhcp server,就是需要虚拟机中启动dhclient,virt-launcher 服务会分配给虚拟机。
在这里插入图片描述

监控

Kube-handler会去调用当前节点下所有虚拟机的libvirt API,获取虚拟机的监控指标,并提供metrics 接口,最后通过kubevirt-prometheus-metrics聚合所有节点的kube-handler的指标数据,提供给prometheus使用。

迁移

通过CRD:
VirtualMachineInstanceMigration(VMIM) 来实现动态迁移

apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachineInstanceMigration
metadata:
name: migration-job
spec:
vmiName: vmi-fedora

这种迁移形式其实并没有指定迁移到哪些节点上,内部逻辑应该只是重新调度virt-lanucher pod, 其中kubeirt-config可以对此进行迁移的相关限制,比如迁移的频率(同时只能几个节点进行迁移),迁移的网络速率(因为可能实际到数据磁盘复制), 通过VMIM也能查看到迁移进度。

Kubevirt VS Kata Container

当然Kube-virt并不是目前唯一的可以在Kuberentes上实践虚拟化的技术。我们把它也和目前比较流行的kata container做了一个对比,方便用户根据实际情况来做选择。
在这里插入图片描述


点击查看原文
或扫描下方的微信公众号二维码查询
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐