1. Libvirt 是什么
为什么需要Libvirt?
Hypervisor 比如 qemu-kvm 的命令行虚拟机管理工具参数众多,难于使用。
Hypervisor 种类众多,没有统一的编程接口来管理它们,这对云环境来说非常重要。
没有统一的方式来方便地定义虚拟机相关的各种可管理对象。
Libvirt提供了什么?
它提供统一、稳定、开放的源代码的应用程序接口(API)、守护进程 (libvirtd)和和一个默认命令行管理工具(virsh)。
它提供了对虚拟化客户机和它的虚拟化设备、网络和存储的管理。
它提供了一套较为稳定的C语言应用程序接口。目前,在其他一些流行的编程语言中也提供了对libvirt的绑定,在Python、Perl、Java、Ruby、PHP、OCaml等高级编程语言中已经有libvirt的程序库可以直接使用。
它对多种不同的 Hypervisor 的支持是通过一种基于驱动程序的架构来实现的。libvirt 对不同的 Hypervisor 提供了不同的驱动,包括 Xen 的驱动,对QEMU/KVM 有 QEMU 驱动,VMware 驱动等。在 libvirt 源代码中,可以很容易找到 qemu_driver.c、xen_driver.c、xenapi_driver.c、vmware_driver.c、vbox_driver.c 这样的驱动程序源代码文件。
它作为中间适配层,让底层 Hypervisor 对上层用户空间的管理工具是可以做到完全透明的,因为 libvirt 屏蔽了底层各种 Hypervisor 的细节,为上层管理工具提供了一个统一的、较稳定的接口(API)。
它使用 XML 来定义各种虚拟机相关的受管理对象。
目前,libvirt 已经成为使用最为广泛的对各种虚拟机进行管理的工具和应用程序接口(API),而且一些常用的虚拟机管理工具(如virsh、virt-install、virt-manager等)和云计算框架平台(如OpenStack、OpenNebula、Eucalyptus等)都在底层使用libvirt的应用程序接口。
1.1 Libvirt C API
1.1.1 Libvirti API 所管理的主要对象
1.1.2 对象的管理模型
1.1.3 API 的简单分类
Libvirt API 就是对各种对象的各种操作,包括基本的增、删、改、查操作和其它操作。
1.2 Libvirt XML 定义
Libvirt 使用 XML 来定义各种对象,其中,与 OpenStack Nova 关系比较密切的有:
disk (磁盘)
任何磁盘设备,包括软盘(floppy)、硬盘(hard disk)、光驱(cdrom)或者半虚拟化驱动都使用 <disk> 元素来定义。 方式:
<disk type='' device=''>。其中:
”type“ 用来指定device source 的类型:"file", "block", "dir", "network", 或者 "volume"。具体的 source 由 <source> 标签定义。
”device“ 用来指定 device target 的类型:"floppy", "disk", "cdrom", and "lun", 默认为 "disk" 。具体的 target 由 <target> 标签定义。
(1)”volume“ 类型的 disk
(2)”file“ 类型的 disk
(3)”block“ 类型的 disk
(4)”network“ 类型的 disk
Host device assignment (主机设备分配)
有几种 interface 类型:
(1)type = ‘network’ 定义一个连接 Virtual network 的 interface
(2)type=‘birdge’ 定义一个 Bridge to LAN(桥接到物理网络)的interface:前提是主机上存在一个 bridge,该 bridge 已经连到物理LAN。
(3)type=‘ethernet’ 定义一个使用指定脚本连接到 LAN 的 interface
(4)type=‘direct’ 定义一个直接连到物理网卡(Direct attachment to physical interface)的 interface:需要 Linux macvtap 驱动支持
(5)type=‘hostdev’ 定义一个由主机PCI 网卡直接分配(PCI Passthrough)的 interface: 分配主机上的网卡给虚机
network (网络)
1. bridge:定义一个用于构造该虚拟网络的网桥。
2. domain:定义 DHCP server 的 DNS domain。
3. forward: 定义虚拟网络直接连到物理 LAN 的方式. ”mode“指转发模式。
(1) mode=‘nat’:所有连接到该虚拟网络的虚拟的网络都会经过物理机器的网卡,并转换成物理网卡的地址。
(2) mode=‘route’:类似于 NAT,但是不使用NAT,而是使用routing table。 </pre>
(3) mode=‘bridge’:使用不受libvirt管理的bridge,比如主机上已有的bridge;open vswitch bridge;使用 macvtap's "bridge" 模式
(4) mode=‘passthrough’:使用 a macvtap "direct" connection in "passthrough" mode 指定主机上的特定网卡用于虚拟网络
(5) mode=‘hostdev’:直接分配主机上的网络设备。
详细的 XML 定义说明在 https://libvirt.org/format.html。
1.3 Libvirt API 的实现
libvirt API 的实现是在各个 Hypervisor driver 和 Storage dirver 内。Hypervisor 驱动包括:
LXC - Linux Containers
OpenVZ
QEMU
Test - Used for testing
UML - User Mode Linux
VirtualBox
VMware ESX
VMware Workstation/Player
Xen
Microsoft Hyper-V
IBM PowerVM (phyp)
Parallels
Bhyve - The BSD Hypervisor
1.4 Libvirt 的 Python 绑定
python-libvirt 包含 Libvirt 的 Python 语言绑定。安装 libvirt 时,默认会安装 python-libvirt 。 来源: https://libvirt.org/python.html https://pypi.python.org/pypi/libvirt-python
Python API 和 C API 之间几乎是一对一的映射关系,比如:
因此,libvirt 官网并没有提供详细的 python API 描述。
2. QEMU/KVM libvirt 驱动
2.1 架构
•Libvirtd 是一个 daemon 进程,可以被本地的virsh调用,也可以被远程的virsh调用
•Libvirtd 调用 qemu-kvm 操作KVM 虚拟机
这里有一个 virsh 命令、Libvirt C API、 QEMU driver 方法 和 QEMU Monitor 命令的对照表(部分):
2.2 安装
有三种方式来安装 libvirt:
(1)下载 libvirt 的源代码,然后编译和安装
(2)从各 Linux 的发行版中直接安装,比如 Ubuntu 上运行 apt-get install libvirt-bin
(3)从 git 上克隆 libvirt 的代码,然后编译和安装
2.3 libvirt log
这篇文章(https://libvirt.org/logging.html) 描述了 livbirt log。设置所有日志的方法是在 /etc/libvirt/libvirtd.conf 中添加下面的配置然后重启 libvirt:
3 使用 libvirt 编程来管理 KVM 虚机的实例
这里只描述基本的过程。具体的过程,下一篇文章会具体分析 Nova 中 libvirt 的使用。
定义虚机的基本配置,包括 vCPU、内存、磁盘或者cdrom以及启动顺序,生成 xml 配置,调用 virDomainCreateXML API 启动一个虚机
使用 Domain 相关的 API 来管理虚机的生命周期。我的这篇文章(http://www.cnblogs.com/sammyliu/p/4486712.html)有虚机生命周期的详细介绍。
添加磁盘:定义一个 disk 的 xml 配置,使用 virDomainAttachDevice API 将它挂载到虚机上。如果不是本地的源磁盘,需要提前准备好。
添加interface:使用 Network API 定义一个虚拟网络(需要提前准备好物理网络),然后定义一个 interface 的 XML 配置,使用 virDomainAttachDevice API 将它加到虚机。
按照需要,重复2、3、4步骤。
作者:刘世民(Sammyliu)
博客:http://www.cnblogs.com/sammyliu/