Libvirt学习笔记

 一、Libvirt简介

        libvirt是一个用于虚拟化管理的库,它提供了一组API,可以用于管理各种虚拟化技术,例如KVM、QEMU、Xen和LXC等。libvirt库使得管理虚拟化环境变得更加容易,它可以用于创建、配置、启动、停止、暂停和恢复虚拟机,以及管理虚拟机的存储和网络等方面。

        在使用libvirt库时,需要注意一些基本概念,例如连接(connection)、域(domain)、存储池(storage pool)、网络(network)等。连接是与虚拟化环境的通信渠道,域是指虚拟机实例,存储池是指存储虚拟机镜像的地方,网络是指虚拟机使用的网络环境。

 二、Libvirt使用手册

1、建立连接:libvirt.open(uri)

         该函数用于建立虚拟环境的链接。该函数的有一个参数uri,来确定建立连接的对象。

        URI是一种用于标识和连接到虚拟化环境的统一资源标识符(Uniform Resource Identifier)。URI由三个部分组成:

        ①scheme:标识使用的虚拟化技术,例如qemu、xen、lxc等。

        ②hostname:指定连接的目标主机的名称或IP地址。

        ③path:标识虚拟化环境的位置或类型。

        如,使用QEMU/KVM作为虚拟化技术,连接到本地系统上的默认虚拟化环境,URI为qemu:///system。如果要连接到远程主机,可以使用主机名部分指定远程主机的名称或IP地址,如使用qemu+ssh://user@remotehost/system可以连接到远程主机上的虚拟化环境。

        libvirt.open(uri) 将返回一个 virConnect 对象,它包含了与虚拟化环境进行通信所需的方法和属性。例如,可以使用 virConnect.listDomains() 方法列出虚拟化环境中存在的域(虚拟机实例)。

conn = libvirt.open('qemu:///system')
domains = conn.listAllDomains()

2、域(虚拟机实例)的各个属性

        在建立连接,并通过 listDomains() 获取连接中的所有虚拟机实例后,我们可以通过多种方法获取虚拟机实例的相关信息。

        以下列出了一些常用的属性:

for domain in domains:

# 虚拟机实例的信息
    print(domain.name())           # 虚拟机名称
    print(domain.ID())             # 虚拟机ID
    print(domain.state())          # 虚拟机状态,返回一个二元组:[a,b]表示状态码和原因码
    print(domain.UUIDString())     # 虚拟机UUID,唯一标识符
    print(domain.info())           # 虚拟机详细信息,返回一个元组,包括了状态、最近一次启动时间、内存使用情况、CPU使用情况等
    print(domain.XMLDesc())        # 返回虚拟机实例的XML描述,包括虚拟机的配置信息和设备信息等

# 对虚拟机实例的操作
    domain.create()                # 启动虚拟机实例
    domain.shutdown()              # 关闭虚拟机实例
    domain.destroy()               # 销毁虚拟机实例
    domain.reboot()                # 重启虚拟机实例
    domain.suspend()               # 暂停虚拟机实例
    domain.resume()                # 恢复暂停的虚拟机实例

        其中,domain.info() 返回的元组中:

        ① info[0] :state 表示虚拟机实例的状态。可以取整数0,1,2,3,4,5,6。

分别表示0:NOSTATE(无状态),1:RUNNING(正在运行),2:BLOCKED(阻塞),3:PAUSED(暂停),4:SHUTDOWN(正在关闭),5:SHUTOFF(已经关闭),6:CRASHED(崩溃)。

        ② info[1] :maxMem 表示虚拟机实例可以使用的最大内存。

        ③ info[2] :memory 表示目前可使用的内存。

        ④ info[3] :nrVirtCpu 表示虚拟机实例的虚拟CPU数量。

        ⑤ info[4] :cpuTime 表示虚拟机实例在虚拟CPU上运行的时间。

3、对指定虚拟机进行查看或操作

        主要用到了 conn.lookupByName(domainName)  这个函数。该函数可以通过虚拟机实例的名称查找并返回 virDomain 对象,具体来说,它会在当前连接的虚拟化环境中查找名称与 domainName 相同的虚拟机实例,并返回一个 virDomain 对象,用于对该虚拟机实例进行操作。

        同理,也可以用 domain 的其他属性来查找,如 lookupByID(domainID) 、 lookupByUUIDString(domainUUID) 等。

        找到指定虚拟机后,通过上面讲到的对虚拟机实例的操作方法进行操作。

        示例:

# 查找指定虚拟机(通过名称查找)
vm = conn.lookupByName(domain_Name)

# 开启虚拟机
if not vm.isActive():
    vm.create()

# 关闭虚拟机
if vm.isActive():
    vm.shutdown()

# 暂停虚拟机
if vm.isActive():
    vm.suspend()

# 继续运行虚拟机
if vm.state()[0] == libvirt.VIR_DOMAIN_PAUSED:
    vm.resume()

4、监视虚拟机网络状态

4.1、判断网络状态

        这里使用paramiko库建立主机与远程虚拟机的SSH连接,通过是否能够连接成功,来判断虚拟机的网络状态是否正常。

        创建一个SSH客户端连接对象。这个对象可以用来连接到远程主机并执行命令。

client = paramiko.SSHClient()

        设置客户端连接对象的主机密钥策略。在默认情况下,当客户端连接到远程主机时,paramiko会检查本地是否存在该主机的密钥,如果不存在则会引发一个警告。paramiko.AutoAddPolicy() 是一种密钥策略,它会自动接受远程主机的密钥,而不会引发警告。

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        使用指定的参数连接到远程主机。hostname 参数指定要连接的远程主机的IP地址或域名, username 参数指定登录远程主机时使用的用户名, password 参数指定登录远程主机时使用的密码。这个函数会尝试连接远程主机并进行身份验证,如果验证成功则会建立一个SSH会话,并返回一个新的通道(channel)对象,可以使用这个对象执行远程命令或传输文件等操作。

client.connect(hostname='192.168.43.61', username='root002', password='*******')

4.2、超时处理 

        如果connect函数执行成功,说明虚拟机网络状态良好,如果connect函数执行失败,说明虚拟机网络状态出现问题。

        由于如果网络出现异常,connect函数会执行很长时间,我们将这种情况直接视为网络异常。

        关于 connect 函数执行时间长的问题,可以通过signal库处理,即超出一定时间,引发TimeoutError异常,返回网络错误信息。

def run_with_timeout(func, timeout):
    def _handle_timeout(signum, frame):
        raise TimeoutError("Function call timed out")

    # Set the signal handler and alarm
    signal.signal(signal.SIGALRM, _handle_timeout)
    signal.alarm(timeout)
    try:
        # Run the function and return the result
        result = func()
    finally:
        # Cancel the alarm and reset the signal handler
        signal.alarm(0)
        signal.signal(signal.SIGALRM, signal.SIG_DFL)
    return result

        参数func是一个函数对象,它表示要运行的函数;参数timeout表示函数运行的最长时间(以秒为单位)。

        在函数内部,首先定义了一个名为_handle_timeout的内部函数,它是一个信号处理函数,用于在函数运行超时时引发TimeoutError异常。

        使用signal.signal()函数设置了一个信号处理程序,用于在超时时调用_handle_timeout函数。signal.SIGALRM表示设置的是闹钟信号,_handle_timeout是信号处理程序的回调函数。

        然后,使用signal.alarm()函数设置一个定时器,用于在timeout秒后发送一个闹钟信号。如果函数在这个时间内没有完成运行,就会触发闹钟信号,从而引发TimeoutError异常。

        使用try-finally语句运行函数func。如果函数在规定时间内完成运行,则取消定时器并返回函数的返回值;否则,闹钟信号会引发 TimeoutError 异常。在这种情况下,finally块中的代码会取消定时器并重置信号处理程序,以确保程序的正确性并避免影响后续的代码执行。

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值