可脚本化的KVM/QEMU客户代理(主机端)
项目描述
Python包negotiator-host、negotiator-guest和negotiator-common共同实现了一个可脚本化的Python KVM/QEMU客户代理基础设施。该基础设施支持Linux主机和客户机之间的实时双向通信,允许主机和客户机在“另一边”调用用户定义的命令。
因为用户定义了主机和客户机可以执行的命令,所以用户控制主机和客户机相互影响的大小(有几种内置的命令,这些都是只读的)。
状态
一些需要考虑的点
“谈判者”项目做到了我预期的功能:基于Linux的KVM/QEMU主机和虚拟机之间的实时双向通信。
该项目没有自动化的测试套件,尽管在开发过程中对其功能进行了广泛测试,并且已在超过100个虚拟机上投入生产环境使用(用于非关键任务)。
该项目尚未进行安全性的同行评审。我的主要用例是相互之间有一定信任的KVM/QEMU主机和虚拟机(考虑私有云,而不是共享托管 :-)。
安装
《negotiator》软件包及其依赖项与Python 2.7及更高版本兼容,并且全部为纯Python。这意味着您不需要编译工具链即可安装《negotiator》软件包。这是一个设计决策,所以不会改变。
在KVM/QEMU主机上
以下是如何在主机上安装negotiator-host软件包的方法
$ sudo pip install negotiator-host
如果您愿意,可以在虚拟环境中安装Python软件包
$ sudo apt-get install --yes python-virtualenv
$ virtualenv /tmp/negotiator-host
$ source /tmp/negotiator-host/bin/activate
$ pip install negotiator-host
安装完成后,《negotiator-host》程序即可使用。使用信息将帮助您开始,尝试使用--help选项。现在您需要找到一种方法以守护进程的形式运行negotiator-host命令。我使用supervisord有很好的经验,以下是设置方法
$ sudo apt-get install --yes supervisor
$ sudo tee /etc/supervisor/conf.d/negotiator-host.conf >/dev/null << EOF
[program:negotiator-host]
command = /usr/local/bin/negotiator-host --daemon
autostart = True
stdout_logfile = /var/log/negotiator-host.log
stderr_logfile = /var/log/negotiator-host.log
EOF
$ sudo supervisorctl update negotiator-host
在KVM/QEMU客户机上
在您的虚拟机上安装negotiator-guest软件包
$ sudo pip install negotiator-guest
如果您愿意,可以在虚拟环境中安装Python软件包
$ sudo apt-get install --yes python-virtualenv
$ virtualenv /tmp/negotiator-guest
$ source /tmp/negotiator-guest/bin/activate
$ pip install negotiator-guest
安装完成后,您需要找到一种方法以守护进程的形式运行negotiator-guest命令。我使用supervisord有很好的经验,以下是设置方法
$ sudo apt-get install --yes supervisor
$ sudo tee /etc/supervisor/conf.d/negotiator-guest.conf >/dev/null << EOF
[program:negotiator-guest]
command = /usr/local/bin/negotiator-guest --daemon
autostart = True
stdout_logfile = /var/log/negotiator-guest.log
stderr_logfile = /var/log/negotiator-guest.log
EOF
$ sudo supervisorctl update negotiator-guest
入门
如果以下说明不足以帮助您开始,请查看下面的“调试”部分以获取关于事物未按预期工作的提示。
首先,您必须向您的QEMU虚拟机添加两个虚拟设备。您可以通过编辑虚拟机的XML定义文件来实现。在Ubuntu Linux KVM/QEMU主机上,这些文件位于目录/etc/libvirt/qemu中。使用您喜欢的文本编辑器(Vim? :-))打开文件,并在<devices>部分内添加以下XML片段
<channel type=
'unix'> <source mode='bind'path='/var/lib/libvirt/qemu/channel/target/GUEST_NAME.negotiator-host-to-guest.0'/> <target type='virtio'name='negotiator-host-to-guest.0'/> </channel> <channel type='unix'> <source mode='bind'path='/var/lib/libvirt/qemu/channel/target/GUEST_NAME.negotiator-guest-to-host.0'/> <target type='virtio'name='negotiator-guest-to-host.0'/> </channel>将GUEST_NAME替换为您虚拟机的名称。如果您使用libvirt 1.0.6或更高版本(您可以使用virsh --version进行检查),可以省略path='...'属性,因为libvirt将在重新加载虚拟机的XML定义文件时自动填充它(在第2步中)。
添加配置片段后,您需要激活它
$ sudo virsh define /etc/libvirt/qemu/GUEST_NAME.xml
现在您需要关闭虚拟机,然后重新启动它
$ sudo virsh shutdown --mode acpi GUEST_NAME $ sudo virsh start GUEST_NAME
请注意,仅重启虚拟机不会添加新的虚拟设备,您必须实际停止虚拟机然后重新启动它!
现在,请在/usr/lib/negotiator/commands中创建一些脚本,并尝试从另一侧执行它们!一旦您开始编写自己的命令,了解KVM/QEMU主机侧的命令可以访问一些环境变量会有所帮助。
用法
本节记录了在主机和虚拟机上运行程序的命令行界面。有关Python API的信息,请参阅Read the Docs上的在线文档。
negotiator-host程序
用法: negotiator-host [OPTIONS] GUEST_NAME
通过在虚拟机内部运行的代理守护进程,与正在运行的虚拟机系统进行通信。
支持选项
选项 |
描述 |
---|---|
-g,--list-guests |
列出具有适当通道的访客名称。 |
-c,--list-commands |
列出访客对其宿主公开的命令。 |
-e,--execute=COMMAND |
在GUEST_NAME内部执行指定的命令。访客内部命令的标准输出流被截获并复制到宿主的标准输出流。如果命令以非零状态码退出,协商宿主程序也将以非零状态码退出。 |
-t,--timeout=SECONDS |
设置远程调用在没有响应之前超时的秒数。零值将禁用超时(在这种情况下,命令可以无限期地挂起)。默认值为10秒。 |
-d,--daemon |
启动宿主守护进程,该守护进程响应用户的实时请求。 |
-v,--verbose |
增加日志详细程度(可重复)。 |
-q,--quiet |
减少日志详细程度(可重复)。 |
-h,--help |
显示此信息并退出。 |
negotiator-guest程序
用法: negotiator-guest [OPTIONS]
从KVM/QEMU访客系统与其宿主通信,或启动访客守护进程,允许宿主在其访客上执行命令。
支持选项
选项 |
描述 |
---|---|
-l,--list-commands |
列出宿主对其访客公开的命令。 |
-e,--execute=COMMAND |
在KVM/QEMU宿主上执行指定的命令。宿主上命令的标准输出流被截获并复制到访客的标准输出流。如果命令以非零状态码退出,协商访客程序也将以非零状态码退出。 |
-d,--daemon |
启动访客守护进程。当使用此命令行选项时,“negotiator-guest”程序不会返回(除非出现意外的错误条件)。 |
-t,--timeout=SECONDS |
设置远程调用在没有响应之前超时的秒数。零值将禁用超时(在这种情况下,命令可以无限期地挂起)。默认值为10秒。 |
-c,--character-device=PATH |
默认情况下,根据/sys/class/virtio-ports/*/name自动选择合适的字符设备。如果自动选择不起作用,您可以设置用于与运行在KVM/QEMU宿主上的negotiator-host守护进程通信的字符设备的绝对路径名。 |
-v,--verbose |
增加日志详细程度(可重复)。 |
-q,--quiet |
减少日志详细程度(可重复)。 |
-h,--help |
显示此信息并退出。 |
调试
本节包含有关在预期情况不正常时应该做什么的建议。
KVM/QEMU主机上的损坏通道
无论您是想运行官方QEMU访客代理还是运行协商者项目,您都需要一个正常工作的双向通道。我在Ubuntu 14.04 KVM/QEMU宿主上测试协商者,需要做几个更改才能正常工作。
$ CHANNELS_DIRECTORY=/var/lib/libvirt/qemu/channel/target
$ sudo mkdir -p $CHANNELS_DIRECTORY
$ sudo chown libvirt-qemu:kvm $CHANNELS_DIRECTORY
如果您问我,这些应该由KVM/QEMU系统软件包来完成,但无论如何。此外,如果您正在运行启用AppArmor(默认)的Ubuntu,您可能需要应用以下补丁。
$ diff -u /etc/apparmor.d/abstractions/libvirt-qemu.orig /etc/apparmor.d/abstractions/libvirt-qemu
--- /etc/apparmor.d/abstractions/libvirt-qemu.orig 2015-09-19 12:46:54.316593334 +0200
+++ /etc/apparmor.d/abstractions/libvirt-qemu 2015-09-24 14:43:43.642064576 +0200
@@ -49,6 +49,9 @@
/run/shm/ r,
owner /run/shm/spice.* rw,
+ # Local modification to enable the QEMU guest agent.
+ owner /var/lib/libvirt/qemu/channel/target/* rw,
+
# 'kill' is not required for sound and is a security risk. Do not enable
# unless you absolutely need it.
deny capability kill,
同样,这些应该只是KVM/QEMU系统软件包的一部分,但无论如何。协商者项目正在尝试一些较新的功能,所以我几乎可以肯定会出现锋利的边缘 :-)
字符设备检测失败
当 negotiator-guest 程序无法检测到正确的字符设备时,它会大声抱怨并指向这里。以下是我遇到的一些可能导致此问题的情况
虚拟通道(s)尚未正确配置,或者正确的配置尚未应用。请仔细遵循上面 入门 部分的说明。
内核模块 virtio_console 没有被加载,因为您的内核中不可用。您可以使用 lsmod 命令来检查。如果没有加载该模块,您需要安装并引导到一个包含该模块的内核。
为什么还需要另一个客户代理?
QEMU 项目提供了一个官方的虚拟机代理,这个代理对于增强 QEMU 主机和虚拟机之间的集成非常有用。然而,官方的 QEMU 虚拟机代理有两个显著的不足(至少对我来说是这样的)
- 可扩展性
官方的 QEMU 虚拟机代理有一些通用机制,例如能够在虚拟机内部写入文件,但这与一个通用、可扩展的架构相去甚远。理想情况下,在主机和虚拟机权限允许的情况下,我们应该能够在双方传输任意数据并执行用户定义的代码。
- 平台支持
尽管我付出了很多努力,但我无法在较旧的 Linux 发行版(例如 Ubuntu Linux 10.04)上运行 QEMU 虚拟机代理的最新版本。虽然较旧的虚拟机代理可以成功编译为这些发行版,但它们不支持我需要的功能。通过创建自己的虚拟机代理,我可以在平台支持方面有更多的控制(考虑到通信所需的原始机制)。
请注意,我的项目绝不是试图取代官方的 QEMU 虚拟机代理。例如,我没有任何意图实现文件系统的冻结和解冻,因为官方代理已经做得很好了 :-)。换句话说,这两个项目有很多相似之处,但目标却截然不同。
它是如何工作的?
可脚本化虚拟机代理基础设施使用与官方 QEMU 虚拟机代理相同的机制
在虚拟机内部创建特殊字符设备,允许读写操作。这些字符设备是 /dev/vport[0-9]p[0-9]。
在主机上创建 UNIX 域套接字,连接到虚拟机内部的字符设备。在 Ubuntu Linux KVM/QEMU 主机上,这些 UNIX 域套接字位于目录 /var/lib/libvirt/qemu/channel/target 中。
联系方式
最新版本的 negotiator 可在 PyPI 和 GitHub 上找到。您可以在 Read The Docs 上找到文档。有关错误报告,请在 GitHub 上创建问题。如果您有问题、建议等,请随时发送电子邮件至 peter@peterodding.com。
许可证
本软件受 MIT 许可证 许可。
© 2019 Peter Odding。
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。
源代码分发
构建发行版
negotiator-host-0.12.2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 5b5dbfa994077e58a6a66fc20ff321748aef96b9cc61b0c375de3501b04499d8 |
|
MD5 | 2d0ef3c0eb9b30022685aca943db052e |
|
BLAKE2b-256 | 65e5bddc148f12aa8e81cfb0fbe504541436d0d38c6cb1546fa4fb5fbefcb5ce |
negotiator_host-0.12.2-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2c65ff145767bb0029cace1f9dc63e1d0fb651743f0306aa0c41752b7ceb8da1 |
|
MD5 | 87c8762dec8b14a57d5d129058532d4a |
|
BLAKE2b-256 | 1278fccbe2a54a8c837c75a7b8b570e828870ceb4940e5d3bb9d92292f3c94d2 |