一、kubevirt 是什么?
kubevirt 像管理 pod 一样管理虚拟机
问题1: kubevirt 既然是像管理pod一样管理虚拟机,那和管理容器的区别是什么呢?
容器:
- 进程的隔离,使用还是本机的内核
- 启动快,是毫秒级
kubevirt:
- 完整的隔离,是独立的内核
- 启动慢,以秒计算
容器更像电视机,每个都可以看电视,但是记录都会留下来
kubevirt 更像手机,每个人都是独立的
问题2:为什么要在kubernetes安装kubevirt
核心的目的是:可以在 kubernetes 统一管理虚拟机

二、安装篇
2.1 安装 kubevirt
# 拉取kubevirt-operator.yaml
wget https://github.com/kubevirt/kubevirt/releases/download/v1.5.0/kubevirt-operator.yaml
kubectl apply -f kubevirt-operator.yaml# 检测
[root@master kubevirt]# kubectl get pod -n kubevirt
NAME READY STATUS RESTARTS AGE
virt-operator-59bcb55d85-9k57j 1/1 Running 0 2m10s
virt-operator-59bcb55d85-bt294 1/1 Running 0 2m10s# 拉取kubevirt-cr.yaml
wget https://github.com/kubevirt/kubevirt/releases/download/v1.5.0/kubevirt-cr.yaml
kubectl apply -f kubevirt-cr.yaml# 检测
[root@master kubevirt]# kubectl get pod -n kubevirt
NAME READY STATUS RESTARTS AGE
virt-api-6b476fff5-gnb8f 1/1 Running 0 3m13s
virt-api-6b476fff5-k78q6 1/1 Running 0 3m13s
virt-controller-5886db5b4d-pvfsm 1/1 Running 0 2m37s
virt-controller-5886db5b4d-rl2nt 1/1 Running 0 2m37s
virt-handler-99f9t 1/1 Running 0 2m36s
virt-operator-59bcb55d85-9k57j 1/1 Running 0 9m15s
virt-operator-59bcb55d85-bt294 1/1 Running 0 9m15s# 查看kubevirt是否满足VM运行条件
[root@master kubevirt]# kubectl wait kubevirt kubevirt --for condition=Available -n kubevirt
kubevirt.kubevirt.io/kubevirt condition met
2.1 安装虚拟机的管理工具
wget https://github.com/kubevirt/kubevirt/releases/download/v1.5.0/virtctl-v1.5.0-linux-amd64
chmod +x virtctl-v1.5.0-linux-amd64mv virtctl-v1.5.0-linux-amd64 /usr/local/bin/virtctl
[root@master kubevirt]# virtctl version
Client Version: version.Info{GitVersion:"v1.5.0", GitCommit:"522b44c0ce8d1909618324cb083d69e5c7a0a234", GitTreeState:"clean", BuildDate:"2025-03-13T18:12:11Z", GoVersion:"go1.23.4 X:nocoverageredesign", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{GitVersion:"v1.5.0", GitCommit:"522b44c0ce8d1909618324cb083d69e5c7a0a234", GitTreeState:"clean", BuildDate:"2025-03-13T19:53:21Z", GoVersion:"go1.23.4 X:nocoverageredesign", Compiler:"gc", Platform:"linux/amd64"}
三、使用篇
如果是 openstack,openstack 的虚拟机是没有虚拟机化的,cpu 虚拟化、memory 虚拟化
[root@k8s-master01 ~]# kubectl edit kubevirts.kubevirt.io -n kubevirt
developerConfiguration:
下面添加
useEmulation: true
这个参数的意思是:纯软件仿真,绕过 cpu 的虚拟化
3.1 创建VirtualMachine(简称 vm)
VM和VMI的关系,VMI可以理解为控制器,VM理解为pod,VMI和VM的关系就是deployment和pod之间的关系
3.2 准备 VM 的配置文件
wget https://kubevirt.io/labs/manifests/vm.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:name: testvm
spec:runStrategy: Halted # 这个表示不启动vmtemplate:metadata:labels:kubevirt.io/size: smallkubevirt.io/domain: testvmspec:domain:devices:disks:- name: containerdiskdisk:bus: virtio- name: cloudinitdiskdisk:bus: virtiointerfaces:- name: defaultmasquerade: {} # 使用NAT的网络格式resources:requests:memory: 64Mnetworks:- name: default pod: {} # IP 由集群 CNI(如 Calico)分配。volumes:- name: containerdiskcontainerDisk:image: quay.io/kubevirt/cirros-container-disk-demoimagePullPolicy: IfNotPresent- name: cloudinitdiskcloudInitNoCloud:userDataBase64: SGkuXG4=kubectl apply -f vm.yaml[root@master yaml]# kubectl get vm
NAME AGE STATUS READY
testvm 5s Stopped False
3.3 进入虚拟机
[root@master yaml]# 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
$ # 退出控制器使用
ctrl + ]
3.4 暴露端口
把虚拟机暴露出去,通过SVC的端口的咉射
virtctl expose vmi testvm --port=22 --name=myvm-ssh --type=NodePort[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d14h
myvm-ssh NodePort 10.98.54.150 <none> 22:31452/TCP 70m通过ssh进行连接
# 外部连接
ssh cirros@192.168.100.110 -p 31452# 内部连接
ssh cirros@10.98.54.150 -p 22
3.5 挂载PVC到VM虚拟机
提供磁盘的空间到VM
# 修改vm的文件
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:name: testvm
spec:runStrategy: Haltedtemplate:spec:domain:devices:disks:- name: containerdisk # 系统盘disk:bus: virtio- name: cloudinitdisk # 云初始化盘disk:bus: virtio- name: pvc # 新增:挂载 PVCdisk:bus: virtio # 推荐使用 virtio 总线interfaces:- name: defaultmasquerade: {}resources:requests:memory: 64Mvolumes:- name: containerdiskcontainerDisk:image: quay.io/kubevirt/cirros-container-disk-demo- name: cloudinitdiskcloudInitNoCloud:userDataBase64: SGkuXG4=- name: pvc # 必须与 disks.name 一致persistentVolumeClaim:claimName: test-pvc # 确保 PVC 名称正确networks:- name: defaultpod: {}# 创建pv
[root@k8s-master01 yaml]# cat pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:name: test-pv
spec:accessModes: ["ReadWriteOnce"]capacity:storage: 100MihostPath:path: /host_data# 创建pvc
[root@k8s-master01 yaml]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: test-pvc
spec:accessModes: ["ReadWriteOnce"]resources:requests:storage: 10Mi# 可以在宿主机中看到会生成一个disk.img的文件
[root@k8s-worker host_data]# ls
disk.img # 在虚拟机中做的操作都在这里# 可以看到虚拟机中vdc
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 44M 0 disk
|-vda1 253:1 0 35M 0 part /
`-vda15 253:15 0 8M 0 part
vdb 253:16 0 1M 0 disk
vdc 253:32 0 100M 0 disk # 格式化
$ sudo mkfs.ext4 /dev/vdc
$ sudo mkdir -p /mnt/pvc
$ sudo mount /dev/vdc /mnt/pvc
$ cd /mnt/pvc/
$ ls
lost+found
$ sudo mkdir eee
$ ls
eee lost+found# 如果想要在宿主机使用这份数据
[root@k8s-worker host_data]# mount /host_data/disk.img /mnt/diskimg/
[root@k8s-worker diskimg]# ls
eee lost+found