kubevirt(五)VirtualMachine

kubevirt除了定义VirtualMachineInstance(后文简称VMI)这个与虚拟机对应的CRD,还定义了一个叫做VirtualMachine(后文简称VM)的CRD。本文假设读者对VMI有一定的了解,并基于kubevirt@0.49.0来探讨下VM。

VirtualMachine定义

首先来看看VM这个CRD的定义:

type VirtualMachine struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    // Spec contains the specification of VirtualMachineInstance created
    Spec VirtualMachineSpec `json:"spec" valid:"required"`
    // Status holds the current state of the controller and brief information
    // about its associated VirtualMachineInstance
    Status VirtualMachineStatus `json:"status,omitempty"`
}

type VirtualMachineSpec struct {
    // Running controls whether the associatied VirtualMachineInstance is created or not
    // Mutually exclusive with RunStrategy
    Running *bool `json:"running,omitempty" optional:"true"`

    // Running state indicates the requested running state of the VirtualMachineInstance
    // mutually exclusive with Running
    RunStrategy *VirtualMachineRunStrategy `json:"runStrategy,omitempty" optional:"true"`

    // FlavorMatcher references a flavor that is used to fill fields in Template
    Flavor *FlavorMatcher `json:"flavor,omitempty" optional:"true"`

    // Template is the direct specification of VirtualMachineInstance
    Template *VirtualMachineInstanceTemplateSpec `json:"template"`

    // dataVolumeTemplates is a list of dataVolumes that the VirtualMachineInstance template can reference.
    // DataVolumes in this list are dynamically created for the VirtualMachine and are tied to the VirtualMachine's life-cycle.
    DataVolumeTemplates []DataVolumeTemplateSpec `json:"dataVolumeTemplates,omitempty"`
}

在VirtualMachineSpec中,有以下的参数:

  • Running:与RunStrategy字段互斥(即只能二选一),如果该字段为true,创建了VM对象后会根据Template中的内容创建VMI,false则不会。
  • RunStrategy:与Running字段互斥(即只能二选一),虚拟机的运行策略,可选值为:Always-表示VMI对象应该一直是running状态;Halted-表示VMI对象永远都不应该是running状态;Manual-VMI可以通过API接口启动或者停止;RerunOnFailure-VMI初始应为running,当有错误发生时会自动重启;Once-VMI只会运行一次,当出现错误等情况时不会重启。
  • Flavor:虚拟机底层特性配置,从代码上看目前只有CPU的配置,相关配置项包括是否绑定CPU(绑定的CPU只能给该虚拟机使用)、虚拟机中的线程数、NUMA配置等。flavor有VirtualMachineFlavor和VirtualMachineClusterFlavor两种类型数据。该字段会被填充到VMI模板对应字段中。
  • Template:VMI的模板,类似deployment中配置的pod模板。
  • DataVolumeTemplates:数据卷模板,这里配置的数据卷会自动创建,并且可以被Template字段的模板中使用。这些数据卷的生命周期和VM对象的生命周期一致。

VirtualMachine controller

对VirtualMachine CRD定义有些了解后,再来看看VirtualMachine对应的controller部分逻辑。

初始化部分:

// cmd/virt-controller/virt-controller.go
func main() { 
    watch.Execute()
}

// pkg/virt-controller/watch/application.go
func Execute() {
    /*...*/
    app.initVirtualMachines()
    /*...*/
}

// pkg/virt-controller/watch/application.go
func (vca *VirtControllerApp) initVirtualMachines() {
    /*...*/
    vca.vmController = NewVMController(...)
}

// pkg/virt-controller/watch/vm.go
func NewVMController(...) *VMController {
    /*...*/
    c.vmInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        AddFunc:    c.addVirtualMachine,
        DeleteFunc: c.deleteVirtualMachine,
        UpdateFunc: c.updateVirtualMachine,
    })

    c.vmiInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        AddFunc:    c.addVirtualMachineInstance,
        DeleteFunc: c.deleteVirtualMachineInstance,
        UpdateFunc: c.updateVirtualMachineInstance,
    })

    c.dataVolumeInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
        AddFunc:    c.addDataVolume,
        DeleteFunc: c.deleteDataVolume,
        UpdateFunc: c.updateDataVolume,
    })
    
    return c
}

从初始化部分代码来看,vm controller注册了vm、vmi、dv三种资源的add/update/delete事件处理函数,当这三种资源事件发生后且满足一定的条件时,vm controller会把对应的vm对象的key(namespace/name)放入workQueue队列中。

有了入队,再看看出队消费逻辑:

// pkg/virt-controller/watch/vm.go
func (c *VMController) Execute() bool {
    key, quit := c.Queue.Get()
    /*...*/
    if err := c.execute(key.(string)); err != nil {
        /*...*/
    } else {
        /*...*/
    }
    return true
}

// pkg/virt-controller/watch/vm.go
func (c *VMController) execute(key string) error {
    /*...*/
    
    // 根据vm对象DataVolumeTemplate中定义的dv列表
    // 获取已经创建的dv列表
    dataVolumes, err := c.listDataVolumesForVM(vm)
    if err != nil {
        logger.Reason(err).Error("Failed to fetch dataVolumes for namespace from cache.")
        return err
    }

    if len(dataVolumes) != 0 {
        // 如果dv已经存在,则把该dv的ownerReference声明为该vm
        dataVolumes, err = cm.ClaimMatchedDataVolumes(dataVolumes)
        if err != nil {
            return err
        }
    }

    var syncErr syncError

    syncErr, err = c.sync(vm, vmi, key, dataVolumes)
    if err != nil {
        return err
    }
    
    /*...*/
}

// pkg/virt-controller/watch/vm.go
func (c *VMController) sync(vm *virtv1.VirtualMachine, vmi *virtv1.VirtualMachineInstance, key string, dataVolumes []*cdiv1.DataVolume) (syncError, error) {
    /*...*/
    
    // 判断是否有dv不存在,如果不存在则创建
    // 当所有dv都已经ready时,dataVolumesReady为true
    dataVolumesReady, err := c.handleDataVolumes(vm, dataVolumes)
    if err != nil {
        syncErr = &syncErrorImpl{fmt.Errorf("Error encountered while creating DataVolumes: %v", err), FailedCreateReason}
    } else if dataVolumesReady || runStrategy == virtv1.RunStrategyHalted {
        syncErr = c.startStop(vm, vmi)
    } else {
        log.Log.Object(vm).V(3).Infof("Waiting on DataVolumes to be ready. %d datavolumes found", len(dataVolumes))
    }
    
    /*...*/
}

// pkg/virt-controller/watch/vm.go
func (c *VMController) startStop(vm *virtv1.VirtualMachine, vmi *virtv1.VirtualMachineInstance) syncError {
    /*...*/
    
    switch runStrategy {
    case virtv1.RunStrategyAlways:
        // 1.如果vmi存在,判断虚拟机是否有stop操作,如果有则先删除旧的vmi
        // 2. 根据vm模板创建一个新的vmi
        
    case virtv1.RunStrategyRerunOnFailure:
        // 1.如果vmi存在,判断虚拟机是否有stop操作或者vmi状态为failed,则删除旧的vmi
        // 2.根据vm模板创建一个新的vmi
        
    case virtv1.RunStrategyManual:
        // 1.如果vmi存在且有stop虚拟机的动作,则删除旧的vmi
        // 2.如果vmi不存在且有start虚拟机的动作,则根据vm模板创建一个新的vmi
        
    case virtv1.RunStrategyHalted:
        // 1.如果vmi不存在,且有start虚拟机的动作,把vm对象的runStrategy改为virtv1.RunStrategyAlways
        // 2.如果vmi存在,则删除vmi
        
    default:
        // 报错
    }
}

总结

通过上面的代码可以看出,vm controller的逻辑还是比较简单的,主要是创建/删除vmi,并根据vm中的runStrategy和vmi相匹配。有点类似于deployment和pod的关系:pod对应具体的应用实例,deployment则是基于pod做一些更完善的动作,例如控制pod副本数等。

总结起来vm和vmi的关系为:vmi对应虚拟机实例,vm则是在vmi的基础上的一层更完善的逻辑控制。通过vm创建的vmi虚拟机可以做到硬重启(删除vmi再创建vmi)等功能,单独的vmi虚拟机只能做到软重启、暂停等功能。

除了上述差异,virtctl操作这两种资源的子命令也不同。对vm资源的操作命令包括:virtctl restart/migrate/start/stop/portforward/addvolume/removevolume,对vmi资源的操作命令则为:virtctl freeze/unfreeze/softreboot/pause/unpause/console/vnc/usbredir/portforward/test/guestosinfo/userlist/filesystemlist/addvolume/removevolume。(对应pkg/virt-api/api.go composeSubresources函数)

微信公众号卡巴斯同步发布,欢迎大家关注。

<think>好的,用户想了解KubeVirt的使用指南和技术文档,我需要根据提供的引用内容来组织回答。首先,我需要确认已有的引用资料中哪些部分与使用指南和技术文档相关。 引用[1]提到在KubeVirt中使用GPU Operator,并有一个示例输出,可能涉及配置或补丁的应用。引用[2]介绍了kubevirt-manager.io,这是一个Web管理工具,对用户来说可能是一个重要的使用入口。引用[3]是关于Cluster API Provider for KubeVirt,可能涉及集群层面的集成和管理。引用[4]是关于cilium的kube-proxy替换模式,可能和网络配置有关,但不确定是否直接关联KubeVirt的使用指南。 首先,应该分步骤介绍KubeVirt的基本使用流程,包括安装、创建虚拟机、管理工具等。然后结合引用中的内容,比如kubevirt-manager.io作为管理工具,Cluster API Provider的作用,以及GPU Operator的使用。需要确保每个部分都引用正确的来源。 另外,用户可能需要入门指南的具体步骤,例如如何应用补丁(引用1中的示例),如何访问Web界面(引用2),以及集群管理(引用3)。网络配置部分(引用4)可能属于高级主题,可以在进阶部分提到。 需要检查是否有遗漏的关键点,比如官方文档的链接、CLI工具的使用等。由于引用中没有提供官方文档的直接链接,可能需要建议用户查阅官方资源,但根据现有引用,尽可能提供具体的信息。 最后,生成相关问题时要基于回答内容,可能涉及安装、虚拟机管理、工具集成、优化等。</think>### KubeVirt 使用指南与技术文档解析 #### **一、核心概念** KubeVirtKubernetes 的扩展组件,允许在 Kubernetes 集群中直接运行虚拟机(VM),实现容器与虚拟机工作负载的统一管理[^1]。其核心功能包括: - 通过自定义资源(CRD)定义虚拟机(`VirtualMachine`)、虚拟机实例(`VirtualMachineInstance`)等对象 - 与 Kubernetes 网络、存储体系无缝集成 - 支持多种虚拟化后端(如 QEMU/KVM) #### **二、快速入门指南** 1. **安装部署** ```bash # 使用 KubeVirt Operator 进行安装 export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases | jq -r '.[0].tag_name') kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml ``` 安装后可通过 `kubectl get pods -n kubevirt` 验证组件状态[^1]。 2. **创建首个虚拟机** 定义 YAML 文件(如 `vm.yaml`): ```yaml apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: test-vm spec: running: true template: metadata: labels: kubevirt.io/domain: test-vm spec: domain: devices: disks: - name: rootdisk disk: {} resources: requests: memory: 1G volumes: - name: rootdisk containerDisk: image: kubevirt/cirros-registry-disk-demo ``` 应用配置:`kubectl apply -f vm.yaml`,通过 `virtctl console test-vm` 连接控制台。 #### **三、关键工具与集成** 1. **kubevirt-manager.io** - 提供 Web 界面管理虚拟机生命周期(创建/启动/停止) - 可视化查看虚拟机资源使用情况 - 支持多集群管理(需配置 Cluster API Provider for KubeVirt[^3]) 2. **GPU 加速支持** 通过 GPU Operator 实现虚拟机的 GPU 直通: ```bash kubectl patch kubevirt.kubevirt.io/kubevirt --type=merge -p '{"spec":{"configuration":{"developerConfiguration":"enableGPU: true"}}}' ``` 需确保节点已安装 NVIDIA 驱动[^1]。 3. **网络配置** 结合 Cilium CNI 实现高性能网络: ```bash kubectl -n kube-system exec ds/cilium -- cilium status | grep KubeProxyReplacement # 输出应显示 Strict 模式[^4] ``` #### **四、进阶应用场景** - **混合工作负载编排**:容器与虚拟机并存的服务编排 - **传统应用迁移**:将遗留系统迁移至 Kubernetes 平台 - **边缘计算**:通过 Cluster API 管理边缘节点的虚拟机 §§ 1. 如何监控 KubeVirt 虚拟机的性能指标? 2. KubeVirt 与普通容器在资源调度上有何区别? 3. 如何实现 KubeVirt 虚拟机的热迁移? 4. 在 KubeVirt 中如何配置持久化存储?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值