当前位置: 首页 > 工具软件 > Libvirt > 使用案例 >

libvirt 详解(2)

萧心水
2023-12-01

1.1.3 libvirt、libvirtd的配置和使用

1. libvirt的配置文件

以RHEL 6.3为例,libvirt相关的配置的配置文件都在 /etc/libvirt/ 目录之中,如下所示:

[root@rhel6u3-ga libvirt]# cd /etc/libvirt/

[root@rhel6u3-ga libvirt]# ls

cim  libvirt.conf  libvirtd.conf  lxc.conf  nwfilter  qemu  qemu.conf  qemu-sanlock.conf  storage

[root@rhel6u3-ga libvirt]# cd qemu

[root@rhel6u3-ga qemu]# ls

networks  rhel6u3-1.xml  rhel6u3-2.xml

下面简单介绍其中几个重要的配置文件和目录:

(1)/etc/libvirt/libvirt.conf

libvirt.conf 文件是用于配置一些常用 libvirt 连接(通常是远程连接)的别名,和Linux中的普通配置文件一样,该配置文件中以井号(#)开头的行是注释,本次示例中的该配置文件如下:

[root@rhel6u3-ga kvm_demo]# cat /etc/libvirt/libvirt.conf

#

# This can be used to setup URI aliases for frequently

# used connection URIs. Aliases may contain only the

# characters  a-Z, 0-9, _, -.

#

# Following the ‘=’ may be any valid libvirt connection

# URI, including arbitrary parameters

 

uri_aliases = [

"remote1=qemu+ssh://root@192.168.93.201/system",

]

其中,配置了 remote1 这个别名用于指代 qemu+ssh://root@192.168.93.201/system 这个远程的libvirt连接,有这个别名后,就可以在 virsh 等工具或者自己写代码调用libvirt API 时使用这个别名而不需要写完整的、冗长的URI连接标识了。用 virsh 使用这个别名,连接到远程的 libvirt 上查询当前已经启动的客户机状态,然后退出连接,命令行操作如下:

[root@rhel6u3-ga kvm_demo]# service libvirtd reload

Reloading libvirtd configuration:                          [  OK  ]

[root@rhel6u3-ga kvm_demo]# virsh -c remote1

root@192.168.93.201′s password:

Welcome to virsh, the virtualization interactive terminal.

 

Type:  ‘help’ for help with commands

‘quit’ to quit

 

virsh # list

Id    Name                           State

—————————————————-

1     rhel6u3-remote                 running

 

virsh # quit

 

[root@rhel6u3-ga kvm_demo]#

在代码中调用 libvirt API 也可以使用这个别名用于建立连接,如下的 python 代码行就是使用这个别名来建立连接:

conn = libvirt.openReadOnly(‘remote1′)

(2)/etc/libvirt/libvirtd.conf

libvirtd.conf 是 libvirt 的守护进程 libvirtd 的配置文件,修改后需要让libvirtd重新加载配置文件(或重启libvirtd)才会生效。 libvirtd.conf 文件中,用井号(#)开头的行是注释内容,真正有用的配置在文件的每一行中使用“配置项 = 值”(如tcp_port = “16509″)这样配对的格式来设置。 libvirtd.conf 配置值了 libvirtd 启动时的许多设置,包括是否建立 TCP、UNIX domain socket 等连接方式及其最大连接数,以及这些连接的认证机制,等等。

例如,下面的几个配置项,表示关闭TLS安全认证的连接(默认值是打开的)、打开 TCP 连接(默认是关闭TCP连接的),设置TCP监听的端口,TCP连接不使用认证授权方式,设置UNIX domain socket 的保存目录等。

listen_tls = 0

listen_tcp = 1

tcp_port = “16666″

unix_sock_dir = “/var/run/libvirt”

auth_tcp = “none”

注意:要让TCP、TLS等连接的生效,需要在启动 libvirtd 时加上 –listen 参数(简写为 -l )。而默认的 service libvirtd start 命令启动 libvirtd 服务时,并没带 –listen 参数,所以如果要使用TCP等连接方式,可以使用 libvirtd –listen -d 命令来启动libvirtd。

上面配置选项让 UNIX socket 放到 /var/run/libvirt 目录下,启动 libvirtd 并检验配置是否生效,命令行操作如下:

[root@rhel6u3-ga ~]# libvirtd –listen -d

2012-12-01 07:54:02.715+0000: 6788: info : libvirt version: 0.9.10, package: 21.el6 (Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, 2012-05-23-09:15:11, x86-003.build.bos.redhat.com)

[root@rhel6u3-ga ~]# virsh -c qemu+tcp://localhost:16666/system

Welcome to virsh, the virtualization interactive terminal.

 

Type:  ‘help’ for help with commands

‘quit’ to quit

 

virsh # quit

 

[root@rhel6u3-ga ~]# ls /var/run/libvirt/libvirt-sock*

/var/run/libvirt/libvirt-sock  /var/run/libvirt/libvirt-sock-ro

(3)/etc/libvirt/qemu.conf

qemu.conf 是 libvirt 对QEMU的驱动的配置文件,包括 VNC、SPICE等和连接它们时采用的权限认证方式的配置,也包括内存大页、SELinux、Cgroups等相关配置。

(4)/etc/libvirt/qemu/ 目录

qemu 目录下是存放使用QEMU驱动的域的配置文件,查看qemu目录如下:

[root@rhel6u3-ga ~]# ls /etc/libvirt/qemu/

networks  rhel6u3-1.xml  rhel6u3-2.xml

其中包括了两个域的XML配置文件(rhel6u3-1.xml 和 rhel6u3-2.xml),这就是笔者用virt-manager 工具创建的两个域,默认会将其配置文件保存到 /etc/libvirt/qemu/ 目录下。而其中的 networks 目录是保存了创建一个域时默认使用的网络配置。

2. libvirtd的使用

libvirtd 是一个作为 libvirt 虚拟化管理系统中的服务器端的守护程序,如果要让某个节点能够用 libvirt 进行管理(无论是本地还是远程管理),都需要在这个节点上运行着 libvirtd 这个守护进程,以便让其他上层管理工具可以连接到该节点,libvirtd 负责执行其他管理工具发送它的虚拟化管理操作指令。而 libvirt 的客户端工具(包括virsh、virt-manager等)可以连接到本地或远程的 libvirtd 进程,以便管理节点上的客户机(启动、关闭、重启、迁移等)、收集节点上的宿主机和客户机的配置和资源使用状态。

在RHEL 6.3 中 libvirtd 是作为一个服务(service)配置在系统中的,所以可以通过 service 命令来对其进行操作(实际是通过 /etc/init.d/libvirtd 服务脚本来实现的)。常用的操作方式有:“service libvirtd start”命令表示启动libvirtd,“service libvirtd restart”表示重启 libvirtd,“service libvirtd reload”表示不重启服务但是重新加载配置文件(即 /etc/libvirt/libvirtd.conf 配置文件)。对 libvirtd 服务进行操作示例的命令行如下:

[root@rhel6u3-ga ~]# service libvirtd

Usage: /etc/init.d/libvirtd {start|stop|status|restart|condrestart|reload|force-reload|try-restart}

 

[root@rhel6u3-ga ~]# service libvirtd start

Starting libvirtd daemon: 2012-12-01 08:14:33.048+0000: 31202: info : libvirt version: 0.9.10, package: 21.el6 (Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, 2012-05-23-09:15:11, x86-003.build.bos.redhat.com)

[  OK  ]

 

[root@rhel6u3-ga ~]# service libvirtd status

libvirtd (pid  31327) is running…

 

[root@rhel6u3-ga ~]# service libvirtd restart

Stopping libvirtd daemon:                                  [  OK  ]

Starting libvirtd daemon: 2012-12-01 08:14:43.522+0000: 31325: info : libvirt version: 0.9.10, package: 21.el6 (Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, 2012-05-23-09:15:11, x86-003.build.bos.redhat.com)

[  OK  ]

默认情况下,libvirtd监听在一个本地的Unix domain socket上,而没有监听基于网络的TCP/IP socket,需要使用“-l 或 –listen”的命令行参数来开启对 libvirtd.conf 配置文件中对TCP/IP socket的配置。另外,libvirtd 守护进程的启动或停止,并不会直接影响到正在运行中的客户机。 libvirtd 在启动或重启完成时,只要客户机的XML配置文件是存在的,libvirtd 会自动加载这些客户的配置,获取它们的信息;当然,如果客户机没有基于 libvirt 格式的XML文件来运行,libvirtd 则不能发现它。

libvirtd 是一个可执行程序,不仅可以使用“service”命令调用它作为服务来运行,而且可以单独地运行 libvirtd 命令来使用它。libvirtd 命令行主要有如下几个参数:

-d,或 –daemon

表示让 libvirtd 作为守护进程(daemon)在后台运行。

-f,或 –config  FILE

指定libvirtd的配置文件为FILE,而不是使用默认值(通常是 /etc/libvirt/libvirtd.conf )。

-l,或 –listen

开启配置文件中配置的 TCP/IP 连接。

-p,或 –pid-file FILE

将 libvirtd 进程的PID写入到FILE文件中,而不是使用默认值(通常是 /var/run/libvirtd.pid )。

-t,或 –timeout SECONDS

设置对 libvirtd 连接的超时时间为SECONDS秒。

-v,或 –verbose

让命令输出详细的输出信息。特别是运行出错时,详细的输出信息便于用户查找原因。

–version

显示 libvirtd 程序的版本信息。

对libvirtd 命令的使用,几个简单的命令行操作示例如下:

#使用libvirtd 命令前,先停止已有的服务

[root@rhel6u3-ga ~]# service libvirtd stop

Stopping libvirtd daemon:                                  [  OK  ]

[root@rhel6u3-ga ~]# libvirtd –version

libvirtd (libvirt) 0.9.10

[root@rhel6u3-ga ~]# libvirtd

2012-12-01 08:57:38.475+0000: 2196: info : libvirt version: 0.9.10, package: 21.el6 (Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, 2012-05-23-09:15:11, x86-003.build.bos.redhat.com)

^C    #没有以daemon的形式启动,标准输出被libvirtd 占用;这里用 Ctrl-C 结束掉libvirtd 进程,以便继续进行后续操作。

 

[root@rhel6u3-ga ~]# libvirtd -l -d  -p /root/libvirtd.pid

2012-12-01 08:56:14.665+0000: 7683: info : libvirt version: 0.9.10, package: 21.el6 (Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>, 2012-05-23-09:15:11, x86-003.build.bos.redhat.com)

[root@rhel6u3-ga ~]# cat /root/libvirtd.pid

7685

1.1.5 libvirt API 简介

libvirt 的核心价值和主要目标就是提供了一套管理虚拟机的、稳定的、高效的应用程序接口(API)。libvirt API 本身是用C语言实现的,本节以其提供了最核心的 C语言接口的 API 为例做简单的介绍。

libvirt API 大致可划分为如下8个大的部分:

(1)连接 Hypervisor 相关的API:以virConnect 开头的一系列函数。

只有与 Hypervisor 建立了连接之后,才能进行虚拟机管理操作,所以连接 Hypervisor 的API是其他所有API使用的前提条件。与 Hypervisor 建立的连接是为其他API的执行提供了路径,是其他虚拟化管理功能的基础。通过调用 virConnectOpen 函数可以建立一个连接,其返回值是一个virConnectPtr 对象,该对象就代表到 Hypervisor 的一个连接;如果连接出错,则返回空值(NULL)。而 virConnectOpenReadOnly 函数会建立一个只读的连接,在该连接上可以使用一些查询的功能,而不使用创建、修改等功能。 virConnectOpenAuth 函数提供了更具认证建立的连接。 virConnectGetCapabilities 函数是返回对 Hypervisor 和驱动的功能的描述的 XML 格式的字符串。virConnectListDomains函数返回一列域标识符,它们代表该 Hypervisor 上的活动域。

(2)域管理的 API:以virDomain 开头的一系列函数。

虚拟机的管理,最基本的职能就是对各个节点上的域的管理,故 libvirt API 中实现了很多针对域管理的函数。要管理域,首先就要获取virDomainPtr 这个域对象,然后才能对域进行操作。有很多种方式来获取域对象,如 virDomainPtr virDomainLookupByID (virConnectPtr conn, int id) 函数是根据域的 id 值到 conn 这个连接上去查找相应的域。类似地,virDomainLookupByName、virDomainLookupByUUID 等函数分别是根据域的名称和 UUID 去查找相应的域。在得到了某个域的对象后,就可以进行很多的操作,可以是查询域的信息(如:virDomainGetHostname、virDomainGetInfo、virDomainGetVcpus、virDomainGetVcpusFlags、virDomainGetCPUStats,等等),也可以是控制域的生命周期(如:virDomainCreate 、virDomainSuspend 、virDomainResume 、virDomainDestroy 、virDomainMigrate,等等)。

(3)节点管理的 API:以virNode 开头的一系列函数。

域是运行在物理节点之上,libvirt也提供了对节点的信息查询和控制的功能。节点管理的多数函数都需要使用一个连接 Hypervisor 的对象作为其中的一个传入参数,以便可以查询或修改到该连接上的节点的信息。virNodeGetInfo函数是获取节点的物理硬件信息,virNodeGetCPUStats 函数可以获取节点上各个 CPU 的使用统计信息,virNodeGetMemoryStats 函数可以获取节点上的内存的使用统计信息,virNodeGetFreeMemory 函数可以获取节点上可用的空闲内存大小。也有一些设置或者控制节点的函数,如virNodeSetMemoryParameters 函数可以设置节点上的内存调度的参数,virNodeSuspendForDuration 函数可以让节点(宿主机)暂停运行一段时间。

(4)网络管理的 API:以 virNetwork 开头的一系列函数和部分以 virInterface 开头的函数。

libvirt 对虚拟化环境中的网络管理也提供了丰富的API。libvirt 首先需要创建virNetworkPtr 对象,然后才能查询或控制虚拟网络。一些查询网络相关信息的函数,如:virNetworkGetName 函数可以获取网络的名称,virNetworkGetBridgeName 函数可以获取该网络中网桥的名称,virNetworkGetUUID 函数可以获取网络的 UUID 标识,virNetworkGetXMLDesc 函数可以获取网络的以 XML 格式的描述信息,virNetworkIsActive 函数可以查询网络是否正在使用中。一些控制或更改网络设置的函数,有:virNetworkCreateXML 函数可以根据提供的 XML 格式的字符串创建一个网络(返回 virNetworkPtr 对象),virNetworkDestroy 函数可以销毁一个网络(同时也会关闭使用该网络的域),virNetworkFree 函数可以回收一个网络(但不会关闭正在运行的域),virNetworkUpdate 函数可根据提供的 XML 格式的网络配置来更新一个已存在的网络。另外,virInterfaceCreate、virInterfaceFree、virInterfaceDestroy、virInterfaceGetName、virInterfaceIsActive 等函数可以用于创建、释放和销毁网络接口,以及查询网络接口的名称和激活状态。

(5)存储卷管理的 API:以 virStorageVol 开头的一系列函数。

libvirt 对存储卷(volume)的管理,主要是对域的镜像文件的管理,这些镜像文件可能是 raw、qcow2、vmdk、qed等各种格式。libvirt 对存储卷的管理,首先需要创建virStorageVolPtr 这个存储卷的对象,然后才能对其进行查询或控制操作。libvirt 提供了3个函数来分别通过不同的方式来获取存储卷对象,如:virStorageVolLookupByKey 函数可以根据全局唯一的键值来获得一个存储卷对象,virStorageVolLookupByName 函数可以根据名称在一个存储资源池(storage pool)中获取一个存储卷对象,virStorageVolLookupByPath 函数可以根据它在节点上路径来获取一个存储卷对象。有一些函数用于查询存储卷的信息,如:virStorageVolGetInfo 函数可以查询某个存储卷的使用情况,virStorageVolGetName 函数可以获取存储卷的名称,virStorageVolGetPath 函数可以获取存储卷的路径,virStorageVolGetConnect 函数可以查询存储卷的连接。一些函数用于创建和修改存储卷,如:virStorageVolCreateXML 函数可以根据提供的 XML 描述来创建一个存储卷,virStorageVolFree 函数可以释放存储卷的句柄(但是存储卷依然存在),virStorageVolDelete 函数可以删除一个存储卷,virStorageVolResize 函数可以调整存储卷的大小。

(6)存储池管理的 API:以virStoragePool 开头的一系列函数。

libvirt 对存储池(pool)的管理,包括对本地的基本文件系统、普通网络共享文件系统、iSCSI共享文件系统、LVM分区等的管理。libvirt 需要基于 virStoragePoolPtr 这个存储池对象才能进行查询和控制操作。一些函数可以通过查询获取一个存储池对象,如:virStoragePoolLookupByName 函数可以根据存储池的名称来获取一个存储池对象,virStoragePoolLookupByVolume 可以根据一个存储卷返回其对应的存储池对象。virStoragePoolCreateXML 函数可以根据 XML 描述来创建一个存储池(默认已激活),virStoragePoolDefineXML 函数可以根据 XML 描述信息静态地定义个存储池(尚未激活),virStoragePoolCreate 函数可以激活一个存储池。virStoragePoolGetInfo、virStoragePoolGetName、virStoragePoolGetUUID等函数可以分别获取存储池的信息、名称和 UUID 标识。virStoragePoolIsActive函数可以查询存储池是否处于使用中状态。virStoragePoolFree 函数可以释放存储池相关的内存(但是不改变其在宿主机中的状态),virStoragePoolDestroy 函数可以用于销毁一个存储池(但并没有释放virStoragePoolPtr 对象,之后还可以用virStoragePoolCreate 函数重新激活它),virStoragePoolDelete 函数可以物理删除一个存储池资源(该操作不可恢复)。

(7)事件管理的API:以virEvent 开头的一系列函数。

libvirt 支持事件机制,使用该机制注册之后,可以在发生特定的事件(如:域的启动、暂停、恢复、停止等)之时,得到自己定义的一些通知。

(8)数据流管理的API:以virStream 开头的一系列函数。

libvirt 还提供了一系列函数用于数据流的传输。

对于 libvirt API 一些细节的使用方法和实现原理,可以参考其源代码或者本章末尾的参考阅读中介绍资料。

 类似资料: