KubeVirt虚拟化管理架构
目录
一. KubeVirt简介
1.1 KubeVirt的价值
1.2 KubeVirt架构
1.3 KubeVirt组件
1.4 KubeVirt流程管理
KubeVirt实战
2.1 Kubevirt安装
2.1.1节点规划
2.1.2 环境准备
2.1.3 安装KubeVirt
2.1.4 安装CDI
2.1.5 安装virtctl命令工具
2.1.6 生成官方虚拟机
2.1.7 进入虚拟机控制台
2.2 KubeVirt基本命令
2.2.1 创建、列出VM
2.2.2 启动、查看VM
2.2.3 暂停、取消暂停命令
2.2.4 重启、删除VM
2.3 KubeVirt运行策略
2.3.1 容器与虚拟机的统一管理
2.3.2 Kubernetes 与虚拟化的结合
2.4 KubeVirt 存储
2.4.1 KubeVirt 存储类型
2.5 KubeVirt 网络
2.5.1 KubeVirt 网络架构
2.5.2 KubeVirt网络模式
2.5.3 KubeVirt插入方式
2.5.4 KubeVirt卷的类型
一. KubeVirt简介
KubeVirt 是Red-Hat开源的,以容器方式运行的虚拟机项目,旨在将虚拟机(VM)引入 Kubernetes 集群,使用户能够在 Kubernetes 上管理和运行虚拟机,就像管理容器一样。KubeVirt 提供了一种将虚拟机作为 Kubernetes 资源进行管理的方式,从而实现了容器和虚拟机的统一管理
1.1 KubeVirt的价值
什么是kubevirt的价值?就好比说我们为什么需要kubevirt ?
说到这里就不得不说kubernetesl,Kubernetes 是一个强大的容器编排平台,提供了自动化的部署、扩展和管理容器化应用的能力。它的优势包括高可用性、可伸缩性、自我修复能力等,使得越来越多的开发团队选择采用 Kubernetes。
但是,在 Kubernetes 出现之前,虚拟化技术(如 VMware、KVM 等)已经广泛使用。许多关键业务应用和遗留系统都运行在虚拟机上。
虽然 Kubernetes 有许多更好的优势,但并不是所有的应用都能轻松地迁移到容器中。一些复杂的应用、依赖于特定操作系统或硬件的应用、以及需要长期稳定运行的生产系统,可能不适合直接容器化
至此,kubevirt应运而生,kubevirt试图解决有些基于虚拟化的工作负载难以实现容器化的情景
统一管理:KubeVirt 允许用户在同一 Kubernetes 集群中同时管理容器和虚拟机,简化了多工作负载的管理。
兼容 Kubernetes:KubeVirt 完全遵循 Kubernetes 的设计理念,使用相同的 API 和工具链。
灵活的虚拟化:KubeVirt 支持多种虚拟化技术,如 QEMU/KVM,提供了丰富的虚拟机配置选项。
网络和存储集成:KubeVirt 与 Kubernetes 的网络和存储插件无缝集成,支持多种网络和存储方案。
自动化和扩展:KubeVirt 支持自动化部署和扩展虚拟机,可以利用 Kubernetes 的原生功能进行滚动更新和回滚
KubeVirt的应用
Kubecirt是如何应用在kubernetes中?
Kubevirt是通过Kubernetes的自定义资源来定义API资源来扩展的。主要添加了额外的虚拟化资源类型,特别是VMI, VM类型的API资源。然后可以通过kubectl工具去管理这些API资源 (也是说我们通过CRD进行增加关于虚拟机的资源类型,然后通过写YAML的形式来创建虚拟机等一系列的操作)
本身扩展这些资源需要运行额外的控制器和代理,这些控制器和代理都是由Kubevrit来提供。
1.2 KubeVirt架构
KubeVirt 的核心功能是在 Kubernetes 上运行和管理虚拟机。
KubeVirt 定义了一套 Kubernetes 原生的虚拟化 API,让用户可以像使用 Pod 和 Deployment 一样使用 VirtualMachine 和 VirtualMachineInstance 来定义和管理虚拟机。VirtualMachine 是一种声明式的资源类型,表示一个期望的虚拟机状态。VirtualMachineInstance 是一种实时的资源类型,表示一个正在运行的虚拟机实例。用户可以通过 YAML 文件或者 kubectl 命令来创建,更新,删除或者查询这些资源
KubeVirt 实现了一套虚拟化运行时,让用户可以在 Kubernetes 集群中的任何节点上运行和管理虚拟机。
这里还有一个简化版的架构图,Agent就是virt-hander
1.3 KubeVirt组件
通过上一节对kubevirt架构的了解,我们可以发现支撑整个系统架构运行的主要组件有以下几种:
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。
1.4 KubeVirt流程管理
KubeVirt 管理虚拟机的方式基于 Kubernetes 的架构和功能,提供了一套完整的虚拟机生命周期管理解决方案。
自定义资源定义(CRDs)
KubeVirt 使用 Kubernetes 的自定义资源定义(CRDs)来描述虚拟机及其状态。主要的 CRDs 包括:
- VirtualMachine:定义虚拟机的配置,例如 CPU、内存、存储和网络设置。
- VirtualMachineInstance (VMI):表示实际运行的虚拟机实例,包含当前的运行状态和配置信息。
镜像管理
- 虚拟机镜像以容器镜像的形式存放在镜像仓库中,支持多种格式(如
qcow2
、raw
)。 - 用户可以通过 Dockerfile 将虚拟机镜像制作成容器镜像,并推送到不同的 registry。
- 创建虚拟机时,系统根据配置优先级从可用的 registry 中拉取镜像,以确保高可用性。
虚拟机创建流程
- 创建 VMI:用户通过 Kubernetes API 创建
VirtualMachine
资源,这将生成一个 VMI CRD 对象。 - 生成 Pod 规范:KubeVirt 的
virt-controller
监听到 VMI 创建事件,生成相应的virt-launcher
Pod 规范。 - 启动虚拟机实例:
virt-controller
创建virt-launcher
Pod,virt-handler
负责与该 Pod 通信并启动虚拟机。
虚拟机镜像以容器镜像的形式存放在镜像仓库中。
创建过程如下:将 Linux 发行版的镜像文件放置在基础镜像的 /disk
目录下,支持的镜像格式包括 qcow2
、raw
和 img
。通过 Dockerfile 将虚拟机镜像构建为容器镜像,并将其推送到不同的 registry 镜像仓库。在创建虚拟机时,系统根据配置的优先级策略从 registry 中拉取相应的虚拟机容器镜像。如果某个 registry 出现故障,系统会自动从其他健康的 registry 拉取镜像
数据卷管理
- DataVolume:在创建 VMI 之前,通常需要创建
DataVolume
。- CDI(Containerized Data Importer)组件负责创建 PVC,并通过临时 Importer Pod 从镜像仓库拉取镜像,将其绑定到 DataVolume。
- 镜像被转换成
disk.img
文件,存储在 PV 中供虚拟机使用。
生命周期管理
- 状态监控:KubeVirt 监控虚拟机的运行状态,提供以下主要状态:
- 未初始化:VMI 已创建,但尚未启动。
- 初始化中:虚拟机正在启动。
- 运行中:虚拟机成功启动并正常运行。
- 停止:用户停止虚拟机,状态更新。
- 故障:虚拟机发生错误,需要用户介入。
运行时管理
- 虚拟机操作:用户可以通过 kubectl 或 API 进行操作,例如启动、停止、重启、迁移、快照和克隆虚拟机。
- 状态同步:VMI 不断与
virt-launcher
Pod 进行状态同步,确保虚拟机状态与用户操作一致。
监控与日志
- KubeVirt 可以与监控工具(如 Prometheus 和 Grafana)集成,提供实时的虚拟机性能监控和告警功能。
- 日志信息可以通过 Fluentd 等工具集中管理,便于故障排查和审计
KubeVirt实战
2.1 Kubevirt安装
部署所需的yaml包,可自行下载
联合出品合作人:MarkSea
网站:锦梦思隅
2.1.1节点规划
3个kubernetes节点,操作系统为Rocky9.4,kubernetes版本v1.27.1
主机 | 节点 | CPU/内存/磁盘 | IP |
Master | 集群master节点 | 4C/8G/100G | 192.168.2.41 |
Node1 | 集群node1节点 | 4C/8G/100G | 192.168.2.41 |
Node2 | 集群node2节点 | 4C/8G/100G | 192.168.2.41 |
前置要求
在开始之前需要满足一些要求
1. Kubernetes集群或衍生产品(例如OpenShift)基于 KubeVirt 版本发布时发布的最新三个 Kubernetes 版本之一
2. Kubernetes apiserver 必须具有--allow-privileged=true才能运行 KubeVirt 的特权 DaemonSet
3. kubectl客户端实用程序
版本支持矩阵
kubevirt与kubernetes版本兼容性如下表所示:
注意: EOL表示 Kubernetes 版本受 KubeVirt 支持,但已达到生命周期终点
2.1.2 环境准备
3台节点均要执行以下操作
安装所需的软件包
[root@k8s-master ~]# sudo dnf install -y qemu-kvm libvirt virt-install
在执行这下一步之前,先要确保自己的CPU是否已经打开硬件虚拟化功能(CUP是否支持硬件虚拟化可在电脑官方查询)。
硬件虚拟化打开之后,在vmware中。虚拟机选项卡----设置-----处理器----虚拟化引擎,如图2-1,三个选项均要勾选。
查看是否支持虚拟化功能(三台节点均要支持虚拟化功能)
若硬件不支持则需使用软件模拟虚拟化
[root@k8s-master ~]# virt-host-validate qemu
2.1.3 安装KubeVirt
将准备好的yaml包上传到master节点
应用kubevirt-operator.yaml包
[root@k8s-master ~]# kubectl apply -f kubevirt-operator.yaml
查看pod运行状态
[root@k8s-master ~]# kubectl get pods -n kubevirt
应用kubevirt-cr.yaml包
[root@k8s-master ~]# kubectl apply -f kubevirt-cr.yaml
[root@k8s-master ~]# kubectl get pods -n kubevirt
2.1.4 安装CDI
应用cdi的2个yaml包
[root@k8s-master ~]# kubectl apply -f cdi-operator.yaml
[root@k8s-master ~]# kubectl apply -f cdi-cr.yaml
查看pod状态
[root@k8s-master ~]# kubectl get pods -n cdi
2.1.5 安装virtctl命令工具
为适配K8S版本,此处安装版本为 V1.2.1
[root@k8s-master ~]# export RELEASE=V1.2.1
[root@k8s-master~]# wget https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/virtctl-${RELEASE}-linux-amd64
将下载好的安装包移动到/usr/local/bin/virtctl目录下,并给予该目录权限
[root@k8s-master~]# mv virtctl-${RELEASE}-linux-amd64 /usr/local/bin/virtctl
[root@k8s-master ~]# chmod +x /usr/local/bin/virtctl
查看virtctl版本,说明安装成功
[root@k8s-master ~]# virtctl version
2.1.6 生成官方虚拟机
下载官方的vm.yaml文件
[root@k8s-master ~]# wget https://kubevirt.io/labs/manifests/vm.yaml
[root@k8s-master ~]# kubectl apply -f vm.yaml
启动虚拟机
[root@k8s-master ~]# kubectl get vm
[root@k8s-master ~]# virtctl start testvm
查看vmi资源 /mnt/nfs_share
[root@k8s-master ~]# kubectl get vmi
2.1.7 进入虚拟机控制台
[root@k8s-master ~]# virtctl console testvm
login as 'cirros' user. default
password: 'gocubsgo'. use 'sudo' for root.
根据上面提供的用户/密码进行登录
Ctrl+ ] 退出此虚拟机
2.2 KubeVirt基本命令
在 KubeVirt 中创建虚拟机(VM)通常需要使用 virtctl 命令行工具。
在上面部署KubeVirt中就已经安装过了,下面简单列出安装命令
[root@k8s-master ~]# export RELEASE=V1.2.1
[root@k8s-master~]# wget https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/virtctl-${RELEASE}-linux-amd64
查看virtctl版本,说明安装成功
[root@k8s-master ~]# virtctl version
2.2.1 创建、列出VM
方便实验,先创建一个vm-fedora.yaml文件,内容如下
[root@k8s-master ~]# vm-fedora.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: my-vm
namespace: default
spec:
running: false
template:
spec:
domain:
resources:
requests:
memory: 1024M
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
volumes:
- name: containerdisk
containerDisk:
image: kubevirt/fedora-cloud-container-disk-demo:latest
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
创建VM
[root@k8s-master ~]# kubectl apply -f vm-fedora.yaml
列出创建的VM
[root@k8s-master ~]# kubectl get vm
2.2.2 启动、查看VM
启动VM
[root@k8s-master ~]# virtctl start testvm
[root@k8s-master ~]# virtctl start my-vm
查看VM和VMI
[root@k8s-master ~]# kubectl get vm
[root@k8s-master ~]# kubectl get vmi
2.2.3 暂停、取消暂停命令
暂停VM
[root@k8s-master ~]# virtctl pause vm my-vm
或
[root@k8s-master ~]# virtctl pause vmi my-vm
查看暂停后的VMI状态
[root@k8s-master~]# kubectl get vmi
取消暂停VM
[root@k8s-master~]# virtctl unpause vm my-vm
或
[root@k8s-master~]# virtctl unpause vmi my-vm
2.2.4 重启、删除VM
重启VM
[root@k8s-master~]# virtctl restart my-vm
删除VM
[root@k8s-master~]# kubectl delete -f vm-fedora.yaml
2.3 KubeVirt运行策略
KubeVirt 遵循 Kubernetes 的惯例,通常包含 spec
(规范)和 status
(状态)两个部分。spec
是可配置的部分,允许用户以声明式的方式指定集群所需的最终状态。而 status
部分则是不可配置的,它反映了集群中资源的实际状态。简而言之,用户编辑 spec
,控制器则负责更新 status
。
running
字段
在 KubeVirt 中,running
字段位于 VM 的 spec
中,这并不能直接反映 VM 的实际运行状态。因此,即使 spec.running
设置为 true
,也不能保证 VM 实际上正在运行。
runStrategy
如果我们通过客户端关闭 VM,KubeVirt 会重新生成 VM!虽然在高可用性用例中这是合理的,但在大多数情况下,这会导致不必要的混淆。关闭 VM 并不等同于重新启动。
为了解决这些问题,KubeVirt 决定废弃 running
字段,并引入了一个新的字段——runStrategy
。通过使用 runStrategy
,用户状态的变化更大,这与系统实际提供的状态是分离的,因为它们有一些重叠的条件。
目前支持的四种运行策略如下:
Always:如果 VM 因任何原因停止,将生成一个新的实例。
RerunOnFailure:如果 VM 在错误状态下结束执行,将生成一个新的实例。如果用户手动停止 VM,则不会生成新的实例。
Manual:KubeVirt 不会尝试自动启动或停止 VM。用户必须通过 API 调用 start、stop 或 restart 来手动更改 VM 的状态。virtctl 命令行客户端也提供了相应的命令。
Halted:如果 VM 正在运行,它将被停止,并保持关闭状态
为了更直观的感受,我们可以创建一个 Always运行策略的 VM 示例
[root@k8s-master ~]# cat vm-f.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
labels:
kubevirt.io/vm: vm-fedora
name: vm-fedora
spec:
runStrategy: Always
template:
metadata:
labels:
kubevirt.io/vm: vm-fedora
spec:
domain:
resources:
requests:
memory: 1Gi
devices:
disks:
- name: containerdisk
disk:
bus: virtio
volumes:
- name: containerdisk
containerDisk:
image: kubevirt/fedora-cloud-container-disk-demo:latest
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
创建、查看VM
[root@k8s-master~]# kubectl delete -f vm-fedora.yaml
[root@k8s-master ~]# kubectl get vm
[root@k8s-master ~]# kubectl get vmi
除此之外,virtctl的start、stop和restart方法会调用VM的子资源会对VM的运行策略产生的影响
运行策略 | 方法 | 影响 |
Always | start | 确保 VM 处于运行状态,不会改变现有策略 |
stop | 暂时停止 VM,但 KubeVirt 会立即重新启动它 | |
restart | 重启 VM,不会改变现有策略 | |
RerunOnFailure | start | 确保 VM 处于运行状态,不会改变现有策略 |
stop | 暂时停止 VM,如果 VM 是因为错误状态停止的,KubeVirt 会重新启动它 | |
restart | 重启 VM,不会改变现有策略 | |
Manual | start | 使 VM 进入运行状态,状态仍受手动控制 |
stop | 使 VM 进入停止状态,状态仍受手动控制 | |
restart | 重启 VM,状态仍受手动控制 | |
Halted | start | 临时覆盖 Halted 策略,使 VM 进入运行状态 |
stop | VM 已经处于停止状态,不会改变现有策略 | |
restart | 使 VM 进入运行状态,但不会改变现有策略 |
2.3.1 容器与虚拟机的统一管理
KubeVirt 是一个基于 Kubernetes 的扩展项目,旨在实现对虚拟机(VM)和容器的统一管理。通过将虚拟机作为 Kubernetes 中的原生资源(Custom Resources),KubeVirt 使得虚拟机可以像容器一样进行管理,允许用户在同一平台上运行容器化应用和传统虚拟化工作负载。
传统的虚拟化技术(如 KVM)和容器技术(如 Docker)在管理、调度和操作方式上存在很大差异。KubeVirt 通过 Kubernetes 提供的资源调度、自动化扩展、集群管理等能力,解决了这些差异,并提供了跨虚拟机与容器的统一平台。
2.3.2 Kubernetes 与虚拟化的结合
Kubernetes 是一个开源的容器编排平台,主要用于管理容器化应用的部署、扩展、负载均衡等。它通过一组统一的 API 让开发者和运维人员能够以声明式的方式管理应用。
虚拟化技术(如 QEMU/KVM)则提供了独立的操作系统实例,通常用于运行传统的非容器化应用。虚拟化技术与 Kubernetes 结合时,KubeVirt 充当桥梁,实现容器与虚拟机资源的统一调度。
通过在 Kubernetes 中引入虚拟机,用户能够将现有的虚拟机基础设施与新兴的容器化工作负载无缝集成,从而简化集群管理,提高资源利用率
使用 KubeVirt 管理虚拟机与容器,提供对容器化和虚拟化工作负载的统一管理
我们可以动手感受一下,先创建一个虚拟机以及一个容器
[root@k8s-master ~]# cat vm.gl.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: test-vm
namespace: default
spec:
running: false # 保持为 false,允许手动启动
template:
metadata:
labels:
kubevirt.io/vm: test-vm
spec:
domain:
cpu:
cores: 2
memory:
guest: 2Gi # 设置虚拟机的内存为 2Gi
devices:
disks:
- disk:
bus: virtio
name: disk0
volumes:
- name: disk0
containerDisk:
image: quay.io/kubevirt/cirros-registry-disk-demo
[root@k8s-master ~]# kubectl create -f vm.gl.yaml
查看虚拟机的状态(这里我们可以想想为什么可以用kubectl直接来查看虚拟机)
[root@k8s-master ~]# kubectl get virtualmachines -n default
访问虚拟机控制台
[root@k8s-master ~]# virtctl console test-vm
创建容器应用
[root@k8s-master ~]# cat app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
[root@k8s-master ~]# kubectl create -f app-deployment.yaml
查看容器的运行状态
[root@k8s-master ~]# kubectl get pods -n default
通过上面的示例,我们可以发现,通过 KubeVirt,你可以使用 kubectl
来管理虚拟机和容器资源。虽然 Kubernetes 本身并不支持原生的虚拟机管理,但是 KubeVirt 扩展了 Kubernetes,使其能够像管理容器一样管理虚拟机。
那如果我们没有安装KubeVirt,去查看集群内是否有虚拟机会出现什么
[root@k8s-master ~]# kubectl get virtualmachines -A
系统会提示你,Kubernetes API 服务器没有找到 virtualmachines 资源类型,这就要我们安装KubeVirt服务了
2.4 KubeVirt 存储
KubeVirt 是一个在 Kubernetes 上运行虚拟机的插件,可以使我们在 Kubernetes 环境中管理虚拟机(VM)。在运行虚拟机的过程中,存储是一直是至关重要的组件,它确保了虚拟机数据的持久化与高效管理。KubeVirt 使用 Kubernetes 的持久存储卷(Persistent Volume, PV)和持久卷声明(Persistent Volume Claim, PVC)来管理存储资源,允许用户为虚拟机提供持久存储,以便虚拟机重启或迁移时不会丢失数据。
2.4.1 KubeVirt 存储类型
持久卷(Persistent Volume, PV)
持久卷是一种存储资源的抽象,可以在 Kubernetes 集群中定义、提供,并可以被 Pod 或虚拟机使用。KubeVirt 支持各种类型的 PV,比如 NFS、Ceph、iSCSI、AWS EBS、GCE Persistent Disk 等。
持久卷声明(Persistent Volume Claim, PVC)
PVC 是用户对存储资源的请求,用户可以声明需要的存储大小和访问模式。KubeVirt 可以通过 PVC 绑定到相应的 PV 上,确保虚拟机使用的存储符合需求。
DataVolume
KubeVirt 提供了 DataVolume 资源作为 PVC 的一种抽象层,用来帮助用户更容易管理 VM 的存储数据。DataVolume 可以与外部存储(比如 HTTP、S3、Registry)进行数据导入,实现自动创建和管理 PVC
2.4.2 KubeVirt存储访问模式
KubeVirt 支持三种主要的存储访问模式:
ReadWriteOnce (RWO):单个节点可以读取和写入
ReadOnlyMany (ROX):多个节点可以只读访问
ReadWriteMany (RWX):多个节点可以读写访问
示例:创建本地存储
创建一个本地存储目录
[root@k8s-master ~]# sudo mkdir -p /mnt/local-storage
[root@k8s-master ~]# sudo chmod 777 /mnt/local-storage
创建一个 PersistentVolume (PV) 配置文件 local-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/local-storage
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- <NODE_NAME>
应用配置
[root@k8s-master ~]# kubectl apply -f local-pv.yaml
创建一个 StorageClass 配置文件 local-storage-class.yaml
[root@k8s-master ~]# vi local-storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
应用配置
[root@k8s-master ~]# kubectl apply -f local-storage-class.yaml
创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-storage
resources:
requests:
storage: 5Gi
创建文件后,应用配置
[root@k8s-master ~]# kubectl apply -f pvc.yaml
查看PV和PVC是否绑定成功
如果绑定成功,STATUS
应该显示为 Bound
[root@k8s-master ~]# kubectl get pv my-pv
[root@k8s-master ~]# kubectl get pvc my-vm-pvc
创建虚拟机并绑定PVC
创建vmq.yaml文件定义一个 KubeVirt 虚拟机,并将刚创建的 PVC 挂载为虚拟机的磁盘
[root@k8s-master ~]# vi vmq-yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
running: false
template:
spec:
domain:
resources:
requests:
memory: 1024M
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: datavolumedisk1
disk:
bus: virtio
volumes:
- name: containerdisk
containerDisk:
image: kubevirt/cirros-container-disk-demo:latest
- name: datavolumedisk1
persistentVolumeClaim:
claimName: test-pvc
应用yaml文件并启动虚拟机,验证虚拟机的状态
[root@k8s-master ~]# kubect apply -f vmq-yaml
[root@k8s-master ~]# virtctl start testvmq
进入虚拟机控制台,查看磁盘情况
[root@k8s-master ~]# virtctl console testvm
2.5 KubeVirt 网络
2.5.1 KubeVirt 网络架构
KubeVirt 的网络架构利用 Kubernetes 原生网络模型,并使用虚拟机接口 (VMI) 配置 VM 的网络。KubeVirt 通过 CNI(容器网络接口)插件来实现网络连接,并支持多种网络模式(例如 Pod 网络和多网络)来满足不同需求。
类型 | 描述 |
Pod | 默认 Kubernetes 网络 |
multus | 使用 Multus 提供的辅助网络或当 Multus 定义为默认网络时提供主网络 |
2.5.2 KubeVirt网络模式
KubeVirt 主要支持以下几种网络模式:
Pod 网络(默认模式)
使用 Kubernetes 集群默认的 Pod 网络。
在这种模式下,每个虚拟机(VM)作为一个 Pod 运行,并与 Kubernetes Pod 网络共享 IP 地址。
默认使用 bridge 插入方式,将 VM 接口桥接到 Pod 的虚拟以太网接口上,使其具备 Pod 网络的 IP,且能够与其他 Pod 通信。
多网络模式(Multus CNI 插件)
使用 Multus CNI 插件,可以为每个 VM 配置多个网络接口。
允许 VM 连接到多个网络,实现隔离或独立的网络拓扑。
常用于复杂的网络拓扑设计,比如电信级应用或 NFV(网络功能虚拟化)场景。
SR-IOV 网络
使用 SR-IOV(单根 I/O 虚拟化)直接将物理网卡的虚拟功能分配给 VM,从而实现高性能网络。
适用于对网络性能要求高的场景,如高性能计算、数据密集型应用等。
SR-IOV 需要集群节点和网卡支持 SR-IOV 功能,并使用 SR-IOV CNI 插件。
MACVLAN 网络
MACVLAN 允许多个接口共享一个物理网络接口,但每个接口拥有独立的 MAC 地址和 IP 地址。
在使用 Multus CNI 时,MACVLAN 可以用于将虚拟机直接连接到物理网络。
2.5.3 KubeVirt插入方式
KubeVirt 支持不同的网络接口插入方式,用于将 VM 的网络接口与 Pod 网络接口连接。主要的插入方式包括:
Bridge(桥接)
将 VM 的网络接口桥接到 Pod 的 veth(虚拟以太网)接口上。
适用于默认的 Pod 网络模式,VM 获得 Pod 的 IP 地址,并通过该 IP 与其他资源通信。
Masquerade(伪装)
使用网络地址转换(NAT)将 VM 的私有 IP 地址隐藏在 Pod 的 IP 地址后。
适合需要隔离 VM 网络的场景,通常用于虚拟机作为客户端访问外部服务,而不需要直接被访问的场景。
SR-IOV
直接将 SR-IOV 网卡功能分配给 VM,提供接近物理网络的性能。
2.5.4 KubeVirt卷的类型
cloudInitConfigDrive:在通过给VM挂载一个文件系统,给cloud-init提供meta-data和user-data
cloudInitNoCloud:在通过给VM挂载一个文件系统,给cloud-init提供meta-data和user-data,生成的文件格式与ConfigDrive不同
containerDisk:指定一个包含qcow2或raw格式的Docker镜像,重启VM数据会丢失
dataVolume:动态创建一个PVC,并用指定的磁盘映像填充该PVC,重启vm数据不会丢失。
emptyDisk:从宿主机上分配固定容量的空间,映射到VM中的一块磁盘,与emptyDir一样,emptyDisk的生命周期与VM等同,重启VM数据会丢失。
ephemeral:在VM启动时创建一个临时卷,VM关闭后自动销毁,临时卷在不需要磁盘持久性的任何情况下都很有用。
hostDisk:在宿主机上创建一个img镜像文件给VM使用。重启VM数据不会丢失。
persistentVolumeClaim:指定一个PVC创建一个块设备。重启VM数据不会丢失。
secret:使用Kubernetes的secret来存储和管理一些敏感数据,比如密码,token,密钥等敏感信息,并把这些信息注入给VM,可以动态更新到Pod,但是不能修改Pod中生成的iso文件,更不能更新到VM。要想更新到VM,需重启VM。
configMap:功能类似于secret,把configMap里的信息写入到iso磁盘中,挂给VM。
serviceAccount:功能类似为secret,把serviceAccount里的信息写入到iso磁盘中,挂给VM。
sysprep:以secret或configMap的形式,往VM写入sysprep
示例:创建虚拟机并配置网络
创建一个虚拟机配置文件 vmi.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: test-vm
spec:
running: false
template:
spec:
domain:
resources:
requests:
memory: 1024M
devices:
disks:
- name: containerdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: kubevirt/cirros-container-disk-demo:latest
创建虚拟机
[root@k8s-master ~]# kubectl apply -f vmi-yaml
启动虚拟机
[root@k8s-master ~]# virtctl start testvm
[root@k8s-master ~]# kubectl get vmi test-vm
验证网络配置
[root@k8s-master~]# kubectl
get vmi test-vm -o jsonpath='{.status.interfaces[0].ipAddress}'
进入虚拟机控制台,验证网络连接
[root@k8s-master ~]# virtctl console test-vm
$ ping -c 3 8.8.8.8
配置多网络接口
安装Multus CNI
[root@k8s-master~]#kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
[root@k8s-master~]# kubectl get pods -n kube-system | grep multus
创建一个额外的网络配置文件
[root@k8s-master ~]# cat additional-network.yaml
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: additional-network
spec:
config: '{
"cniVersion": "0.3.1",
"type": "bridge",
"bridge": "br0",
"ipam": {
"type": "host-local",
"subnet": "10.10.0.0/16",
"rangeStart": "10.10.1.2",
"rangeEnd": "10.10.3.5",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"gateway": "10.10.1.1"
}
}'
应用配置
[root@k8s-master ~]# kubectl apply -f additional-network.yaml
配置虚拟机使用额外网络
修改虚拟机配置文件 vm.yaml
,添加额外网络接口:
[root@k8s-master ~]# cat vmi.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
running: false
template:
spec:
domain:
resources:
requests:
memory: 1024M
devices:
disks:
- name: containerdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
- name: additional
bridge: {}
networks:
- name: default
pod: {}
- name: additional
multus:
networkName: additional-network
volumes:
- name: containerdisk
containerDisk:
image: kubevirt/cirros-container-disk-demo:latest
重新创建虚拟机
[root@k8s-master ~]# kubectl delete -f vm.yaml
[root@k8s-master ~]# kubectl apply -f vm.yaml
[root@k8s-master ~]# virtctl start testvm
查看虚拟机的运行状态
[root@k8s-master ~]# kubectl get vmi test-vm
验证额外的网络接口
[root@k8s-master~]#kubectl
get vmi testvm -o jsonpath='{.status.interfaces}'
验证虚拟机网络连接
[root@k8s-master ~]# virtctl console test-vm
$ ip addr show
$ ping -c 3 8.8.8.8