type
Post
status
Published
date
Jan 9, 2024
slug
summary
VDSM 是虚拟化管理器(如 oVirt 引擎或 Red Hat Enterprise Virtualization Manager)所需的守护进程,用于管理 Linux 主机及其 KVM 虚拟机客户机。VDSM 管理和监视主机的存储、内存和网络,以及虚拟机的创建、其他主机管理任务、统计数据收集和日志收集。 –来自 ovirt 官网
tags
开发
category
技术分享
icon
简介
VDSM 是虚拟化管理器(如 oVirt 引擎或 Red Hat Enterprise Virtualization Manager)所需的守护进程,用于管理 Linux 主机及其 KVM 虚拟机客户机。VDSM 管理和监视主机的存储、内存和网络,以及虚拟机的创建、其他主机管理任务、统计数据收集和日志收集。 –来自 ovirt 官网
简单点说, VDSM 是一个运行在物理机上的守护进程,对外暴露了一系列接口,方便上层应用在物理机上创建虚拟机,修改物理机的网络配置,创建存储等。
背景
之前有段时间,公司里让加急学习 ovirt 相关技术,而我被分配去熟悉 VDSM 的项目,虽然时间时间已经过去了很久,想了一想,还是有必要做下记录,方便以后有需要时查看。因为只是粗略的介绍一下,所以直接跳过编译、单测以及各种代码规范等。
代码入口
注意,本文代码基于 VDSM v4.4.100.2,新版本或者旧版本中的实现可能不一致,注意甄别。
阅读 VDSM 源码注意,VDSM 中大量使用了 python 的魔术方法,动态的加载方法,很多时候你发现某个方法在 IDE 中找不到引用,那大概率就是通过魔术方法+字符串的方式来调用的,此时可以使用全局搜索,去全局搜索哪些地方有同名的方法
VDSM 的主要代码都在
/lib/vdsm 这个项目的相对路径下,其中包括了 api、common、hook、super-vdsm等等多个模块,而整个项目在安装完成以后,至少会有两个 service(由 systemd 管理,可用 systemctl 查看服务状态),第一个是 vdsmd,第二个是 super-vdsmd。这里对
super-vdsm 只简单介绍一下,vdsm 是由 vdsm 用户启动的守护进程,而 super-vdsm 是由 root 用户启动的守护进程,super-vdsm 主要用户执行一些需要 root 权限的操作,比如对物理机的网络进行配置,比如增加路由,创建虚拟网卡等。vdsmd.py 是 VDSM 的入口,其中 main() 方法调用了 run() 启动了 vdsm 了,在 run 中,主要的逻辑在serve_clients(log) 中。进入 serve_clients,有 libvirtconnection.start_event_loop() 用于监听 libvirt 事件,这里点击函数跟进去就可以看到。然后
这里创建了一个调度器,这个调度器是 VDSM 自己设计的,晦涩难懂,有功夫的可以自己好好看一看,我写不明白,简单理解就是类似 Go 的调度器,VDSM 把自己的任务提交以后,由它自己去执行,监控任务进度,以及返回任务状态。
这里的 cif.start() 是重点,首先从 clientIF 获取了一个示例,然后执行了 start(),注意,这里将前面初始化的 scheduler 以参数的形式传递了进去。
让我们跳转到
clientIF.py 去看里面都做了什么。clientIF.py 的 __init_. 方法,初始化了 VDSM 的大部分内容,比如锁还启动了 RPC 以及 HTTP 服务器
这里的 _prepareJSONRPCServer 进去,有一个 self._acceptor.add_detector()。
在 VDSM,官方只有 http server 和 rpc server,但是实际上这里是预留出来了接口的,在 clientIF.py 的 _createAcceptor() 方法中,使用了一个 MultiProtocolAcceptor(),只要你实现了它的 def detect(self, data) 以及 def handle_socket(self, client_socket, socket_address),那么就可以实现一个自己的协议的 server。
各个模块
API
网络模块,对外提供调用的方法,基本都在 lib/vdsm/network/api.py 这个文件中,其中有一些方法通过 supervdsm_api 的方式暴露出去,供 ovirt-engine,或者其它的 client 去调用。在 api.py 中,又会通过调用 network 模块下的其它模块,去完成需要的操作。
Common
代码中的路径为 lib/vdsm/network/common,里面提供了一些通用的方法。
configurators
lib/vdsm/network/configurators,提供了一些使用 linux 中的 tc (一个命令行工具)去修改网络配置,以实现主机 qos 的方法。
Ip
lib/vdsm/network/ip,提供验证 nameserver,验证 ip 地址格式是否合法等的方法。
Lldp
获取所有设备的 lldp 信息,lldp 是一个链路层发现协议,用户发现交换机端口等,详细概念自己谷歌。
Lldpad
通过 python 的 cmd.exec_sync() 执行 shell 命令,包括 /usr/sbin/lldptool、/usr/bin/systemctl,去获取 lldpad.service 的状态信息,暴露出方法供前一个模块 lldp 调用。
Netinfo
提供跟网络信息有关的方法,包括获取主机的 ip 地址信息,获取主机 bond 信息 Linux 网卡 Bonding 配置 ,获取主机上的 bridges,添加网络设备的 qos 等等。
Netlink
对 netlink 的封装。
Netswitch
对主机网络的操作,其中包括一个主要的用于配置网络的方法, lib/vdsm/network/netswitch/configurator.py 中的 setup()。
Nmstate
使用 nmstate 完成各种跟网络配置相关的操作,提供方法供其它模块调用
Tc
调用 linux 主机上的 tc 命令,完成网络配置,lib/vdsm/network/tc/_wrapper.py。