searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

libvirt原理和API

2023-03-30 01:51:48
136
0

libvirt原理和API

libvirt架构

架构介绍

  1. libvirt分为client和deamon两个部分
  2. libvirt deamon中还包含了rpc,acl,事件机制,线程池等公共组件。基于rpc可以实现libvirt remote client对本地虚拟机的操作。acl实现了访问控制标签。事件机制是libvirt所有动作的基础,所有的请求,消息转发,事件触发都是通过事件机制传递的。
  3. libvirt deamon中通过事件机制监听某个端口的消息。client发出的请求会通过socket连接发送到libvirt api。
  4. libvirt deamon在启动时会加载部署的hypervisor驱动,libvirt api接收到的请求会路由到conn对象指定的驱动程序中。
  5. 驱动程序接收到转发的请求之后会与hypervisor交互实现对虚拟机的具体操作。
  6. libvirt中目前实现了多种hypervisor的驱动,其中qemu_driver对应kvm,lxc对应容器。
  7. 对于kvm而言,一个虚拟机对应一个qemu进程。qemu进程通过软件模拟计算机的主板,CPU,南北桥及内存设备。虚拟机操作系统就运行在qemu进程内。
  8. libvirt独立实现了lxc driver来管理容器。lxc driver启动一个独立的进程并使用这个进程拉起一个init子进程,这个子进程有其独立的namespace并与cgroup结合实现了容器资源的隔离和限制。

接口调用

在libvirt中接口的调用方式分为两种:

远程调用

本地调用

从nova到libvirt openstack是基于Python实现的,而libvirt是基于C实现的。那么C和Python之间是如何转换的呢。下面以启动虚拟机实例来看一下在openstack中如何调用libvirt接口:

  • import python-libvirt库

 if libvirt is None:
     libvirt = __import__('libvirt')

  • 通过openAuth获取与libvirtd进程的连接conn

 return tpool.proxy_call(
     (libvirt.virDomain, libvirt.virConnect),
     libvirt.openAuth, uri, auth, flags)

  • 调用define接口创建一个虚拟机实例,获取domain对象

 domain = self._conn.defineXML(xml)

  • 通过domain对象启动虚拟机实例

 domain.createWithFlags(launch_flags)

由这个流程我们可以看到,openstack中主要通过python-libvirt库与libvirtd进程交互,完成对虚拟机实例的操作。python-libvirt是由libvirt提供的一个面向python client的连接组件,包含以下内容:

 /usr/share/pyshared/libvirt.py #libvirt python接口文件,包含大部分的libvirt接口
 /usr/share/pyshared/libvirt_lxc.py #lxc接口文件,因为这部分接口参数不能自动转换,所以通过手动重写完成转换
 /usr/share/pyshared/libvirt_qemu.py #与上面的类似,qemu相关的。
 /usr/lib/python2.7/dist-packages/libvirtmod_qemu.so
 /usr/lib/python2.7/dist-packages/libvirtmod_lxc.so
 /usr/lib/python2.7/dist-packages/libvirtmod.so

在libvirt代码中有一个专门的目录用于存放接口python化相关的代码。所有的libvirt接口被分为了两个部分:

  1. 可以直接自动转换的接口,使用py直接封装python接口
  2. 无法直接自动转换的接口,通过libvirt-override.c等文件对C接口做一层封装再封装python接口。 libvirt-python工程会将未重写和重写过的接口编译到一个动态库中,并且和生成的py文件一起打包到python-libvirt包中。然后我们就可以通过引入这个python库的方式调用libvirt的C接口了。

 

 

Libvirt XML

XML配置

XML地址:https://libvirt.org/formatdomain.html

域、网络、网络过滤、存储、存储加密、能力、域能力、存储池能力、节点设备、秘密、快照、检查点、备份任务的XML模式描述

 

Libvirt API

Libvirt 概述

https://github.com/libvirt/libvirt

Libvirt提供了一种便携式,长期稳定的C语言API,用于管理许多操作系统提供的虚拟化技术。它包括对QEMU,KVM,XEN,LXC,BHYVE,Virtuozzo,VMware Vcenter和ESX,VMware Desktop,Hyper-V,VirtualBox和Power Hypervisor的支持。

对于其中一些虚拟机管理程序,它提供了一个状态管理守护程序,该守护程序在虚拟化主机上运行,允许非私有的本地用户和远程用户访问API。

分层软件包将libvirt c api的绑定到其他语言中,包括python,perl,php,go,java,ocaml,以及映射到诸如Gobject,CIM和SNMP之类的对象系统中。

API架构介绍

https://libvirt.org/api.html

 

 

 

 

API for Python

地址:https://libvirt.org/python.html

源码:https://github.com/libvirt/libvirt-python

安装:https://pypi.org/project/libvirt-python/#description

部署:pip install libvirt-python

import libvirt
import sys
 ​
 try:
     conn = libvirt.openReadOnly(None)
 except libvirt.libvirtError:
     print('Failed to open connection to the hypervisor')
     sys.exit(1)
 ​
 try:
     dom0 = conn.lookupByName("Domain-0")
 except libvirt.libvirtError:
     print('Failed to find the main domain')
     sys.exit(1)
 ​
 print("Domain 0: id %d running %s" % (dom0.ID(), dom0.OSType()))
  print(dom0.info())

C 和Python对比

支持的API对比

主要功能

全部功能:https://libvirt.org/html/index.html

 

接口转换关系

https://libvirt.org/python.html

  1. C语言API里的一些全局函数,对应于Python版本里的特定类的成员函数,比如:int virDomainSetMemory(virDomainPtr domain, unsigned long memory); 这是一个C语言的全局函数,它对应于Python中的类virDomain的成员函数setMemory()
  2. C语言里面的一些宏,比如 XXX,到了Python中体现为 libvirt.XXX.
  3. C语言里面一些指向结构体的指针,尤其是该指针被用作函数的入参同时也是出参的时候,到了Python中就体现为该函数的返回值是一个dict. 比如,int virDomainMemoryStats(virDomainPtr dom, virDomainMemoryStatPtr stats, unsigned int nr_stats, unsigned int flags) 这个函数,到了Python中就体现为 virDomain::memoryStats(),该函数没有入参,返回值是一个dict,包含了'actual', 'available'等keys,分别表示实际总内存量、可得内存量等等。
  4. libvirt 是一个 C 动态库,其 Python API 由 libvirt-python项目下的py 生成。

一部分 Python API 通过 libvirt 的 C API 定义自动生成

 $ ls /usr/share/libvirt/api/
 libvirt-admin-api.xml  libvirt-api.xml  libvirt-lxc-api.xml  libvirt-qemu-api.xml

一部分 Python API 通过 override API 定义(即对 libvirt C API 有一定的封装)自动生成

 $ ls *.xml
 libvirt-lxc-override-api.xml  libvirt-override-api.xml  libvirt-qemu-override-api.xml

一部分 Python API 手工实现

 $ ls libvirt-override*.py
 libvirt-override.py                    libvirt-override-virNetwork.py
 libvirt-override-virConnect.py         libvirt-override-virStoragePool.py
 libvirt-override-virDomain.py          libvirt-override-virStream.py
 libvirt-override-virDomainSnapshot.py

Python API 对应的动态库 wrapper so 一部分由 C API 定义自动生成,一部分由 override API 定义自动生成,其对应的 c 代码实现为

 $ ls *-override.c
 libvirt-lxc-override.c  libvirt-override.c  libvirt-qemu-override.c

通过如下命令生成 Python API (build/lib.linux-x86_64-2.7/libvirt.py) 及 wrapper so 动态库 (build/lib.linux-x86_64-2.7/libvirtmod.so):

 $ ./setup.py build
 $ tree build/
 build/
 ├── lib.linux-x86_64-2.7
 │   ├── libvirt_lxc.py
 │   ├── libvirtmod_lxc.so
 │   ├── libvirtmod_qemu.so
 │   ├── libvirtmod.so
 │   ├── libvirt.py
 │   └── libvirt_qemu.py
 ├── libvirt.c
 ├── libvirt-export.c
 ├── libvirt.h
 ├── libvirt-lxc.c
 ├── libvirt-lxc-export.c
 ├── libvirt-lxc.h
 ├── libvirt_lxc.py
 ├── libvirt.py
 ├── libvirt-qemu.c
 ├── libvirt-qemu-export.c
 ├── libvirt-qemu.h
 ├── libvirt_qemu.py

其中:

  1. build/lib.linux-x86_64-2.7/libvirt.py 是从 build/libvirt.py 拷贝过去的;
  2. build/libvirt.py 由 libvirt-override.py 手写部分和
  3. so由 libvirt-override.c, build/libvirt.c, typewrappers.c, libvirt-utils.c 构建;
  4. so由 libvirt-qemu-override.c, build/libvirt-qemu.c, typewrappers.c, libvirt-utils.c 构建;
  5. so由 libvirt-lxc-override.c, build/libvirt-lxc.c, typewrappers.c, libvirt-utils.c 构建;

需要主要的是,Python 绑定中的方法名相比 libvirt C 接口的函数名去掉了前缀,如 libvirt-domain.c/virDomainDefineXML 接口在 Python 绑定中就变成了 virConnect.defineXML。

版本矩阵图

qemu版本和libvirt提供的API接口的版本支持关系

https://libvirt.org/hvsupport.html

 ​

0条评论
作者已关闭评论
杨****萌
5文章数
1粉丝数
杨****萌
5 文章 | 1 粉丝
原创

libvirt原理和API

2023-03-30 01:51:48
136
0

libvirt原理和API

libvirt架构

架构介绍

  1. libvirt分为client和deamon两个部分
  2. libvirt deamon中还包含了rpc,acl,事件机制,线程池等公共组件。基于rpc可以实现libvirt remote client对本地虚拟机的操作。acl实现了访问控制标签。事件机制是libvirt所有动作的基础,所有的请求,消息转发,事件触发都是通过事件机制传递的。
  3. libvirt deamon中通过事件机制监听某个端口的消息。client发出的请求会通过socket连接发送到libvirt api。
  4. libvirt deamon在启动时会加载部署的hypervisor驱动,libvirt api接收到的请求会路由到conn对象指定的驱动程序中。
  5. 驱动程序接收到转发的请求之后会与hypervisor交互实现对虚拟机的具体操作。
  6. libvirt中目前实现了多种hypervisor的驱动,其中qemu_driver对应kvm,lxc对应容器。
  7. 对于kvm而言,一个虚拟机对应一个qemu进程。qemu进程通过软件模拟计算机的主板,CPU,南北桥及内存设备。虚拟机操作系统就运行在qemu进程内。
  8. libvirt独立实现了lxc driver来管理容器。lxc driver启动一个独立的进程并使用这个进程拉起一个init子进程,这个子进程有其独立的namespace并与cgroup结合实现了容器资源的隔离和限制。

接口调用

在libvirt中接口的调用方式分为两种:

远程调用

本地调用

从nova到libvirt openstack是基于Python实现的,而libvirt是基于C实现的。那么C和Python之间是如何转换的呢。下面以启动虚拟机实例来看一下在openstack中如何调用libvirt接口:

  • import python-libvirt库

 if libvirt is None:
     libvirt = __import__('libvirt')

  • 通过openAuth获取与libvirtd进程的连接conn

 return tpool.proxy_call(
     (libvirt.virDomain, libvirt.virConnect),
     libvirt.openAuth, uri, auth, flags)

  • 调用define接口创建一个虚拟机实例,获取domain对象

 domain = self._conn.defineXML(xml)

  • 通过domain对象启动虚拟机实例

 domain.createWithFlags(launch_flags)

由这个流程我们可以看到,openstack中主要通过python-libvirt库与libvirtd进程交互,完成对虚拟机实例的操作。python-libvirt是由libvirt提供的一个面向python client的连接组件,包含以下内容:

 /usr/share/pyshared/libvirt.py #libvirt python接口文件,包含大部分的libvirt接口
 /usr/share/pyshared/libvirt_lxc.py #lxc接口文件,因为这部分接口参数不能自动转换,所以通过手动重写完成转换
 /usr/share/pyshared/libvirt_qemu.py #与上面的类似,qemu相关的。
 /usr/lib/python2.7/dist-packages/libvirtmod_qemu.so
 /usr/lib/python2.7/dist-packages/libvirtmod_lxc.so
 /usr/lib/python2.7/dist-packages/libvirtmod.so

在libvirt代码中有一个专门的目录用于存放接口python化相关的代码。所有的libvirt接口被分为了两个部分:

  1. 可以直接自动转换的接口,使用py直接封装python接口
  2. 无法直接自动转换的接口,通过libvirt-override.c等文件对C接口做一层封装再封装python接口。 libvirt-python工程会将未重写和重写过的接口编译到一个动态库中,并且和生成的py文件一起打包到python-libvirt包中。然后我们就可以通过引入这个python库的方式调用libvirt的C接口了。

 

 

Libvirt XML

XML配置

XML地址:https://libvirt.org/formatdomain.html

域、网络、网络过滤、存储、存储加密、能力、域能力、存储池能力、节点设备、秘密、快照、检查点、备份任务的XML模式描述

 

Libvirt API

Libvirt 概述

https://github.com/libvirt/libvirt

Libvirt提供了一种便携式,长期稳定的C语言API,用于管理许多操作系统提供的虚拟化技术。它包括对QEMU,KVM,XEN,LXC,BHYVE,Virtuozzo,VMware Vcenter和ESX,VMware Desktop,Hyper-V,VirtualBox和Power Hypervisor的支持。

对于其中一些虚拟机管理程序,它提供了一个状态管理守护程序,该守护程序在虚拟化主机上运行,允许非私有的本地用户和远程用户访问API。

分层软件包将libvirt c api的绑定到其他语言中,包括python,perl,php,go,java,ocaml,以及映射到诸如Gobject,CIM和SNMP之类的对象系统中。

API架构介绍

https://libvirt.org/api.html

 

 

 

 

API for Python

地址:https://libvirt.org/python.html

源码:https://github.com/libvirt/libvirt-python

安装:https://pypi.org/project/libvirt-python/#description

部署:pip install libvirt-python

import libvirt
import sys
 ​
 try:
     conn = libvirt.openReadOnly(None)
 except libvirt.libvirtError:
     print('Failed to open connection to the hypervisor')
     sys.exit(1)
 ​
 try:
     dom0 = conn.lookupByName("Domain-0")
 except libvirt.libvirtError:
     print('Failed to find the main domain')
     sys.exit(1)
 ​
 print("Domain 0: id %d running %s" % (dom0.ID(), dom0.OSType()))
  print(dom0.info())

C 和Python对比

支持的API对比

主要功能

全部功能:https://libvirt.org/html/index.html

 

接口转换关系

https://libvirt.org/python.html

  1. C语言API里的一些全局函数,对应于Python版本里的特定类的成员函数,比如:int virDomainSetMemory(virDomainPtr domain, unsigned long memory); 这是一个C语言的全局函数,它对应于Python中的类virDomain的成员函数setMemory()
  2. C语言里面的一些宏,比如 XXX,到了Python中体现为 libvirt.XXX.
  3. C语言里面一些指向结构体的指针,尤其是该指针被用作函数的入参同时也是出参的时候,到了Python中就体现为该函数的返回值是一个dict. 比如,int virDomainMemoryStats(virDomainPtr dom, virDomainMemoryStatPtr stats, unsigned int nr_stats, unsigned int flags) 这个函数,到了Python中就体现为 virDomain::memoryStats(),该函数没有入参,返回值是一个dict,包含了'actual', 'available'等keys,分别表示实际总内存量、可得内存量等等。
  4. libvirt 是一个 C 动态库,其 Python API 由 libvirt-python项目下的py 生成。

一部分 Python API 通过 libvirt 的 C API 定义自动生成

 $ ls /usr/share/libvirt/api/
 libvirt-admin-api.xml  libvirt-api.xml  libvirt-lxc-api.xml  libvirt-qemu-api.xml

一部分 Python API 通过 override API 定义(即对 libvirt C API 有一定的封装)自动生成

 $ ls *.xml
 libvirt-lxc-override-api.xml  libvirt-override-api.xml  libvirt-qemu-override-api.xml

一部分 Python API 手工实现

 $ ls libvirt-override*.py
 libvirt-override.py                    libvirt-override-virNetwork.py
 libvirt-override-virConnect.py         libvirt-override-virStoragePool.py
 libvirt-override-virDomain.py          libvirt-override-virStream.py
 libvirt-override-virDomainSnapshot.py

Python API 对应的动态库 wrapper so 一部分由 C API 定义自动生成,一部分由 override API 定义自动生成,其对应的 c 代码实现为

 $ ls *-override.c
 libvirt-lxc-override.c  libvirt-override.c  libvirt-qemu-override.c

通过如下命令生成 Python API (build/lib.linux-x86_64-2.7/libvirt.py) 及 wrapper so 动态库 (build/lib.linux-x86_64-2.7/libvirtmod.so):

 $ ./setup.py build
 $ tree build/
 build/
 ├── lib.linux-x86_64-2.7
 │   ├── libvirt_lxc.py
 │   ├── libvirtmod_lxc.so
 │   ├── libvirtmod_qemu.so
 │   ├── libvirtmod.so
 │   ├── libvirt.py
 │   └── libvirt_qemu.py
 ├── libvirt.c
 ├── libvirt-export.c
 ├── libvirt.h
 ├── libvirt-lxc.c
 ├── libvirt-lxc-export.c
 ├── libvirt-lxc.h
 ├── libvirt_lxc.py
 ├── libvirt.py
 ├── libvirt-qemu.c
 ├── libvirt-qemu-export.c
 ├── libvirt-qemu.h
 ├── libvirt_qemu.py

其中:

  1. build/lib.linux-x86_64-2.7/libvirt.py 是从 build/libvirt.py 拷贝过去的;
  2. build/libvirt.py 由 libvirt-override.py 手写部分和
  3. so由 libvirt-override.c, build/libvirt.c, typewrappers.c, libvirt-utils.c 构建;
  4. so由 libvirt-qemu-override.c, build/libvirt-qemu.c, typewrappers.c, libvirt-utils.c 构建;
  5. so由 libvirt-lxc-override.c, build/libvirt-lxc.c, typewrappers.c, libvirt-utils.c 构建;

需要主要的是,Python 绑定中的方法名相比 libvirt C 接口的函数名去掉了前缀,如 libvirt-domain.c/virDomainDefineXML 接口在 Python 绑定中就变成了 virConnect.defineXML。

版本矩阵图

qemu版本和libvirt提供的API接口的版本支持关系

https://libvirt.org/hvsupport.html

 ​

文章来自个人专栏
libvirt
1 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0