这篇文章发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不正确。
了解 Kubevirt
一旦您习惯在 Kubernetes 上运行 Linux 容器工作负载,您可能会希望在 Kubernetes 集群上运行其他类型的工作负载。也许您需要运行一个未针对容器架构的应用,或者需要与容器主机上可用的 Linux 内核不同的版本——或者完全不同的操作系统。
这些类型的工作负载通常非常适合在虚拟机 (VM) 中运行,而 KubeVirt 是 Kubernetes 的虚拟机管理附加组件,旨在允许用户在 Kubernetes 或 OpenShift 集群中与容器一起运行虚拟机。
KubeVirt 通过 Kubernetes 的 自定义资源定义 API (CRD) 添加虚拟机和虚拟机集的资源类型来扩展 Kubernetes。KubeVirt 虚拟机在常规 Kubernetes Pod 中运行,在那里它们可以访问标准的 Pod 网络和存储,并且可以使用 kubectl 等标准 Kubernetes 工具进行管理。
与使用 oVirt 或 OpenStack 等工具相比,使用 Kubernetes 运行虚拟机需要进行一些调整,了解 KubeVirt 的基本架构是一个很好的起点。
在这篇文章中,我们将从高层次讨论 KubeVirt 中涉及的一些组件。我们将研究的组件包括 CRD、KubeVirt virt-controller、virt-handler 和 virt-launcher 组件、libvirt、存储和网络。
KubeVirt 组件

自定义资源定义
Kubernetes 资源是 Kubernetes API 中的端点,用于存储相关 API 对象的集合。例如,内置的 pods 资源包含 Pod 对象的集合。Kubernetes 自定义资源定义 API 允许用户通过定义具有给定名称和架构的新对象来使用其他资源扩展 Kubernetes。一旦您将自定义资源应用于集群,Kubernetes API 服务器就会提供并处理自定义资源的存储。
KubeVirt 的主要 CRD 是 VirtualMachine (VM) 资源,它在 Kubernetes API 服务器中包含 VM 对象的集合。VM 资源定义了虚拟机本身的所有属性,例如机器和 CPU 类型、RAM 和 vCPU 的数量,以及虚拟机中可用的网卡数量和类型。
virt-controller
virt-controller 是一个 Kubernetes Operator,负责集群范围内的虚拟化功能。当新的 VM 对象发布到 Kubernetes API 服务器时,virt-controller 会注意到并在其中运行虚拟机的 Pod。当 Pod 在特定节点上调度时,virt-controller 会使用节点名称更新 VM 对象,并将进一步的职责移交给节点特定的 KubeVirt 组件 virt-handler,该组件的实例在集群中的每个节点上运行。
virt-handler
与 virt-controller 一样,virt-handler 也是被动的,监视 VM 对象的变化,并执行所有必要的操作以更改 VM 以满足所需的状态。virt-handler 引用 VM 规范,并使用 VM Pod 中的 libvirtd 实例发出创建相应域的信号。当 VM 对象被删除时,virt-handler 会观察到删除并关闭域。
virt-launcher
对于每个 VM 对象,都会创建一个 Pod。此 Pod 的主容器运行 virt-launcher KubeVirt 组件。virt-launcher Pod 的主要目的是提供将用于托管 VM 进程的 cgroups 和命名空间。
virt-handler 通过将 VM 的 CRD 对象传递给 virt-launcher 来发出信号以启动 VM。然后,virt-launcher 使用其容器中的本地 libvirtd 实例来启动 VM。从那里开始,virt-launcher 监视 VM 进程,并在 VM 退出后终止。
如果 Kubernetes 运行时尝试在 VM 退出之前关闭 virt-launcher Pod,virt-launcher 会将 Kubernetes 的信号转发到 VM 进程,并尝试阻止 Pod 的终止,直到 VM 成功关闭。
# kubectl get pods
NAME READY STATUS RESTARTS AGE
virt-controller-7888c64d66-dzc9p 1/1 Running 0 2h
virt-controller-7888c64d66-wm66x 0/1 Running 0 2h
virt-handler-l2xkt 1/1 Running 0 2h
virt-handler-sztsw 1/1 Running 0 2h
virt-launcher-testvm-ephemeral-dph94 2/2 Running 0 2h
libvirtd
每个 VM Pod 中都存在一个 libvirtd 实例。virt-launcher 使用 libvirtd 来管理 VM 进程的生命周期。
存储和网络
KubeVirt 虚拟机可以使用由卷支持的磁盘进行配置。
持久卷声明卷使 Kubernetes 持久卷可作为直接连接到虚拟机的磁盘使用。这是为 KubeVirt 虚拟机提供持久存储的主要方法。目前,持久卷必须是 iscsi 块设备,尽管正在进行启用基于文件的 pv 磁盘的工作。
临时卷是本地写入时复制映像,它使用网络卷作为只读后备存储。当虚拟机启动时,KubeVirt 动态生成与虚拟机关联的临时映像,并在虚拟机停止时丢弃临时映像。目前,临时卷必须由 pvc 卷支持。
注册表磁盘卷引用嵌入 qcow 或原始磁盘的 docker 映像。顾名思义,这些卷是从容器注册表中提取的。与常规临时容器映像一样,这些卷中的数据仅在 Pod 存在时才持续存在。
CloudInit NoCloud 卷为虚拟机提供 cloud-init NoCloud 用户数据源,该数据源作为磁盘添加到虚拟机,虚拟机可在其中使用该数据源向安装了 cloud-init 的来宾提供配置详细信息。Cloud-init 详细信息可以以纯文本形式、base64 编码的 UserData 文件或通过 Kubernetes 密钥提供。
在下面的示例中,配置了一个注册表磁盘以提供从中启动虚拟机的映像。提供了一个 cloudInit NoCloud 卷,并与存储为 userData 字段中的纯文本的 ssh 密钥配对,用于与虚拟机进行身份验证。
apiVersion: kubevirt.io/v1alpha1
kind: VirtualMachine
metadata:
name: myvm
spec:
terminationGracePeriodSeconds: 5
domain:
resources:
requests:
memory: 64M
devices:
disks:
- name: registrydisk
volumeName: registryvolume
disk:
bus: virtio
- name: cloudinitdisk
volumeName: cloudinitvolume
disk:
bus: virtio
volumes:
- name: registryvolume
registryDisk:
image: kubevirt/cirros-registry-disk-demo:devel
- name: cloudinitvolume
cloudInitNoCloud:
userData: |
ssh-authorized-keys:
- ssh-rsa AAAAB3NzaK8L93bWxnyp [email protected]
与常规 Kubernetes Pod 一样,基本网络功能会自动提供给每个 KubeVirt VM,并且可以使用常规 Kubernetes 服务将特定的 TCP 或 UDP 端口暴露给外部世界。不需要特殊的网络配置。
参与其中
KubeVirt 开发正在加速,该项目渴望新的贡献者。如果您有兴趣参与其中,请查看该项目的 未解决的问题并查看 项目日历。
如果您需要一些帮助或想聊天,可以通过 freenode IRC 中的 #kubevirt 或在 KubeVirt 邮件列表中与团队联系。用户文档可在 https://kubevirt.gitbooks.io/user-guide/ 获得。