kubevirt - 心识

一、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