kubevirt
-
- [架构:KubeVirt 组件的技术和概念概述](#架构:KubeVirt 组件的技术和概念概述)
- 快速入门
架构:KubeVirt 组件的技术和概念概述
KubeVirt 是一个基于 Kubernetes 的虚拟化平台,它允许在 Kubernetes 集群中运行和管理虚拟机(VM)。KubeVirt 的核心目的是将虚拟化和容器化的管理统一在一个平台上,从而在 Kubernetes 环境中同时管理容器和虚拟机,帮助用户实现混合负载的部署和管理。 通常适用于需要将传统虚拟化技术与容器化技术结合使用的场景,比如大规模混合负载的管理、迁移现有虚拟机工作负载到 Kubernetes 集群等。
KubeVirt总体架构图:
KubeVirt框架主要由以下几个组件构成,它们协调工作来提供虚拟机的生命周期管理、存储、网络和调度等功能:
- KubeVirt Operator
作用:KubeVirt Operator 是 KubeVirt 的核心管理组件,负责 KubeVirt 控制面板和资源的生命周期管理。
功能:- 安装、升级和配置 KubeVirt。
KubeVirt 的组件(如 API Server、Controller)在 Kubernetes 集群中始终确保一个健康状态。
根据 Kubernetes 的自定义资源定义(CRD)管理虚拟机相关资源的创建、更新和删除。
- 安装、升级和配置 KubeVirt。
- 虚拟机控制器(VirtualMachineController)
作用:管理虚拟机的生命周期,执行虚拟机的创建、启动、停止、删除等操作。
功能:- 监视虚拟机资源(VirtualMachineCRD),并根据这些资源的状态执行相应的操作。
负责虚拟机实例的调度和创建虚拟机的容器化实例(VirtualMachineInstance)。
确保虚拟机的状态与期望一致,例如启动虚拟机、停止虚拟机等。
- 监视虚拟机资源(VirtualMachineCRD),并根据这些资源的状态执行相应的操作。
- 虚拟机实例控制器(VirtualMachineInstanceController)
作用:管理虚拟机实例(VMI),保证虚拟机实例的运行状态。
功能:- 负责虚拟机实例的生命周期管理,创建、启动、删除虚拟机实例。
监视虚拟机实例(VirtualMachineInstanceCRD),并在状态发生变化时触发相应的操作。
处理虚拟机的调度,保证虚拟机实例在合适的节点上运行。
- 负责虚拟机实例的生命周期管理,创建、启动、删除虚拟机实例。
- virt-handler
作用:virt-handler是一个运行在 Kubernetes 节点上的组件,它负责与虚拟机实例的操作环境进行交互。
功能: - 管理虚拟机实例的启动、停止、迁移等操作。
通过与虚拟机管理程序(如KVM)交互来启动和控制虚拟机。
监听虚拟机实例的状态,确保虚拟机正确运行,并处理实例的故障
Kubevirt 主要实现了下面几种资源,以实现对虚拟机的管理:
- VirtualMachineInstance(VMI):类似于Kubernetes Pod,是管理虚拟机的最小资源。一个VMI对象即表示一台正在运行的虚拟机实例,包含一个虚拟机所需要的各种配置。
- VirtualMachine(VM):为群集内的VMI提供管理功能,例如开机、关机、重启虚拟机,确保虚拟机实例的启动状态,与虚拟机实例是1:1的关系,类似与spec.replica为1的StatefulSet。可以理解为VM是镜像,VMI则是启动的一个容器
- VirtualMachineInstanceReplicaSet(VMIRS):类似于ReplicaSet,可以启动指定数量的VMI,并且保证指定数量的VMI运行,可以配置HPA。
快速入门
部署 KubeVirt:GitHub官网目前最新版本v1.4.0,对应kubernets1.31版本
bash
export VERSION=$(curl -s https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
echo $VERSION
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml"
kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml"
可界面下载后上传到服务器上执行
检查CPU是否支持虚拟化:
shell
[root@k8s-master-node1 ~]# egrep -c 'vmx|svm' /proc/cpuinfo
4
只要输出结果不为0则表示支持虚拟化。VMX和SVM都是虚拟化技术,Intel平台称为VMX--virtual machine extension;AMD平台称为SVM--Secure Virtual Machine extension。
如果输出为0则需要手动启用 KubeVirt 仿真
bash
kubectl -n kubevirt patch kubevirt kubevirt --type=merge --patch '{"spec":{"configuration":{"developerConfiguration":{"useEmulation":true}}}}'
对应配置文件修改的内容为
bash
kubectl edit -n kubevirt kubevirt kubevirt
bash
spec:
certificateRotateStrategy: {}
configuration:
developerConfiguration: #删除了{}
useEmulation: true #添加此行
customizeComponents: {}
imagePullPolicy: IfNotPresent
workloadUpdateStrategy: {}
安装KubeVirt命令行工具:KubeVirt 提供了一个名为virtctl的附加二进制文件,用于快速访问 VM 的串行和图形端口,并处理启动/停止操作。
shell
VERSION=$(kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.observedKubeVirtVersion}")
ARCH=$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/') || windows-amd64.exe
echo ${ARCH}
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-${ARCH}
chmod +x virtctl
sudo install virtctl /usr/local/bin
可界面下载:对应选择Linux-amd64架构
- 创建虚拟机
下载虚拟机清单并进行探索。请注意,它使用容器磁盘,因此不会保留数据。目前,alpine、cirros 和 fedora 均存在此类容器磁盘。
bash
wget https://kubevirt.io/labs/manifests/vm.yaml
官网资源清单如下
bash
[root@k8s-master-node1 ~]# cat vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
runStrategy: Halted
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
VM资源清单文件模板如下:
shell
apiVersion: kubevirt.io/v1 # 指定 API 版本,KubeVirt 的虚拟机资源使用 kubevirt.io/v1
kind: VirtualMachine # 定义资源类型是 VirtualMachine(虚拟机)
metadata:
name: testvm # 虚拟机的名称
spec:
runStrategy: Halted # 定义虚拟机启动策略为 "Halted"(停止状态)。虚拟机在创建时不会自动启动,而是保持停止状态,直到手动启动
template:
metadata:
labels:
kubevirt.io/size: small # 标签,标识虚拟机的大小,"small"表示较小的资源配置
kubevirt.io/domain: testvm # 标签,用于标识虚拟机所属的域,"testvm"为该虚拟机的域名
spec:
domain:
devices:
disks: # 定义虚拟机的磁盘设备
- name: containerdisk # 磁盘名称
disk:
bus: virtio # 使用 virtio 总线来连接磁盘,提供高效的 I/O 性能
- name: cloudinitdisk # 另一个磁盘,用于 Cloud-init 配置
disk:
bus: virtio # 同样使用 virtio 总线
interfaces: # 定义虚拟机的网络接口
- name: default # 默认网络接口的名称
masquerade: {} # 配置网络地址转换(NAT),使虚拟机能够与外部网络通信
resources:
requests:
memory: 64M # 请求的内存资源为 64MB
networks: # 定义虚拟机的网络配置
- name: default # 网络名称
pod: {} # 使用 Pod 网络模式,虚拟机将与 Pod 网络共享同一个网络
volumes: # 定义虚拟机的存储卷
- name: containerdisk # 卷的名称
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo # 使用的容器磁盘镜像(Cirros 测试镜像)
- name: cloudinitdisk # 另一个卷,用于 Cloud-init 配置
cloudInitNoCloud:
userDataBase64: SGkuXG4= # Cloud-init 用户数据(Base64 编码),在虚拟机启动时初始化虚拟机的用户环境
创建VM:
shell
[root@k8s-master-node1 ~]# kubectl apply -f vm.yaml
virtualmachine.kubevirt.io/testvm created
查看VM:
shell
[root@k8s-master-node1 ~]# kubectl get vm
NAME AGE STATUS READY
testvm 17s Stopped False
VirtualMachine 将确保当 VirtualMachine 处于运行状态时,集群中将存在一个具有相同名称的 VirtualMachineInstance 对象,这通过字段控制spec.runStrategy:因为.runStrategy: Halted字段的值设置的Halted,所有虚拟机的状态是Stopped,由于VM还没启动,所以目前还没有VMI资源,只有VM资源。
启动VM:
shell
[root@k8s-master-node1 ~]# virtctl start testvm
VM testvm was scheduled to start
[root@k8s-master-node1 ~]# kubectl get vms
NAME AGE STATUS READY
testvm 83s Running True
可以看到,VM的状态已经变为Running了。
查看对应的VMI:
shell
[root@k8s-master-node1 ~]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
testvm 54s Running 10.244.0.34 k8s-master-node1 True
虚拟机还可以命令式或声明式的方式打开/关闭。设置spec.runStrategy为Always或Halted,这样每次创建vm后,vmi都会对应自动创建,这样就不用通过修改配置文件
bash
[root@k8s-master-node1 ~]# kubectl apply -f vm.yaml
virtualmachine.kubevirt.io/testvm created
[root@k8s-master-node1 ~]# kubectl get vms
NAME AGE STATUS READY
testvm 4s Stopped False
[root@k8s-master-node1 ~]# kubectl patch virtualmachine testvm --type merge -p '{"spec":{"runStrategy": "Always"}}'
virtualmachine.kubevirt.io/testvm patched
[root@k8s-master-node1 ~]# kubectl get vms
NAME AGE STATUS READY
testvm 32s Running True
[root@k8s-master-node1 ~]# kubectl get vmis
NAME AGE PHASE IP NODENAME READY
testvm 2m3s Running 10.244.0.36 k8s-master-node1 True
[root@k8s-master-node1 ~]# kubectl get vm testvm -o jsonpath={.spec.runStrategy}
Always
注意 VM(虚拟机)资源和 VMI(虚拟机实例)资源之间的区别。启动 VM 之前 VMI 不存在,停止 VM 时 VMI 将被删除。(另请注意,如果想更改某些属性,则需要重新启动 VM。仅修改 VM 是不够的,必须替换 VMI。)
例如我把运行策略修改为always
bash
[root@k8s-master-node1 ~]# cat vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
runStrategy: Always
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
masquerade: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
此时我的配置文件修改了,但原来的vmi还是Halted模式,通过删除 VirtualMachineInstance 来触发 VirtualMachineInstance 重启。这还将让 VirtualMachine 中模板的配置更改:从而达到修改配置文件生效的效果(这里只是说明这种方式,还可以直接删除vm,然后重新起vm.yaml文件)
bash
[root@k8s-master-node1 ~]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
testvm 43s Running 10.244.0.37 k8s-master-node1 True
[root@k8s-master-node1 ~]# kubectl delete vmi testvm
virtualmachineinstance.kubevirt.io "testvm" deleted
[root@k8s-master-node1 ~]# virtctl restart testvm
VM testvm was scheduled to restart
[root@k8s-master-node1 ~]# kubectl get vm testvm -o jsonpath={.spec.runStrategy}
Always[root@k8s-master-node1 ~]# kubectl get vm
NAME AGE STATUS READY
testvm 3m12s Running True
[root@k8s-master-node1 ~]# kubectl get vmi
NAME AGE PHASE IP NODENAME READY
testvm 49s Running 10.244.0.39 k8s-master-node1 True
[root@k8s-master-node1 ~]#
- 访问虚拟机(串行控制台)
连接到 Cirros VM 的串行控制台。按几次回车/输入键,然后使用显示的用户名和密码登录。
bash
[root@k8s-master-node1 ~]# kubectl get vmis
NAME AGE PHASE IP NODENAME READY
testvm 89s Running 10.244.0.39 k8s-master-node1 True
[root@k8s-master-node1 ~]# virtctl console testvm
Successfully connected to testvm console. The escape sequence is ^]
login as 'cirros' user. default password: 'gocubsgo'. use 'sudo' for root.
testvm login: cirros
Password:
$ ls
$ sudo su -
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc pfifo_fast qlen 1000
link/ether 52:54:00:59:eb:c5 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.2/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe59:ebc5/64 scope link
valid_lft forever preferred_lft forever
#
通过键入以下内容断开与虚拟机控制台的连接:ctrl+]
如果想从控制台查看完整的启动顺序日志。需要在启动虚拟机后立即连接到串行控制台
暂停和取消暂停虚拟机
注意:此处的暂停指的是 libvirt 的virDomainSuspend命令:
"进程被冻结,不再访问 CPU 资源和 I/O,但域在虚拟机管理程序级别使用的内存将保持分配状态"
暂停VM(或者VMI)
bash
[root@k8s-master-node1 ~]# kubectl get vm
NAME AGE STATUS READY
testvm 3h16m Running True
[root@k8s-master-node1 ~]# virtctl pause vm testvm
VMI testvm was scheduled to pause
[root@k8s-master-node1 ~]# kubectl get vm
NAME AGE STATUS READY
testvm 3h17m Paused False
[root@k8s-master-node1 ~]#
取消暂停(或者VMI)
bash
[root@k8s-master-node1 ~]# virtctl unpause vm testvm
VMI testvm was scheduled to unpause
[root@k8s-master-node1 ~]# kubectl get vm
NAME AGE STATUS READY
testvm 3h18m Running True
[root@k8s-master-node1 ~]#
停止VM:
shell
[root@k8s-master-node1 ~]# virtctl stop testvm
VM testvm was scheduled to stop
[root@k8s-master-node1 ~]# kubectl get vms
NAME AGE STATUS READY
testvm 6m41s Stopped False
[root@k8s-master-node1 ~]#
删除VM
SHELL
[root@k8s-master-node1 ~]# kubectl delete vm testvm
virtualmachine.kubevirt.io "testvm" deleted
[root@k8s-master-node1 ~]# kubectl get vms
No resources found in default namespace.