大家好,我是张晋涛。
随着云计算和容器技术的发展,Kubernetes 已经成为了业界的标准和领导者,为用户提供了一个强大,灵活和可扩展的平台,来部署和管理各种类型的应用。
然而,对于一些难以容器化的应用,例如传统的企业应用,遗留的系统,或者需要特殊硬件支持的应用,虚拟机仍然是一个必要和有效的解决方案。
如何在 Kubernetes 上运行和管理虚拟机,以及如何实现容器和虚拟机之间的互操作性和一致性,是一个亟待解决的问题。
这就是 KubeVirt 项目诞生的背景和目标。
KubeVirt 是一个开源项目,它使得虚拟机可以像容器一样被 Kubernetes 部署,消费和管理。它提供了一个统一的平台,让用户可以根据不同的需求,使用容器或者虚拟机来构建云原生应用。KubeVirt 项目于 2016 年启动,由 Red Hat, IBM, Google, Intel, SUSE 等多家公司和组织共同推动和贡献。经过 7 年的不懈努力,KubeVirt 于 2023 年 7 月发布了 v1.0.0 版本,标志着它已经达到了生产就绪的水平,并且有着健康的社区。(在此之前,它已经被很多公司用到了生产环境)
在这篇中,我将回顾 KubeVirt 的发展历程,介绍 KubeVirt 的核心功能和优势,以及分析 KubeVirt 的未来展望和挑战。
KubeVirt 的发展历程
KubeVirt 的想法最早可以追溯到 2015 年,在第一届 KubeCon 上 Red Hat 的工程师 Fabian Deutsch 提出了一个问题:能否在 Kubernetes 上运行虚拟机?当时的回答是不确定的,但是这个问题引起了很多人的兴趣和讨论。在接下来的一年里,Fabian Deutsch 和他的同事开始了一些原型和实验性的工作,探索了不同的方案和技术。最终,他们选择了使用 libvirt 和 QEMU 来实现虚拟机在 Kubernetes 上的运行和管理。
在 2016 年底,KubeVirt 项目正式启动,并在 GitHub 上开源。项目的主要目标是提供一个 Kubernetes 原生的虚拟化 API 和运行时,让用户可以像使用 Pod 和 Deployment 一样使用 VirtualMachine 和 VirtualMachineInstance 来定义和管理虚拟机。项目的主要挑战是如何将虚拟机与 Kubernetes 的资源模型,调度器,网络,存储等组件进行集成和协调。
在接下来的几年里,KubeVirt 项目经历了多个阶段和版本的迭代和改进。其中一些重要的里程碑包括:
- 2017 年底,KubeVirt 实现了基本的虚拟机创建和删除功能,并发布了 v0.1.0 版本。
- 2018 年初,KubeVirt 重新设计了 VirtualMachine 的 API,并发布了 v0.2.0 版本。
- 2018 年中,KubeVirt 兼容了 Kubernetes 的网络,以及离线虚拟机支持,并发布了 v0.3.0 版本。
- 2018 年底,KubeVirt 支持了初始化空 PV,以及 liveness 和 readiness,并发布了 v0.9.0 ~ v0.11.0 版本。
- 2019 年中,KubeVirt 支持了
virtctl migrate
,并发布了 v0.21.0 版本。 - 2022 年初,KubeVirt 移除了旧的对 GPU 设备的支持,可以通过统一的方式进行定义,并发布了 v0.50.0 版本。
- 2023 年中,KubeVirt 发布了 v1.0.0 版本。
其实可以看到 KubeVirt 虽然一直没有发布 v1.0 版本,但是却一直保持着比较频繁的发布频率。
在这个过程中,KubeVirt 的社区也不断地壮大和活跃。截至目前,KubeVirt 的 GitHub 仓库已经有超过 270 个贡献者,超过 17k 提交,超过 4.5k star。
KubeVirt 的用户和合作伙伴也在不断地增加,包括 IBM, Google, Intel, SUSE, Red Hat, Huawei, VMware, Canonical, Rancher 等多家知名公司和组织。
KubeVirt 的核心功能和优势
KubeVirt 的核心功能是在 Kubernetes 上运行和管理虚拟机。为了实现这个功能,KubeVirt 提供了以下几个方面的解决方案:
虚拟化 API
KubeVirt 定义了一套 Kubernetes 原生的虚拟化 API,让用户可以像使用 Pod 和 Deployment 一样使用 VirtualMachine 和 VirtualMachineInstance 来定义和管理虚拟机。VirtualMachine 是一种声明式的资源类型,表示一个期望的虚拟机状态。VirtualMachineInstance 是一种实时的资源类型,表示一个正在运行的虚拟机实例。用户可以通过 YAML 文件或者 kubectl 命令来创建,更新,删除或者查询这些资源。例如:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
annotations:
kubevirt.io/latest-observed-api-version: v1
kubevirt.io/storage-observed-api-version: v1
creationTimestamp: "2023-09-01T00:25:41Z"
finalizers:
- kubevirt.io/virtualMachineControllerFinalize
generation: 1
name: testvm
namespace: default
resourceVersion: "12691"
uid: d5509381-5f21-438b-9440-cb7c9ee82b37
spec:
running: false
template:
metadata:
creationTimestamp: null
labels:
kubevirt.io/domain: testvm
kubevirt.io/size: small
spec:
architecture: amd64
domain:
devices:
disks:
- disk:
bus: virtio
name: containerdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- masquerade: {}
name: default
machine:
type: q35
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
name: containerdisk
- cloudInitNoCloud:
userDataBase64: SGkuXG4=
name: cloudinitdisk
这个 YAML 文件定义了一个名为 testvm 的虚拟机,它有 2 个磁盘。其中一个磁盘是一个容器镜像,另一个磁盘是一个云初始化配置。用户可以通过 kubectl apply -f testvm.yaml 来创建这个虚拟机,或者通过 kubectl get vm testvm 来查询它的状态。
moelove $ kubectl get vms
NAME AGE STATUS READY
testvm 3m20s Running True
虚拟化运行时
KubeVirt 实现了一套虚拟化运行时,让用户可以在 Kubernetes 集群中的任何节点上运行和管理虚拟机。KubeVirt 的运行时主要由以下几个组件构成:
- virt-controller:负责监控和调谐虚拟机的状态,以及处理虚拟机的生命周期事件,如创建,删除,启动,停止,迁移等。
- virt-handler:负责在每个节点上执行虚拟机的操作,如启动,停止,暂停,恢复等。它也负责与 libvirt 和 QEMU 进行通信,以及收集和报告虚拟机的性能指标。
- virt-operator:负责在每个节点上启动和管理 libvirt 和 QEMU 进程。
- virt-api:负责提供虚拟化 API 的服务端点,以及验证和转换用户的请求。
moelove $ kubectl get pods -n kubevirt
NAME READY STATUS RESTARTS AGE
virt-operator-6c649b9567-m2tbl 1/1 Running 0 6m36s
virt-operator-6c649b9567-kqfnl 1/1 Running 0 6m36s
virt-api-66859f4c8d-tnf68 1/1 Running 0 5m53s
virt-controller-8545966675-wskv9 1/1 Running 0 5m17s
virt-controller-8545966675-z68gb 1/1 Running 0 5m17s
virt-handler-h8zx4 1/1 Running 0 5m17s
KubeVirt 的运行时采用了 Kubernetes 的原生架构和模式,让用户可以像管理容器一样管理虚拟机。例如:
- 用户可以使用 kubectl logs 命令来查看虚拟机的日志。
网络解决方案
KubeVirt 支持多种网络插件和方案,让用户可以根据不同的需求,为虚拟机提供合适的网络连接和配置。KubeVirt 的网络解决方案主要包括以下几种:
- Pod 网络:这是最简单和最常用的网络方案,它让虚拟机共享 Pod 的网络命名空间和接口。这样,虚拟机就可以像 Pod 一样访问集群内外的网络资源,并且可以被集群内外的网络资源访问。
- 多网络:这是一种更灵活和更高级的网络方案,它让虚拟机可以有多个网络接口,并且可以连接到不同的网络平面。这样,虚拟机就可以根据不同的用途和场景,使用不同的网络策略和配置。例如,一个虚拟机可以有一个用于管理的网络接口,一个用于数据传输的网络接口,和一个用于公网访问的网络接口。
- 桥接网络:这是一种更接近传统虚拟化的网络方案,它让虚拟机可以直接使用节点上的物理网络接口和地址。这样,虚拟机就可以像物理机一样,与节点上的其他设备进行通信,并且可以使用节点上的网络安全和监控工具。
- SR-IOV 网络:这是一种更高性能和更低延迟的网络方案,它让虚拟机可以直接使用节点上的物理网卡的虚拟功能。这样,虚拟机就可以绕过软件层的开销,直接访问硬件层的资源,并且可以享受硬件层的加速和优化。
存储解决方案
KubeVirt 支持多种存储插件和方案,让用户可以根据不同的需求,为虚拟机提供合适的存储空间和配置。KubeVirt 的存储解决方案主要包括以下几种:
- 容器磁盘:这是一种基于容器镜像的存储方案,它让虚拟机可以使用容器镜像作为其根磁盘。这样,虚拟机就可以像容器一样,快速地启动和停止,并且可以享受容器镜像的便利和安全性。
- 持久卷:这是一种基于 Kubernetes 的存储方案,它让虚拟机可以使用 Kubernetes 的持久卷(PV)和持久卷声明(PVC)作为其数据磁盘。这样,虚拟机就可以像 Pod 一样,使用 Kubernetes 的存储类(StorageClass)来动态地申请和释放存储空间,并且可以使用 Kubernetes 的存储插件来连接到不同的存储后端。
- 主机磁盘:这是一种基于节点的存储方案,它让虚拟机可以使用节点上的本地磁盘或者目录作为其数据磁盘。这样,虚拟机就可以利用节点上的存储性能和容量,并且可以避免网络层的开销和延迟。
- CDI 磁盘:这是一种基于 CDI(Containerized Data Importer)项目的存储方案,它让用户可以从不同的来源(如 HTTP, S3, Registry 等)导入或者克隆数据到 Kubernetes 的持久卷中,并且可以自动地转换数据的格式(如 qcow2, raw, vmdk 等)。这样,用户就可以方便地将现有的虚拟机镜像或者数据迁移或者复制到 Kubernetes 中,并且可以使用 KubeVirt 来运行和管理它们。
镜像解决方案
KubeVirt 支持多种镜像插件和方案,让用户可以根据不同的需求,为虚拟机提供合适的镜像源和配置。KubeVirt 的镜像解决方案主要包括以下几种:
- 容器镜像:这是一种基于容器技术的镜像方案,它让用户可以使用容器镜像作为虚拟机的根磁盘或者 CD-ROM。这样,用户就可以利用容器技术的优势,如轻量级,快速启动,易于分发,安全隔离等。
- 虚拟机镜像:这是一种基于传统虚拟化技术的镜像方案,它让用户可以使用虚拟机镜像作为虚拟机的初始化配置。
KubeVirt 的未来
如今 KubeVirt 已经发布 v1.0 版本,红帽作为创始成员,在 OpenShift 虚拟化中携带了 KubeVirt。Kubermatic、Rancher、Google、Oracle 等也提供内置 KubeVirt 的产品。Civio、Puzl、Platform9 和其他公司将 KubeVirt 带到了云端,并提供托管和自管理的产品。
KubeVirt 的价值已经被大家看到,未来也将会有更多的企业将其应用到自己的环境中,并且推动社区的发展。
我在 2019 年左右曾经尝试过 KubeVirt,当时它还不是很成熟,所以最终并没有采纳它,现在我觉得我可以再试试如何将它加入到我的系统中了。
欢迎订阅我的文章公众号【MoeLove】