Lazy loaded image
技术分享
vdsm中的qos
00 分钟
2024-2-1
2024-12-27
type
status
date
slug
summary
tags
category
icon
password
https://tonydeng.github.io/sdn-handbook/linux/tc.html Vdsm 中,vm 的流量控制与 host 的流量控制有不同的接口和调用链。 fq_codel 是一种流量控制算法:https://queue.acm.org/detail.cfm?id=2209336 ## QOS 服务质量(英语:Quality of Service,缩写QoS)是一个术语,在分组交换网络领域中指网络满足给定业务合约的几率;或在许多情况下,非正式地指分组在网络中两点间通过的几率。QoS是一种控制机制,它提供了针对不同用户或者不同数据流采用相应不同的优先级,或者是根据应用程序的要求,保证数据流的性能达到一定的水准。QoS的保证对于容量有限的网络来说是十分重要的,特别是对于流多媒体应用,例如VoIP和IPTV等,因为这些应用常常需要固定的传输率,对延迟也比较敏感。 ## Ovirt 中的 QOS 在 ovirt 中,可以针对磁盘、主机网络、虚拟机网络、cpu设置 qos 。 ### Host 网络 Qos #### 代码分析 Ovrit 中设置网络相关的,基本都由一个函数(setupNetworks)作为入口。 https://www.ovirt.org/develop/developer-guide/vdsm/network.html
在 ovirt-engine 代码中,以下几种情况会调用 setupNetworks: 1、创建主机、更新主机,或者手动调用主机的重新安装会执行; 2、在主机的网络编辑页面对网络适配器的增删改会调用; 3、复制主机网络; 4、主机网络启用/禁用; 5、给网络配置打标签; 首先,在 API.py 中暴露 rpc 接口给 engine: 代码相对路径 lib/vdsm/API.py
Networks 的接口通过 supervdsm-api 暴露出来,所以非 supervdsm 服务在调用时需要使用 getProxy() 去调用,被调用的函数位置为:lib/vdsm/network/api.py -> _setup_networks
继续跟着 setup 的函数进去,会来到一个名为 _setup_nmstate 的函数,位置在: lib/vdsm/network/netswitch/configurator.py 这里调用了 _setup_qos 的方法去设置 host 网络
_setup_qos 又去调用了 _configure_qos,而 _configure_qos 最终调用了 qos 模块的 qos.configure_outbound
注意:这里只有设置 outbound,没有 inbound,对应到 ovirt-engine,在设置主机网络的 qos 时,也只支持 outbound,不支持 inbound,原因是网络没有办法限制外部的设备往自身发送网络包,所以 inbound 规则本身能做的事情非常少,合理的方式是去限制网络数据包的发送方。
一直到 configure_outbound 这个函数,终于看到跟网络控制相关的一些代码了。 root_qdisc 获取了网卡设备的 qdisc。
然后 _fresh_qdisc_conf_out 会去更新 qdisc,当没有 root_qdisc 时会调用 _qdisc_conf_out 去新增一个 qdisc。 接着看一下 _qdisc_conf_out 方法,这里面就是在拼接一些规则,然后调用 tc 的命令去完成主机网络的配置。 _fresh_qdisc_conf_out 也是类似,拼接 tc 的规则,然后去完成主机网络的配置。

VM 网络 Qos

vm qos 由 libvirt xml 定义,参考官网定义:https://libvirt.org/formatnetwork.html#quality-of-service #### 代码分析 vm 网络的 qos,由 lib/vdsm/API.py 中的 hotplugNic 设置网络接口的 inbound 和 outbound 的带宽。 在 ovirt-engine 中,在插入和拔出网络接口时,会调用 hotplugNic 方法。 首先,由 API.py 中的 hotplugNic 调用了 self.vm.hotplugNic(params) 去查看 self.vm.hotplugNic(params) 的代码: 其中主要就是解析 params 中的数据,然后拼接出来一个 xml 数据,并调用 libvirt 去操作。
dev_from_xml 在 lib/vdsm/virt/vmdevices/network.py 中有对应的实现 from_xml_tree。 attachDevice 最终是调用的 libvirt,官网中有对应的方法 https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainAttachDevice attachDevice 的调用链:vm.self._dom,而 self._dom 是 在 vm._run 中的

VM Qos(cpu limits和 IO limits)

vdsm 更新 cpu limits 和 IO limits(磁盘 iops) 是通过调用 libvirt 去更新 vm 的 xml 实现的,更新 vm 的方法有多个。其中一个是 updateVmPolicy,在修改已有的 qos 时,会调用这个方法。 还有一个是 hotplugDisk,这是在附加磁盘时会调用,也是去更新 vm 的 xml。 在网页上设置了 cpu qos 和 磁盘 qos以后,需要附加到虚拟机上,才会调用 updateVmPolicy 方法,使得 qos 生效。没附加到虚拟机之前,这些修改不会在 vdsm 的日志中体现。 updateVmPolicy: - vm 探活时执行:探活过程中有判断,判断数据有变化(可能是根据时间戳对比)时调用,探活频率是5秒一次。页面上点击更新是直接触发。 - 手动移除 qos 时会执行,移除 storage 和 cpu 的 qos 时会触发。 hotplugDisk: - 目前已知在附加磁盘时,会调用。还有一个 AddDiskComand,猜测是在新建虚拟机时点击新建磁盘,最后也会调用到这里。 代码分析 针对虚拟机的资源限制,入口函数为 lib/vdsm/API.py 中的 updateVmPolicy。然后调用了 lib/vdsm/virt/vm.py 中的 updateVmPolicy 函数。 updateVmPolicy 函数如下:
最终 vdsm 是调用了 libvirt 的 setMetadata 方法去更新 vm 的信息,有关 vm 的 xml 定义可以参考: https://libvirt.org/formatdomain.html
上一篇
ovirt-engine开发
下一篇
vdsm中network模块的dhcp-monitor