Lazy loaded image
技术分享
vdsm源码阅读
00 分钟
2024-1-9
2024-12-27
type
status
date
slug
summary
tags
category
icon
password

简介

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。

参考

上一篇
vdsm中network模块的dhcp-monitor
下一篇
kubelet节点磁盘爆满处理记录