KubeVirt 安装和使用

简介: kubevirt

KubeVirt 安装和使用

一、KubeVirt 概述

KubeVirt 是 Kubernetes 的一个扩展,允许在 Kubernetes 集群中管理虚拟机(VM)。它将虚拟机工作负载与容器工作负载统一在同一个平台上,为传统应用提供云原生的管理能力。

核心特性

  • 在 Kubernetes 中运行和管理虚拟机
  • 支持热迁移(Live Migration)
  • 支持 SR-IOV、MAC 地址池等高级网络功能
  • 与容器网络(CNI)和容器存储(CSI)集成
  • 提供 virtctl 命令行工具管理虚拟机

二、环境准备

2.1 前置条件

组件 最低版本 说明
Kubernetes v1.22+ 需要启用 Webhook 和 CRD
kubectl v1.22+ 与集群版本匹配
Containerd/Docker 最新稳定版 容器运行时
CPU 2核+ 需要支持硬件虚拟化
内存 4GB+ 建议 8GB 以上

2.2 检查硬件虚拟化支持

# Linux 系统检查
grep -E '(vmx|svm)' /proc/cpuinfo

# 如果输出包含 vmx (Intel) 或 svm (AMD),则支持硬件虚拟化

2.3 加载 KVM 内核模块

# 加载 kvm 模块
modprobe kvm

# 加载 kvm_intel 或 kvm_amd
modprobe kvm_intel   # Intel CPU
modprobe kvm_amd     # AMD CPU

# 验证
lsmod | grep kvm

kubevirt 组件

1. virt-api(入口与网关)

virt-api 是 KubeVirt 的统一入口点,作为 Kubernetes API Server 的扩展运行。

  • 准入控制(Webhook): 充当 MutatingValidating 进站拦截器。在 VM/VMI 资源写入 etcd 之前,负责对其进行字段校验、默认值注入和合规性审查。
  • API 聚合(Aggregator): 通过 Kubernetes 聚合 API,对外暴露虚拟机专属的非声明式操作接口。例如:虚拟机的启动(start)、停止(stop)、重启(restart)、热迁移(migrate)、冷/热冻结(freeze/unfreeze)和软重启(softReboot)等。
  • 控制流路由: 接收到用户的操作指令后,将其转发给对应的 virt-handler 或通过修改 CRD 状态触发控制循环。

2. virt-controller(大脑与协同器)

virt-controller 是 KubeVirt 的核心控制器,以 Deployment 形式运行(通常为多副本主备高可用)。

  • 生命周期协同(VM ➔ Pod): 采用基于 Informer 的 List-Watch 机制,时刻监听 VM、VMI 等自定义资源的变化。
  • 声明式状态转换: 当用户创建一个 VMI(Virtual Machine Instance)时,virt-controller 会在集群中创建并调度一个对应的底层容器 Pod(通常被称为 Helper Pod ),将虚拟机的配置转换为 Pod 的规格(Spec),从而利用 Kubernetes 原生的调度器(Scheduler)来决定虚拟机在哪个节点上运行。
  • 集群级监控: 监控集群中所有 VM/VMI 的期望状态与实际状态,确保两者最终一致。

3. virt-handler(节点代理与守护进程)

virt-handler 是运行在每个物理节点上的 DaemonSet 代理。它以高权限(hostNetwork + hostPID)运行,负责处理该节点上所有虚拟机的具体落地工作。

  • 下发底层操作(通过 Unix Socket): 监听本节点上的 VMI 资源变化。当发现有 VMI 被调度到本节点时,它不直接操作底层 Libvirtd,而是通过域套接字(Domain Socket)与该 VMI 对应的 virt-launcher 容器进行通信,命令其启动或停止底层的 Libvirt 虚拟机。
  • 直接控制接口(Console / VNC): 响应来自 virt-api 的直接控制请求,提供控制台接入(Console)、图形界面接入(VNC)、暂停/恢复(pause/unpause)等本节点 VM 级别的底层对接。
  • 状态收集与上报: 收集本节点上虚拟机的实际运行状态(心跳、网络、磁盘等指标),并更新回 VMI 的 Status 字段。

4. virt-launcher(沙箱与生命周期终点)

每个 VMI 对应的 Pod 内部都运行着一个 virt-launcher 进程。一个虚拟机实例对应一个单独的 Pod 容器。

  • 虚拟机沙箱隔离: virt-launcher 运行在 Pod 的网络和 PID 命名空间中,为 QEMU/KVM 进程提供外部容器隔离。
  • Libvirtd 承载者: 在 Pod 内部拉起一个本地的 libvirtd 守护进程,并由 virt-launcher 进程负责管理这个 libvirtd 的生命周期。
  • QEMU/KVM 进程生命周期管理: 接收来自同一节点上 virt-handler 的指令,通过本地的 libvirtd 去真正创建、销毁和维护底层的 qemu-kvm 虚拟机进程。
  • 异常处理: 如果底层的 QEMU 进程异常退出,virt-launcher 会捕获该信号并负责终止当前 Pod,以便触发 Kubernetes 的重建/自愈机制。

💡 核心组件协同工作流示例(以启动一个 VM 为例)

  1. 用户 提交创建 VM 的请求 ➔ virt-api(校验并通过 webhook 注入默认值,写入 etcd)。
  2. virt-controller 监听到新 VM ➔ 创建对应的 VMI 和底层的 Helper Pod
  3. Kubernetes 调度器将该 Pod 调度到 Node-A
  4. Node-A 上的 virt-handler 检测到本节点有新的 VMI 分配,开始与该 Pod 内的 virt-launcher 通信。
  5. virt-launcher 在 Pod 内部启动本地 libvirtd,并最终拉起 qemu-kvm(虚拟机正式运行)。

三、安装 KubeVirt

3.1 使用 kubectl 安装(推荐)

# 设置 KubeVirt 版本号
export KUBEVIRT_VERSION="v1.8.4"

# 创建 namespace
kubectl create namespace kubevirt

# 部署 KubeVirt Operator
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml

# 创建 KubeVirt CR(Custom Resource)
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml

3.2 验证安装

# 查看 KubeVirt 相关 Pod

[root@master1 ~ ]# kubectl get pods -n kubevirt
NAME                               READY   STATUS    RESTARTS      AGE
virt-api-85bb9b4ffb-67556          1/1     Running   2 (24h ago)   4d
virt-api-85bb9b4ffb-8749q          1/1     Running   3 (24h ago)   4d1h
virt-controller-7cf5b94d5f-59kvl   1/1     Running   5 (24h ago)   4d1h
virt-controller-7cf5b94d5f-cb8lk   1/1     Running   3 (24h ago)   4d1h
virt-handler-2m2nl                 1/1     Running   0             69m
virt-handler-79rcl                 1/1     Running   3 (24h ago)   4d1h
virt-handler-8k829                 1/1     Running   3 (24h ago)   4d1h
virt-handler-kjslj                 1/1     Running   2 (24h ago)   4d1h
virt-handler-mv8z8                 1/1     Running   1 (24h ago)   4d1h
virt-operator-576b8d796c-47m2s     1/1     Running   8 (24h ago)   4d2h
virt-operator-576b8d796c-gr9dl     1/1     Running   6 (24h ago)   4d2h

# 查看 KubeVirt CR 状态
 [root@master1 ~ ]# kubectl get kubevirt.kubevirt.io -n kubevirt
NAME       AGE    PHASE
kubevirt   4d2h   Deployed

# 等待所有组件就绪
kubectl wait --for=condition=Available --timeout=300s \
  kubevirt/kubevirt -n kubevirt

预期输出:

NAME       AGE    PHASE
kubevirt   5m     Deployed

四、安装 virtctl 客户端工具

4.1 下载 virtctl

# 设置版本
export KUBEVIRT_VERSION="v1.8.4"

# Linux 系统下载
wget https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/virtctl-${KUBEVIRT_VERSION}-linux-amd64

4.2 安装 virtctl

# Linux/macOS
[root@master1 ~ ]# chmod +x virtctl-v1.8.4-linux-amd64
[root@master1 ~ ]# mv virtctl-v1.8.4-linux-amd64 /usr/local/bin/virtctl

4.3 验证安装

 [root@master1 ~ ]# virtctl version --client
Client Version: version.Info{
   GitVersion:"v1.8.4", GitCommit:"dfaa398f086692d19e01be21d83a01036e07815f", GitTreeState:"clean", BuildDate:"2026-06-16T13:26:36Z", GoVersion:"go1.24.9 X:nocoverageredesign", Compiler:"gc", Platform:"linux/amd64"}

五、基本使用

VirtualMachine

vm,是在vmi基础之上 更完善的逻辑控制,可以认为是控制器;vmi(VirtualMachiineInstance),是虚拟机实例。vm与vmi之间的关系类似于deployment与pod之间的关系。

5.1 创建虚拟机

 [root@master1 ~/kubevirt/test ]# cat test.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: vm-cirrors
  namespace: default
spec:
  runStrategy: Halted
  template:
    metadata:
      labels:
        kubevirt.io/vm: vm-cirros
    spec:
      domain:
        devices:
          disks:
            - name: containerdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
        machine:
          type: ""
        resources:
          requests:
            memory: 64M
      terminationGracePeriodSeconds: 0
      volumes:
        - name: containerdisk
          containerDisk:
            image: quay.io/kubevirt/cirros-container-disk-demo:latest
        - name: cloudinitdisk
          cloudInitNoCloud:
            userDataBase64: I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogZ2xvbzEyMwpjaHBhc3N3ZDogeyBleHBpcmU6IEZhbHNlIH0KcnVuY21kOgogIC0gZWNobyAiSGVsbG8gS3ViZVZpcnQhIiA+IC9yb290L3Rlc3QudHh0Cg==
 [root@master1 ~/kubevirt/test ]# kubectl get vm
NAME         AGE   STATUS    READY
vm-cirrors   74s   Stopped   False

当前位置: ~/kubevirt/test
 [root@master1 ~/kubevirt/test ]# virtctl start vm-cirrors
VM vm-cirrors was scheduled to start


 [root@master1 ~/kubevirt/test ]# kubectl get vm
NAME         AGE   STATUS     READY
vm-cirrors   94s   Starting   False


 [root@master1 ~/kubevirt/test ]# kubectl get vmi
NAME         AGE   PHASE     IP               NODENAME   READY
vm-cirrors   31s   Running   172.20.166.137   node1      True
                  False

# 一个vmi对象对应一台虚拟机,实际上这台虚拟机是在一个特殊的kubernetes pod中,该pod里有virt-launcher、liibvirtd和qemu进程,因此也就是可以看作kubevirt把虚拟机运行在pod中了。
 [root@master1 ~/kubevirt/test ]# kubectl get pods -A --field-selector spec.nodeName=node1 -owide
NAMESPACE        NAME                             READY   STATUS    RESTARTS       AGE     IP               NODE    NOMINATED NODE   READINESS GATES
default          virt-launcher-vm-cirrors-cl5zq   3/3     Running   0              6m26s   172.20.166.137   node1   <none>           1/1
kube-system      calico-node-dvmbz                1/1     Running   31 (27h ago)   159d    192.168.11.7     node1   <none>           <none>
kube-system      node-local-dns-nldq9             1/1     Running   31 (27h ago)   159d    192.168.11.7     node1   <none>           <none>
kubevirt         virt-handler-2m2nl               1/1     Running   0              4h8m    172.20.166.143   node1   <none>           <none>
metallb-system   speaker-292j5                    1/1     Running   0              4h8m    192.168.11.7     node1   <none>           <none>
traefik          traefik-5mwff                    1/1     Running   15 (27h ago)   89d     172.20.166.141   node1   <none>           <none>

[root@master1 ~/kubevirt/test ]# virtctl console vm-cirrors
Successfully connected to vm-cirrors console. Press Ctrl+] or Ctrl+5 to exit console.

#

为虚拟机创建service 并访问

 [root@master1 ~ ]# virtctl expose vm vm-cirrors --name vmiservice-node --target-port 22 --port 24 --type NodePort
Service vmiservice-node successfully created for vm vm-cirrors

[root@master1 ~ ]# ssh cirros@10.68.86.25 -p 24
cirros@10.68.86.25's password:
$

当前位置: ~
 [root@master1 ~ ]# kubectl get svc
NAME              TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.68.0.1     <none>        443/TCP        159d
vmiservice-node   NodePort    10.68.86.25   <none>        24:32482/TCP   6s
# vm-ubuntu.yaml
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu-vm
  namespace: default
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: ubuntu-vm
    spec:
      domain:
        cpu:
          cores: 2
        memory:
          guest: 2Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
      volumes:
        - name: rootdisk
          containerDisk:
            image: kubevirt/ubuntu-container-disk:latest
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |-
              #cloud-config
              password: ubuntu
              chpasswd: {
    expire: False }
              ssh_authorized_keys:
                - ssh-rsa AAAA...your-key
kubectl apply -f vm-ubuntu.yaml

在 KubeVirt 中,虚拟机(VirtualMachine/VMI)对存储卷的使用分为两个层次:Kubernetes 集群侧的存储提供(Volume) 以及 虚拟机内部感知的磁盘形态(Disk)

以下是 KubeVirt 中最常用的存储卷类型(Volume Types)及其典型应用场景:

  1. persistentVolumeClaim (PVC)

这是生产环境中最核心、最常用的存储类型。它直接对接 Kubernetes 的存储生态(CSI 驱动),支持从本地磁盘、网络文件系统(NFS)、到分布式存储(如 Ceph、OpenEBS 等)。

  • 使用方式: 可以挂载为文件系统模式(Filesystem)(在 PVC 上创建一个磁盘镜像文件,如 disk.img)或原始块设备模式(Block)(直接将块设备映射给虚拟机,性能最佳)。
  • 应用场景: 虚拟机的系统盘、高性能数据盘、需要支持持久化和跨节点热迁移(通常需要 ReadWriteMany / RWX 属性)的场景。
  1. containerDisk

KubeVirt 独创的一种极其便利的存储类型。它允许将虚拟机的操作系统镜像(如 qcow2/raw 格式)直接打包到 Docker 镜像中,并托管在标准的 Container Registry(如 Harbor、Docker Hub)里。

  • 使用方式: 虚拟机启动时,会像拉取容器镜像一样拉取这个 containerDisk 镜像,并从中读取操作系统。
  • 应用场景: 只读系统盘、快速水平扩展的无状态虚拟机(如基础 CI/CD 节点)、共享的黄金镜像(Golden Image)。由于其默认只读或采用临时写时复制(Ephemeral),它非常适合用作虚拟机的启动模板。
  1. dataVolume (DV)

dataVolume 是由 KubeVirt 的子项目 CDI (Containerized Data Importer) 提供的增强型存储管理方式。它在内部本质上还是通过自动创建 PVC 来承载数据,但极大简化了镜像的导入过程。

  • 使用方式: 你可以直接在 dataVolume 中定义数据源(Source),CDI 会自动拉起一个 importer Pod,帮你把数据转换并写入 PVC。
  • 支持的内置数据源:
    • http/s3:直接从外网或对象存储下载 qcow2/raw 镜像。
    • registry:从 Container Registry 导入 containerDisk 的内容。
    • pvc:克隆现有的另一个 PVC(快照克隆)。
    • blank:创建一个指定大小的空白物理磁盘。
  • 应用场景: 从零初始化虚拟机、批量通过基础镜像克隆并部署新 VM。
  1. cloudInitNoCloud

这是一个特殊的配置卷,专门用来向虚拟机注入初始化配置(网络、主机名、用户密码、SSH 密钥、初始脚本等)。

  • 使用方式: KubeVirt 会自动将用户定义的 userDatanetworkData 转换为标准的 cloud-init ISO 镜像,并挂载为虚拟机的只读光驱。
  • 应用场景: Linux 虚拟机的自动化首次开机配置、网络动态分配、公钥注入。
  1. emptyDir

与 Kubernetes 原生的 emptyDir 完全一致,是一个生命周期与当前 Pod(虚拟机实例)绑定的临时空目录。

  • 使用方式: 虚拟机内部会看到一个空白的、未格式化的物理磁盘。当虚拟机 Pod 被重建、漂移或删除时,其中的数据会彻底丢失
  • 应用场景: 虚拟机的临时缓存盘、Swap 交换分区空间、无状态的 scratch 空间。
  1. hostDisk

直接映射宿主机(Node)本地的文件路径到虚拟机中(类似于 Kubernetes 的 hostPath)。

  • 使用方式: 在宿主机的指定路径下创建或使用一个独立的虚拟磁盘文件。

  • 应用场景: 单节点测试环境、边缘计算节点(节点数量少、不需要热迁移、追求极简的本地存储性能)。

  • ⚠️ 注意: 使用 hostDisk 会限制虚拟机的调度灵活性,导致虚拟机无法在集群内热迁移。

📝 典型配置结构示例 (YAML 视角)

在定义 VM CRD 时,这些存储卷在 spec.template.spec 里的基本映射逻辑如下:

YAML

spec:
  domain:
    devices:
      disks:
      - name: boot-disk
        disk: {} # 虚拟机内看作标准磁盘
      - name: init-data
        cdrom: {} # 虚拟机内看作光驱
  volumes:
  - name: boot-disk
    persistentVolumeClaim: # 对应 K8s 集群侧的存储卷类型
      claimName: my-ubuntu-pvc
  - name: init-data
    cloudInitNoCloud:
      userData: |
        #cloud-config
        password: my-secure-password
        chpasswd: { expire: False }

5.2 查看虚拟机

# 查看虚拟机状态
kubectl get vmi

# 查看虚拟机详情
kubectl describe vmi ubuntu-vm

# 使用 virtctl 查看
virtctl get vmi

5.3 使用 virtctl 暴露服务

# 暴露 SSH 服务(NodePort)
virtctl expose virtualmachineinstance ubuntu-vm \
  --name=ubuntu-vm-ssh \
  --port=22 \
  --target-port=22 \
  --type=NodePort

# 暴露 HTTP 服务(ClusterIP)
virtctl expose virtualmachineinstance ubuntu-vm \
  --name=ubuntu-vm-http \
  --port=80 \
  --target-port=80 \
  --type=ClusterIP

# 查看暴露的服务
kubectl get svc

5.4 使用 virtctl 管理虚拟机

# 启动虚拟机
virtctl start ubuntu-vm

# 停止虚拟机
virtctl stop ubuntu-vm

# 重启虚拟机
virtctl restart ubuntu-vm

# 暂停虚拟机
virtctl pause vmi ubuntu-vm

# 恢复虚拟机
virtctl unpause vmi ubuntu-vm

# 查看虚拟机控制台(VNC)
virtctl vnc ubuntu-vm

# 查看虚拟机串口控制台
virtctl console ubuntu-vm

# SSH 连接虚拟机
virtctl ssh ubuntu-vm --username ubuntu

# 热迁移虚拟机
virtctl migrate ubuntu-vm

六、卸载 KubeVirt

# 删除 KubeVirt CR
kubectl delete -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-cr.yaml

# 删除 KubeVirt Operator
kubectl delete -f https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}/kubevirt-operator.yaml

# 删除 namespace
kubectl delete namespace kubevirt
相关文章
|
2月前
|
人工智能 缓存 监控
阿里云 AI 网关 FinOps 能力正式上线丨让每一个 Token 的消耗都“看得见、管得住”
阿里云 AI 网关 FinOps 能力,从“消费者配额”切入,让企业在大模型调用的每一个环节都做到心中有数。
471 21
|
17天前
|
存储 前端开发 Java
AgentScope 2.0 生产可用,企业级 Harness 底座全解析!
AgentScope 2.0 GA 发布,打造企业级分布式智能体Harness底座。
|
23天前
|
人工智能 运维 监控
|
23天前
|
存储 人工智能 运维
一份可信来源,终结 Skill 管理混乱:Skill 治理最佳实践
从本机同步到统一治理可信 Skill 管理实践指南。
|
1月前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 API 网关 2026 年 6 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
|
2月前
|
人工智能 缓存 自然语言处理
【AI 尝鲜实验室】上新 | Qoder x DevBox:让 AI 在云端放开手脚写代码
Qoder × 阿里云DevBox融合AI编程与云端开发:用自然语言描述需求,AI自动生成、调试并运行代码;所有依赖、构建、验证均在云端完成,本地零环境负担。2C2G轻量开发机低至0.1元/小时,适合快速验证、轻薄本开发及避免本地污染。
|
7月前
|
Kubernetes 应用服务中间件 API
应对 Nginx Ingress 退役,是时候理清这些易混淆的概念了
本文希望提供一种更简单的方式,来理解这些容易混淆的技术概念:Nginx、Ingress、Ingress Controller、Ingress API、Nginx Ingress、Higress、Gateway API。
3458 173
|
2月前
|
Kubernetes Ubuntu 网络协议
|
2月前
|
消息中间件 人工智能 Kafka
AI 时代,实时入湖正在告别 ETL:从 Kafka 到 Iceberg 的架构减法
本文围绕“零 ETL”这一趋势,讨论流数据入湖为什么需要做架构减法,并结合 Kafka × Table Bucket 的实践,分析一种将通用入湖能力前移到消息与表存储链路中的方案,如何在降低复杂度的同时,兼顾实时性、一致性、Schema 演进、CDC 语义与开放生态兼容。
392 131
|
13天前
|
人工智能 运维 安全