版本:v26.06

KubeVirt

特性介绍

KubeVirt是由云原生计算基金会(CNCF)赞助的开源项目,也是红帽OpenShift虚拟化技术的核心底座。它旨在将传统虚拟机(VM)工作负载无缝集成到Kubernetes生态中。 通过KubeVirt,用户可以在同一个Kubernetes集群中同时管理容器化应用和传统虚拟机。虚拟机被封装在容器中运行,既保留了传统虚拟化的兼容性和隔离性,又能享受Kubernetes提供的编排、调度、网络策略及声明式API等云原生能力。这使得企业能够在统一的混合云平台上平滑迁移和运行遗留应用。

应用场景

  • 边缘计算:在边缘计算场景中,往往同时存在新开发的云原生应用和难以容器化的传统服务。KubeVirt允许在边缘Kubernetes集群中统一运行这两类工作负载。 例如:IoT边缘节点可以利用KubeVirt部署基于虚拟机的旧版操作系统服务,同时让该服务与容器化微服务共享底层的网络和存储资源,降低硬件成本并简化管理。
  • 混合云与私有云:KubeVirt使Kubernetes成为统一的混合云控制平面。通过在裸金属服务器上部署集成了KubeVirt的Kubernetes集群,企业可以实现对虚拟机和容器的统一管理、调度和运维,打破虚拟化与容器化之间的孤岛。

能力范围

  • 架构支持:支持通过声明式CRD(Custom Resource Definition)方式创建ARM64架构的虚拟机。
  • 生命周期管理:提供完整的虚拟机基础生命周期管理能力,包括创建、删除、启动、停止及状态同步。
  • 鲲鹏适配:支持在鲲鹏节点环境下运行虚拟化工作负载。

亮点特征

  • ARM64原生支持:在鲲鹏等ARM64服务器上提供稳定的虚拟化基础能力。
  • 统一管控:将VM纳入K8s管理体系,实现“一次部署,全域管理”。
  • 云原生特性继承:虚拟机可复用K8s的网络插件(CNI)、存储插件(CSI)及调度策略。

实现原理

KubeVirt通过扩展Kubernetes API来管理虚拟机,其核心组件部署在kubevirt命名空间中,如图1所示

图1 KubeVirt交互视图

交互视图

核心组件说明

KubeVirt引入了一组新的CRD资源和核心控制器组件:

新增CRD资源

  • VirtualMachine(VM):高阶资源对象,用于定义虚拟机的期望状态(如运行、停止)及配置变更。类似于K8s中的Deployment。
  • VirtualMachineInstance(VMI):代表实际运行的虚拟机实例。类似于K8s中的Pod,是调度和执行的基本单元。
  • VirtualMachineInstanceReplicaSet:类似于Pod的ReplicaSet,用于批量管理和维持同构虚拟机实例的数量。

核心运行组件

  • virt-api:作为Kubernetes API的扩展入口。它注册CRD并通过Aggregator机制对外暴露虚拟机操作接口(如start,stop,migrate,console,vnc等),处理用户的REST请求。
  • virt-controller:集群级控制器。侦听VM和VMI资源的变化,负责协调状态一致性。例如,当用户创建VM时,它会创建对应的VMI和virt-launcher Pod。
  • virt-handler:以DaemonSet形式部署在每个计算节点上。负责节点级别的VMI生命周期操作(如启动、停止、监控),并提供本地REST接口供virt-api调用以执行控制台连接等操作。
  • virt-launcher:运行在每个VMI对应的Pod内部。它是一个轻量级容器,内部包含libvirtd和qemu进程,负责实际启动和管理虚拟机。它还启动一个gRPC服务器,供virt-handler进行通信和控制。
  • libvirtd/qemu:运行在virt-launcher Pod内。libvirt封装了Hypervisor的操作指令,并将其转化为对qemu的请求;qemu则依赖宿主机的KVM模块和硬件虚拟化特性来运行虚拟机。

创建与调度流程

图2 创建与调度流程

创建与调度流程

与相关特性的关系

  • 特权模式要求:Kubernetes API Server必须启用--allow-privileged=true参数,以允许KubeVirt的特权DaemonSet(virt-handler)运行。
  • 硬件要求:节点必须支持硬件虚拟化(Intel VT-x或AMD-V),并在BIOS中开启。对于ARM64架构,需支持相应的虚拟化扩展。

使用KubeVirt

前提条件

  • Kubernetes版本:建议使用openFuyao社区推荐版本v1.34.3或兼容版本。
  • 安装docker用于构建虚拟机镜像。

背景信息

KubeVirt基于Kubernetes原生扩展能力,实现VM与容器统一接入K8s声明式管理API,VM可复用集群编排、调度、网络策略等能力,并支持虚机开关机、热迁移等功能;现需在鲲鹏服务器环境适配落地使用。

使用限制

使用支持虚拟化的硬件。

操作步骤

  1. 基础环境准备。

    1.1 安装依赖软件包。

    执行如下命令,在所有节点上安装KVM(Kernel-based Virtual Machine)相关依赖。

    yum install -y qemu-kvm libvirt virt-install bridge-utils

    1.2 验证虚拟化支持。

    执行如下命令,检查节点是否具备虚拟化条件,确保所有关键项显示PASS:

    virt-host-validate qemu

    预期输出示例:

    QEMU: Checking if device /dev/kvm exists                                   : PASS 
    QEMU: Checking if device /dev/vhost-net exists                             : PASS
    QEMU: Checking if device /dev/net/tun exists                               : PASS
    QEMU: Checking for cgroup 'cpu' controller support                         : PASS
    QEMU: Checking for cgroup 'cpuacct' controller support                     : PASS
    QEMU: Checking for cgroup 'cpuset' controller support                      : PASS
    QEMU: Checking for cgroup 'memory' controller support                      : PASS
    QEMU: Checking for cgroup 'devices' controller support                     : PASS
    QEMU: Checking for cgroup 'blkio' controller support                       : PASS
    ...
  2. KubeVirt部署。

    2.1 安装virt-operator。

    执行如下命令,下载virt-operator配置文件,修改镜像地址为openFuyao镜像源,然后应用配置。

    # 下载KubeVirt 1.7.1版本官方Operator部署文件
    wget https://github.com/kubevirt/kubevirt/releases/download/v1.7.1/kubevirt-operator.yaml
    # 替换镜像仓库地址:将官方镜像仓库替换为openFuyao镜像仓库
    sed -i 's|quay\.io/kubevirt/|openfuyao/|g' kubevirt-operator.yaml
    # 在Kubernetes集群中部署KubeVirt Operator
    kubectl apply -f kubevirt-operator.yaml

    2.2 安装KubeVirt核心组件。

    创建kubevirt-cr.yaml文件,定义KubeVirt实例:

    #KubeVirt 自定义资源定义(CRD)配置文件
    #用于在 Kubernetes 集群中部署和配置 KubeVirt 虚拟化组件
    apiVersion: kubevirt.io/v1
    kind: KubeVirt
    metadata:
      name: kubevirt
      namespace: kubevirt
    spec:
      certificateRotateStrategy: {}
      configuration:
        developerConfiguration:
          useEmulation: false
          featureGates: []
      customizeComponents: {}
      imagePullPolicy: IfNotPresent
      workloadUpdateStrategy: {}

    执行如下命令,创建应用配置:

    kubectl apply -f kubevirt-cr.yaml

    2.3 验证部署状态

    执行如下命令,等待所有组件运行正常:

    kubectl get pods -n kubevirt

    当所有组件的状态为Running,表示组件运行正常。

    2.4 安装virtctl客户端

    virtctl是管理KubeVirt虚拟机的专用命令行工具,执行如下命令,安装virtctl。

    # 下载 ARM64 版本
    wget https://github.com/kubevirt/kubevirt/releases/download/v1.7.1/virtctl-v1.7.1-linux-arm64
    
    # 重命名并移动至路径
    mv virtctl-v1.7.1-linux-arm64 /usr/local/bin/virtctl
    chmod +x /usr/local/bin/virtctl
    
    # 验证版本
    virtctl version

    输出版本信息且Platform显示为Linux/arm64,表示部署成功。

  3. 制作KubeVirt镜像。

    3.1 执行如下命令,准备磁盘文件

    wget https://dl-cdn.openeuler.openatom.cn/openEuler-22.03-LTS-SP3/virtual_machine_img/aarch64/openEuler-22.03-LTS-SP3-aarch64.qcow2.xz
    xz -d openEuler-22.03-LTS-SP3-aarch64.qcow2.xz

    3.2 编写Dockerfile。

    创建Dockerfile将qcow2镜像打包进容器:

    FROM openeuler/openeuler:22.03
    ADD openEuler-22.03-LTS-SP3-aarch64.qcow2 /disk/disk.qcow2
    RUN chmod 644 /disk/disk.qcow2

    输入图片说明 说明:

    此处路径需与4.1中oe-vm.yaml定义中的path保持一致。

    3.3 构建并导出镜像。

    执行如下命令,构建并导出镜像

    # 构建镜像
    docker build -t openeuler2203-sp3:v1 .
    
    # 导出镜像为tar包
    docker save -o openeuler.tar openeuler2203-sp3:v1

    3.4 导入镜像到容器运行时。

    执行如下命令,将镜像导入Kubernetes使用的容器运行时(此处以containerd为例):

    ctr -n k8s.io image import openeuler.tar
  4. 创建并运行openEuler虚拟机。

    4.1. 准备虚拟机定义文件 (oe-vm.yaml)

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: openeuler-vm
    spec:
      running: false  # 初始状态为停止,创建后手动启动
      template:
        metadata:
          labels:
            kubevirt.io/domain: openeuler
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  bridge: {}
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
          volumes:
            - name: rootfs
              containerDisk:
                image: openeuler2203-sp3:v1
                path: /disk/disk.qcow2  # 必须与 Dockerfile 中的路径一致
            - name: cloudinit
              cloudInitNoCloud:
                userData: |-
                  password: openEuler12#$
                  chpasswd: { expire: False }
                  ssh_pwauth: True
                  packages:
                    - nginx
                  runcmd:
                    - systemctl enable nginx
                    - systemctl start nginx

    4.2 创建并启动虚拟机。

    执行如下命令,创建并启动虚拟机。

    # 创建虚拟机资源
    kubectl apply -f oe-vm.yaml
    
    # 查看状态(此时应为 Stopped)
    kubectl get vms
    
    # 启动虚拟机
    virtctl start openeuler-vm
    
    # 再次查看状态,等待变为 Running
    kubectl get vms

    4.3 连接虚拟机。

    虚拟机支持virtctl console(串口)SSH两种登录方式。 openEuler镜像默认登录账号:root,默认密码:openEuler12#$

    • 方式一:执行如下命令,使用virtctl console(串口连接)方式连接虚拟机
    virtctl console openeuler-vm

    显示以下结果,表示成功连接虚拟机:

    [root@master ~]# virtctl console openeuler
    Successfully connected to openeuler console. Press Ctrl+] or Ctrl+5 to exit console.
        
    openeuler login: root
    Password:
    Last login: Thu Mar  5 09:02:51 from 76.3.165.18 
        
    Welcome to 5.10.0-182.0.0.95.oe2203sp3.aarch64
    
    System information as of time:  Thu Mar  5 08:23:47 AM UTC 2026
    
    System load:    0.00
    Processes:      93
    Memory used:    10.2%    
    Swap used:      0.0%
    Usage On:       4%
    IP address:     172.27.205.169
    Users online:   1
    • 方式二:使用SSH连接。

    执行如下命令,获取虚拟机IP地址:

    kubectl get vmi openeuler-vm -o jsonpath='{.status.interfaces[0].ipAddress}'

    显示以下结果,表示成功连接虚拟机。

    ......
    Welcome to 5.10.0-182.0.0.95.oe2203sp3.aarch64
    
    System information as of time:  Thu Mar  5 08:23:47 AM UTC 2026
    
    System load:    0.00
    Processes:      93
    Memory used:    10.2%    
    Swap used:      0.0%
    Usage On:       4%
    IP address:     172.27.205.169
    Users online:   1

    4.4 停止虚拟机。

    执行如下命令,停止虚拟机。

    virtctl stop openeuler-vm

使用高级虚拟化管理能力

KubeVirt在鲲鹏节点上运行,支持ARM64虚拟化的高级虚拟化管理特性,包含:网卡热插拔、支持macvlan、支持SR-IOV硬件直通及热迁移、虚机热迁移等。

网卡热插拔能力

背景介绍

为运行中的虚拟机添加网卡,从正在运行的虚拟机中删除网卡。

具体的实现就是给运行的Pod增加和删除网卡,通过增加注解k8s.v1.cni.cncf.io/networks,控制器侦听Pod变化后,获取容器信息(容器ID和Net NS),最后调用CNI接口为容器增加网卡,具体流程如下:

kubevirt社区网络热插拔用户指导请参见KubeVirt网络热插拔用户指导

前提条件

部署Multus-cni thick pluginMultus Dynamic Networks Controller

shell
wget https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/deployments/multus-daemonset-thick.yml
kubectl apply -f multus-daemonset-thick.yml
# 其中使用的镜像为 ghcr.io/k8snetworkplumbingwg/multus-cni:snapshot-thick

wget https://github.com/k8snetworkplumbingwg/multus-dynamic-networks-controller/blob/main/manifests/dynamic-networks-controller.yaml
# 该yaml中镜像为 ghcr.io/k8snetworkplumbingwg/multus-dynamic-networks-controller:latest-amd64
# 修改镜像为 ghcr.io/k8snetworkplumbingwg/multus-dynamic-networks-controller:latest
kubectl apply -f dynamic-networks-controller.yaml

使用限制

  • 目前仅支持对使用virtio模型并通过bridge绑定或SR-IOV绑定连接的接口进行热插拔。
  • 目前仅支持对通过bridge绑定连接的接口进行热拔除。

操作步骤

  1. 集群中新建一个NetworkAttachmentDefinition

    yaml
    apiVersion: k8s.cni.cncf.io/v1
    kind: NetworkAttachmentDefinition
    metadata:
      name: new-fancy-net
    spec:
        config: '{
          "cniVersion": "0.3.1",
          "type": "bridge",
          "mtu": 1300,
          "name":"new-fancy-net"
        }'
  2. 部署VM,启动VM到running状态。

    yaml
    # 原始VM
    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: vm-hotplug
    spec:
      running: false  # 初始状态为停止,创建后手动启动
      template:
        metadata:
          labels:
            kubevirt.io/domain: openeuler
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
          volumes:
            - name: rootfs
              containerDisk:
                image: openeuler2203-sp3-test:v5
                path: /disk/disk.qcow2  # 必须与 Dockerfile 中的路径一致
            - name: cloudinit
              cloudInitNoCloud:
                userData: |-
                  password: openEuler12#$
                  chpasswd: { expire: False }
                  ssh_pwauth: True
                  packages:
                    - nginx
                  runcmd:
                    - systemctl enable nginx
                    - systemctl start nginx
  3. 添加网卡。

    kubectl edit vm vm-hotplug添加网卡,更新VM的spec.domain.devices.interfacesspec.networks如下:

    yaml
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
                  # new interface
                - name: dyniface1
                  bridge: {}
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
              # new network
            - name: dyniface1
              multus:
                networkName: new-fancy-net

    检查VM的网络接口是否添加成功:

    • virt-launcherPod中的annotations更新,出现新网卡的配置。
    • vmi.status.interfaces中出现新网卡。
    • 虚机中出现新网卡。
  4. 删除网卡。

    kubectl edit vm vm-hotplug删除网卡,更新VM的spec.domain.devices.interfaces对应网卡状态为absent

    yaml
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
                  # set the interface state to absent 
                - name: dyniface1
                  bridge: {}
                  state: absent
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
            - name: dyniface1
              multus:
              networkName: new-fancy-net

    检查VM的网络接口是否删除成功:

    • virt-launcherPod中的annotations更新,网卡删除。
    • vmi.status.interfaces中网卡删除。
    • 虚机中网卡删除。

macvlan

背景介绍

Macvlan是一种高效的Linux网络虚拟化技术,允许在一个物理网络接口(即"父接口")上创建多个虚拟网络接口(即"子接口")。每个子接口都被分配一个独立的MAC地址,并可以像普通网卡一样配置IP地址进行通信。这些虚拟设备,在外部看来就是多个独立的物理设备。这种机制的核心优势在于性能。它绕过了传统的Linux网桥,数据包可以直接通过物理网卡收发,减少了网络栈的处理环节,从而降低了延迟,提高了吞吐量。在KubeVirt环境中,它主要用于让虚拟机直接接入宿主机的底层(Underlay)网络,以获得接近于物理机的网络性能。

macvtap CNI包含一个设备插件,用于将macvtap接口暴露给Pod,由Multus这样的元插件会获取由设备插件分配的接口名称,并负责调用CNI插件时将该名称作为deviceID传递。

使用限制

macvtap类型网络接口不支持热插拔能力。

前提条件

创建macvtap CNI配置。

yaml
# 虚拟设备数量理论上限100万,推荐配置200以内
kind: ConfigMap
apiVersion: v1
metadata:
  name: macvtap-deviceplugin-config
data:
  DP_MACVTAP_CONF: |
    [ {
        "name" : "dataplane",
        "lowerDevice" : "enp1s0f0np0",
        "mode": "bridge",
        "capacity" : 20
    } ]

部署macvtap CNI

shell
wget https://github.com/kubevirt/macvtap-cni/blob/main/manifests/macvtap.yaml
kubectl apply -f macvtap.yaml
# 其中使用的镜像为 quay.io/kubevirt/macvtap-cni:latest

操作步骤

  1. 集群中新建一个NetworkAttachmentDefinition
    yaml
    kind: NetworkAttachmentDefinition
    apiVersion: k8s.cni.cncf.io/v1
    metadata:
      name: macvtapnetwork
      annotations:
        k8s.v1.cni.cncf.io/resourceName: macvtap.network.kubevirt.io/dataplane
    spec:
      config: '{
          "cniVersion": "0.3.1",
          "name": "macvtapnetwork",
          "type": "macvtap",
          "mtu": 1500
        }'
  2. 更新kubevirt,新增network.binding配置。
    yaml
      spec:
        certificateRotateStrategy: {}
        configuration:
          developerConfiguration:
            useEmulation: false
          network:  #新增network.binding配置
            binding:
              macvtap:
                domainAttachmentType: tap
        customizeComponents: {}
        imagePullPolicy: IfNotPresent
        imageRegistry: ttl.sh/openfuyao
        imageTag: v17
        workloadUpdateStrategy: {}
  3. VM中配置macvtap接口,新增VM的spec.domain.devices.interfacesspec.networks
    yaml
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
                - name: macvtap-net    # 新增:macvtap 接口定义
                  binding:             # 新增
                    name: macvtap      # 新增
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
            - name: macvtap-net        # 新增:macvtap 网络定义
              multus:                  # 新增:指定使用 Multus
                networkName: macvtapnetwork # 新增:对应 NetworkAttachmentDefinition 名称
          volumes:
    启动VM到running状态,进入VM中查看,有macvtap类型网卡。
    shell
    virtctl start <vm-name>
    virtctl console <vm-name>
    ip a

SR-IOV

背景介绍

SR-IOV(Single Root I/O Virtualization),是一种让单个物理PCIe设备(比如网卡)在虚拟化环境中“分身”成多个独立设备的硬件规范。

核心在于两种新类型:

  • 物理功能(Physical Function,PF):PF是具备完整PCIe能力的实体功能,负责向宿主机提供硬件业务能力,同时用于创建、管理对应一组VF;支持SR‑IOV的PCIe硬件至少包含1个PF。
  • 虚拟功能(Virtual Function,VF):VF为轻量化PCIe逻辑设备,由PF派生生成;单个VF同一时刻仅可挂载至一台虚拟机,单台虚拟机可配置多个VF。虚拟机操作系统可将VF识别为标准物理硬件,例如SR‑IOV网卡拆分的VF,在客户机内呈现为原生网卡。

当虚拟机直接使用一个VF时,数据可以不经过宿主机复杂的软件模拟层(如Linux网桥、Open vSwitch),直接在虚拟机和物理网卡之间交换。这种绕过操作系统内核直接通信的方式,极大地降低了网络延迟,并减少了CPU的额外开销,实现了近乎物理机的性能。

使用限制

本特性需要Linux内核支持VFIO,BIOS中需打开SMMU,在grub里配置iommu.passthrough=1,启用passthrough模式。

前提条件

部署SR-IOV Network Operator属危险操作,会重启所有SR-IOV设备的节点。

shell
# 安装Operator-SDK
export ARCH=$(case $(uname -m) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(uname -m) ;; esac)
export OS=$(uname | awk '{print tolower($0)}')
export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/v1.42.2
curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}
chmod +x operator-sdk_${OS}_${ARCH} && mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk

# 安装operator,按如下步骤从源码生成manifests
# 也可直接获取yaml文件 https://gitcode.com/openFuyao/kubevirt/tree/of-dev%2Fv1.7.1/examples/sriov
git clone https://github.com/k8snetworkplumbingwg/sriov-network-operator.git
cd sriov-network-operator
make deploy-setup-k8s

# 需要SR-IOV的节点打标签
kubectl label node node node-role.kubernetes.io/worker=

操作步骤

  1. 创建SriovNetworkNodePolicy。
    yaml
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: policy-mellanox
      namespace: sriov-network-operator
    spec:
      nodeSelector:
        node-role.kubernetes.io/worker: ""
      resourceName: intel_sriov_vfio
      priority: 99
      mtu: 1500
      numVfs: 8  # 查询可分配的VF数量 cat /sys/class/net/<接口名>/device/sriov_totalvfs
      nicSelector:
        vendor: "15b3"      # 在sriovnetworknodestates资源中查看上报的vendor
        deviceID: "1015"    # 在sriovnetworknodestates资源中查看deviceID
        rootDevices:
        - "0000:01:00.0"    # 只使用第一个端口 enp1s0f0np0
      deviceType: vfio-pci  # kubevirt使用vfio-pci类型
      isRdma: false
  2. 创建SriovNetwork。
    yaml
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: kubevirt-vfio-network
      namespace: sriov-network-operator  # 使用你的实际命名空间
    spec:
      networkNamespace: default  # 根据你的虚拟机部署命名空间调整
      resourceName: intel_sriov_vfio
      ipam: ""
  3. VM中配置sriov接口,新增VM的spec.domain.devices.interfacesspec.networks
    yaml
    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: vm-sriov
    spec:
      running: false  # 初始状态为停止,创建后手动启动
      template:
        metadata:
          labels:
            kubevirt.io/domain: openeuler
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
                - name: sriov-net
                  sriov: {}
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
            - multus:
                networkName: kubevirt-vfio-network  # 与SriovNetwork名字一致
              name: sriov-net
          volumes:
            - name: rootfs
              containerDisk:
                image: openeuler2203-sp3-test:v5
                path: /disk/disk.qcow2  # 必须与 Dockerfile 中的路径一致
            - name: cloudinit
              cloudInitNoCloud:
                userData: |-
                  password: openEuler12#$
                  chpasswd: { expire: False }
                  ssh_pwauth: True
                  packages:
                    - nginx
                  runcmd:
                    - systemctl enable nginx
                    - systemctl start nginx

启动VM到running状态,进入VM中查看有sriov类型功能完备的真实物理网卡接口。

shell
virtctl start <vm-name>
virtctl console <vm-name>
ip a
  • 它有自己的固件版本。
  • 它直接加载了厂商的mlx5_core驱动。
  • 它的硬件卸载功能(如TC offload)已可用。
  • 它的物理链路已正常连接 (Link up)。

SR-IOV实时迁移

背景介绍

配置SR‑IOV直通网卡的虚拟机支持在线热迁移。因VF采用硬件直通模式,虚拟机迁移至目标节点后无法自动重新挂载对应VF资源,需人工介入配置,迁移过程中将产生短时业务中断。为保障迁移后网络快速恢复,虚拟机需预先配置固定静态IP地址与静态MAC地址,避免迁移后网络参数变更导致业务异常。

使用限制

本特性需要Linux内核支持VFIO,BIOS中需打开SMMU,在grub里配置iommu.passthrough=1,启用passthrough模式。

前提条件

操作步骤

  1. 打开特性门控SRIOVLiveMigration

    yaml
    # kubectl edit -n kubevirt kubevirt
      spec:
        certificateRotateStrategy: {}
        configuration:
          developerConfiguration:
            featureGates:
              - SRIOVLiveMigration  #添加SRIOVLiveMigration
            useEmulation: false
          migrations:
            unsafeMigrationOverride: true
          network:
            binding:
              macvtap:
                domainAttachmentType: tap
  2. 原始VM中配置sriov接口,写入静态的MAC地址和IP地址。

    yaml
    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: vm-sriov-ip-mac
    spec:
      running: false  # 初始状态为停止,创建后手动启动
      template:
        metadata:
          labels:
            kubevirt.io/domain: openeuler
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
                - name: sriov-net
                  macAddress: "02:00:00:00:00:01"   # 指定静态mac地址
                  sriov: {}
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
            - multus:
                networkName: kubevirt-vfio-network
              name: sriov-net
          volumes:
            - name: rootfs
              containerDisk:
                image: openeuler2203-sp3-test:v5
                path: /disk/disk.qcow2  # 必须与 Dockerfile 中的路径一致
            - name: cloudinit
              cloudInitNoCloud:
                userData: |-
                  password: openEuler12#$
                  chpasswd: { expire: False }
                  ssh_pwauth: True
                  packages:
                    - nginx
                  runcmd:
                    - systemctl enable nginx
                    - systemctl start nginx
                networkData: |
                  version: 2
                  ethernets:
                    sriov-net:
                      match:
                        macaddress: "02:00:00:00:00:01"
                      set-name: sriov-net
                      addresses:
                      - 76.3.165.23/32  # 指定静态ip
                      dhcp4: no

    进入VM中查看sriov设备上指定了MAC地址和IP地址。

    shell
    virtctl console <vm-name>
    ip a
  3. 部署VirtualMachineInstanceMigration执行热迁移。

    yaml
    apiVersion: kubevirt.io/v1
    kind: VirtualMachineInstanceMigration
    metadata:
      name: migration-sriov
    spec:
      vmiName: vm-sriov-ip-mac
  4. 等待迁移完成。

    确认VM迁移到另一个节点,进入迁移后的VM中,设备仍保持配置的MAC地址和IP地址。

    shell
    kubectl get vm <vm-name>
    virtctl console <vm-name>
    ip a

虚拟机热迁移

背景介绍

目前最新kubevirt官方已声明支持ARM64虚机热迁移,以及虚机暂停/恢复,快照等能力。

使用限制

前提条件

操作步骤

  1. 部署原始VM。

    yaml
    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: vm-migrate
    spec:
      running: false  # 初始状态为停止,创建后手动启动
      template:
        metadata:
          labels:
            kubevirt.io/domain: openeuler
        spec:
          domain:
            devices:
              disks:
                - name: rootfs
                  disk:
                    bus: virtio
                - name: cloudinit
                  disk:
                    bus: virtio
              interfaces:
                - name: default
                  masquerade: {}
            resources:
              requests:
                memory: 1Gi
              limits:
                memory: 1Gi
          networks:
            - name: default
              pod: {}
          volumes:
            - name: rootfs
              containerDisk:
                image: openeuler2203-sp3-test:v5
                path: /disk/disk.qcow2  # 必须与 Dockerfile 中的路径一致
            - name: cloudinit
              cloudInitNoCloud:
                userData: |-
                  password: openEuler12#$
                  chpasswd: { expire: False }
                  ssh_pwauth: True
                  packages:
                    - nginx
                  runcmd:
                    - systemctl enable nginx
                    - systemctl start nginx

    启动VM到running状态。

    shell
    virtctl start <vm-name>
  2. 部署VirtualMachineInstanceMigration执行热迁移。

    yaml
    apiVersion: kubevirt.io/v1
    kind: VirtualMachineInstanceMigration
    metadata:
      name: migration-job
    spec:
      vmiName: vm-migrate
  3. 等待迁移完成。

    确认VM迁移到另一个节点,查看VirtualMachineInstance,其中.status.migrationState中包含了迁移的信息。

使用界面操作管理虚机能力

背景介绍

当前openFuyao容器平台的管理面支持对自定义资源的管理,通过kubevirt能力管理的虚机,在自定义资源页面显示virtualmachines.kubevirt.io资源,支持基础生命周期的管理操作。

操作限制

前提条件

已部署openFuyao容器平台的管理面。

注意事项

可通过页面权限管理设置VM的操作权限,避免未授权用户操作他人的VM:请参见RBAC管理

操作步骤

  1. 登录openFuyao管理面:请参见注册和登录
  2. 虚机生命周期管理操作。
    • 创建虚机:
      1. 在openFuyao平台左侧导航栏“资源管理”中选择“自定义资源”,进入“自定义资源”界面”。
      2. 在自定义资源列表界面查找virtualmachines.kubevirt.io资源,进入“实例”页签。
      3. 单击右上角的创建,在yaml模板中填写虚机的配置信息。
    • 删除虚机:
      1. 在“实例”页签中,选择要删除的虚机,单击删除按钮。
      2. 确认删除操作。
    • 开机/关机/重启虚机:
      1. 在“实例”页签中,选择要操作的虚机,单击开机/关机/重启按钮。
      2. 界面弹出“开机/关机/重启成功”时,表示开机/关机/重启操作成功,界面弹出“开机/关机/重启未成功”时,表示操作失败,请进一步根据提示或者日志进行分析。