后 Kubernetes 时代的虚拟机管理技术之 kubevirt 篇
后 Kubernetes 时代的虚拟机管理技术之 kubevirt 篇周文韬 kubevirt 是 Red Hat 开源的以容器方式运行虚拟机的项目,是基于 kubernetes 运行,利用 k8s CRD 为增加资源类型 VirtualMachineInstance(VMI),使用 CRD 的方式是由于 kubevirt 对虚拟机的管理不局限于 pod 管理接口。通过 CRD 机制,kubevirt 可以自定义额外的操作,来调整常规容器中不可用的行为。kubevirt 可以使用容器的 image registry 去创建虚拟机并提供 VM 生命周期管理。
Kubevirt 的架构
virt-api:kubevirt 是以 CRD 形式去管理 VM Pod,virt-api 就是所有虚拟化操作的入口,这里面包括常规的 CDR 更新验证、以及 console、vm start、stop 等操作。
virt-controller:virt-controller 会根据 vmi CRD,生成对应的 virt-launcher Pod,并且维护 CRD 的状态。与 kubernetes api-server 通讯监控 VMI 资源的创建删除等状态。
virt-handler:virt-handler 会以 deamonset 形式部署在每一个节点上,负责监控节点上的每个虚拟机实例状态变化,一旦检测到状态的变化,会进行响应并且确保相应的操作能够达到所需(理想)的状态。
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-lanuncher 也会去通知 VMI 去执行终止操作;其次在每个 virt-launcher pod 中还对应着一个 libvirtd,virt-launcher 通过 libvirtd 去管理 VM 的生命周期,这样做到去中心化,不再是以前的虚拟机那套做法,一个 libvirtd 去管理多个 VM。
virtctl:virtctl 是 kubevirt 自带类似 kubectl 的命令行工具,它是越过 virt-launcher pod 这一层去直接管理 VM 虚拟机,可以控制 VM 的 start、stop、restart。
Kubevirt 如何管理虚拟机?
虚拟机镜像制作与管理
虚拟机生命周期管理
虚拟机创建:创建 VM 对象,并同步创建 DataVolume/PVC,从 Harbor 镜像仓库中拉取系统模板镜像拷贝至目标调度主机,通过调度、IP 分配后生成 VMI 以及管理 VM 的 Launcher Pod 从而启动供业务使用的 VM。虚拟机运行:运行状态下的 VM 可以进行控制台管理、快照备份/恢复、热迁移、磁盘热挂载/热删除等操作,此外还可以进行重启、下电操作,提高 VM 安全的同时解决业务存储空间需求和主机异常 Hung 等问题。虚拟机关机:关机状态下的 VM 可以进行快照备份/恢复、冷迁移、CPU/MEM 规格变更、重命名以及磁盘挂载等操作,同时可通过重新启动进入运行状态,也可删除进行资源回收。虚拟机删除:对虚机资源进行回收,但 VM 所属的磁盘数据仍将保留、具备恢复条件。
虚拟机创建流程
虚拟机创建分为创建 DataVolume 和 VMI 两个流程:
1.创建 DataVolume 后,CDI 组件创建对应的 PVC 并且关联到合适的 PV,然后通过临时 Importer Pod 拉取虚拟机容器镜像绑定到 DataVolume 生成的 PV 中,并且将镜像转换成 disk.img 文件存储在 PV 中供虚拟机使用。
2.创建 VMI 后,等待 disk.img 转换成功,然后在对应的 Node 上启动 Launcher Pod,并将 CDI 流程生成的 PV 挂载到 Pod 内,当做虚拟机启动的系统盘。Launcher 根据 VMI 的定义生成定义虚拟机的 XML 文件,然后调用 libvirt 进程调用 Qemu 命令创建并且启动虚拟机。VMI 会对 Launcher Pod 状态进行同步,反应 VM 运行的状态。
Kubevirt 如何实现容器与虚拟机交互 TBD
容器和虚拟机互通
Virtual-Kubelet 对应的 Node 会上报节点上 Pod 的 Endpoint,假定 Kubernetes 集群和 IaaS 层平台部署在同一个二层网络下,则集群内容器 Pod 可以访问 VM-Pod,但容器 Pod 对于 VM-Pod 不可见;
针对上一点可以通过 Macvlan 等网络插件,将容器-Pod,降维至二层网络上,实现容器-Pod 和虚拟机互通,有一定硬件要求。
如何实现⼀套集群下虚拟机与容器的混合调度与资源隔离
Virtual-Kubelet 提供的是一个虚拟节点用来向 Kubernetes 上报 Node 对象和 Pod 的状态和资源情况,虚拟机资源和集群内节点资源完全隔离;
在引入 Virtual-Kubelet 的情况下,需要对 Virtual-Kubelet 节点配置 Taint 和 Tolerations,保证容器-Pod 和 VM-Pod 调度分离。
服务发现
Virtual-Kubelet,通过 Provider 实现的 API 将 IaaS 层 VM 信息抽象成对应 Pod 对象的信息的方式来上报 Endpoints,可以通过给 CR 添加 no selector Service,待 VM-Pod 拉起后补充 address 至对应的 Service
Kubevirt 适用场景
由于 Kubervirt 提供的成熟的虚拟化能力和性能,并且可以直接通过 Kubernetes 进行统一管理。所以 Kubevirt 适合在有 PaaS 层管理平台和 Kubernetes 集群环境的情况下,通过 kubevirt 中的单一控制平面简化了对虚拟机的管理,让用户无需关心 IaaS 层,即可轻松在集群内构建、部署出一台虚拟机进行使用。
如何搭建 Kubevirt
Kubevirt 安装
1.前置条件查看硬件是否支持虚拟化
如果虚拟化不可用,则需要手动开启软件仿真
2.安装 Kubevirt 组件直接操作以下命令进行安装
3.检查实例是否正常运行
4.启动相关特性修改 kubevirt-config configmap 内的数据
5.安装 virtctl 安装 kubevirt 命令行工具
6.安装 CDICDI(containerized-data-importer) 是 kubernetes 的持久存储管理插件,帮助 kubevirt 构建磁盘镜像,可以将不同来源的数据源(url、container image、upload....)来填充 pvc 的能力。获取最新版,进行安装
安装完毕后,会在 cdi namespace 下,启动 cdi 相关组件
创建虚拟机
1.准备一个虚拟机镜像
2.创建一台 VM 编辑好 yaml 文件,通过 kubectl 命令拉起一台 vm
版权声明: 本文为 InfoQ 作者【谐云】的原创文章。
原文链接:【http://xie.infoq.cn/article/fa3463c782321149e5e1a01b4】。文章转载请联系作者。
评论