KubeVirt 源码阅读(一):了解KubeVirt 基础架构及虚机创建流程
1. 基础组件架构
安装好 Kubevirt 后,在集群中,会多出如下几种组件:
- virt-api:一个集群两个副本,负责接收有关 kubectl virt 的请求,并与 k8s api server 通信完成 vmi 等资源创建与虚拟机生命周期管理
- virt-controller:一个集群两个副本
- virt-operator:一个集群一个副本,全局唯一,
- virt-handle:每个节点一个,负责与 k8s api server、virt-lanucher通信来完成虚拟机的生命周期管理。
- virt-launcher:每个虚拟机一个,负责与libvirt api 通信提供虚拟机生命周期管理。
2. 虚拟机创建流程
虚拟机创建的整体流程是:
- 执行
kubectl apply -f vm.yaml
- k8s api-server 收到请求后会创建 vm 对象
- virt-controller 监控到有新的 vm 对象
- 就会调用 k8s api-server
- 去创建对应的 vmi 对象
- virt-controller 监控到有新的 vmi 对象
- 就会调用 k8s api-server去创建对应的 virt-launcher-xxx Pod 对象
- Pod 的创建自然是要先走 kube-scheduler 选一台合适的 Node
- 选到之后,创建对应 Pod,启动 virt-launcher 进程监听来自 virt-handler 的消息
- 去对应更新 vmi 的 nodeName 字段
- 节点上的 virt-handler 通过 Informer 监听到有新 vmi 创建到自己的节点后
- 发送 gRPC 消息把该 vmi 的各项配置发给 virt-launcher 进程,启动虚拟机
- virt-launcher 接收到 vmi 的配置后转成虚拟机的 xml 文件
- 启动该虚拟机
- 虚拟启动之后,更新 vmi 的虚拟机状态
为了方便大家理解,我手绘了一张流程图,帮助大家理解
其中还有更细的细节由于画布限制没法完全展示。
比如在创建 vmi 对象之前,virt-controller 其实会先检查是否有 datavolume 的配置,如果有会先去创建 datavolume(其中如果是使用 lvm 的 sc,还涉及 pod 的调度创建,与 PV 的创建,数据导入等),再检查运行策略,如果是running,才会去调用k8s api 创建 vmi 对象,否则需要等你手工 kubectl virt start [vmname]
才会创建 vmi 对象,走后面的流程。
3. 通用源码入口
通过上面的一张图,理解了 KubeVirt 创建虚拟机的整体流程后,接下来,我会开始阅读 kubevirt 各个组件的代码,并且把其中的一些要点通过文章的形式分享出来,希望对你会有帮助。
在此之前,需要知道所有的 kubevirt 组件都是从 cmd/virt-* 开始的