Obtain monitoring information of kvm virtual machine through python (based on libvirt API)

Usually in our cloud environment, in order to ensure the normal operation of the virtual machine in the cloud platform, we basically need such a function, that is to collect the monitoring data of the virtual machine, such as cpu usage, memory usage, disk io, network io and other basic information. This information can be used to adjust some problems in the cloud platform environment in time, so as to ensure the normal operation of the VM.

  When it comes to KVM management tools, the first thing that should come to mind is libvirt, because currently the most widely used management tool (application interface) for KVM is libvirt. Libvirt itself is built on an abstraction that provides a common API for implementing commonly used functions for supported hypervisors. Libvirt provides a native layer interface for operating KVM, which can implement basic management operations on virtual machines. The Libvirt library is implemented in C and includes direct support for python. Libvirt-python is a python language binding toolkit based on libvirt API, through which the daily management and monitoring data of VM can be obtained.

 Use python to obtain VM monitoring information by calling libvirt API

 1) By importing the libvirt module, and then connecting the local qemu hypervisor. Get the domain of each instance on the host and get some basic information.

1

2

3

4

5

6

7

8

import libvirt

conn = libvirt.open("qemu:///system")

for id in conn.listDomainsID():

    domain = conn.lookupByID(id)

    print domain.name()  

    print domain.UUIDString()

    print domain.info()

conn.close()

1

2

3

4

5

[root@kvm opt]# python libvirt_test.py 

KaMg8c0hOSn1

instance1

7dd3ec0e-9b56-4e35-b14d-a58811e5c6ce

[12097152L2097152L28823450000000L]

domain.info() returns a list of parameter descriptions:

[State:1, Max memory:2097152L, Used memory:2097152L, CPU(s):2, CPU time:4245630000000L]

 For the meaning of the specific parameter values, please refer to the corresponding API at http://libvirt.org/html/libvirt-libvirt-domain.html.

 This simple example shows the power that libvirt provides through python.

 2) Get cpu usage

 In Libvirt, the CPU usage of the virtual machine cannot be directly obtained, but the actual usage can be calculated by cputime. The calculation formula is:

First get a cycle difference: cputime_diff = (cpuTimenow — cpuTimet seconds ago)

Calculate the actual usage: %cpu = 100 × cpu_time_diff / (t × nr_cores × 109) Implementation:

illustrate:

cputime can be obtained through dom.info()[4]

Get the number of CPUs through dom.info()[3]

Simple example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import libvirt

import time

conn = libvirt.open("qemu:///system")

for id in conn.listDomainsID():

    domain = conn.lookupByID(id)

    t1 = time.time()

    c1 = int (domain.info()[4])

    time.sleep(1);

    t2 = time.time();

    c2 = int (domain.info()[4])

    c_nums = int (domain.info()[3])

    usage = (c2-c1)*100/((t2-t1)*c_nums*1e9)

    print "%s Cpu usage %f" % (domain.name(),usage)

conn.close()

1

2

[root@kvm opt]# python libvirt_test.py 

instance1 Cpu usage 0.998784

 3) Get network traffic information

  You can use dom.interfaceStats(interface) to get the traffic information of the virtual network card, but this method needs to pass a virtual network card name as a parameter. You can use libvirt's API to get the domain status and get the xml configuration file. Obtain the name of each available device to be monitored through the xml tree, and then obtain the attribute field value of the device through the domain, which is the value to be monitored.

Simple example:

1

2

3

4

5

6

7

8

9

10

11

12

import libvirt

from xml.etree import ElementTree

conn = libvirt.open("qemu:///system")

for id in conn.listDomainsID():

    domain = conn.lookupByID(id)

    tree = ElementTree.fromstring(domain.XMLDesc())

    ifaces = tree.findall('devices/interface/target')

    for in ifaces:

        iface = i.get('dev')

        ifaceinfo = domain.interfaceStats(iface)

        print domain.name(),iface,ifaceinfo

conn.close()

1

2

3

[root@kvm opt]# python libvirt_test.py 

instance1 vnet12 (90L1L0L0L1632L24L0L0L)

instance1 vnet13 (63120L256L0L371L0L0L0L0L)

domain.interfaceStats(iface) returns the result description:

(rx_bytes:24194376L, rx_packets:363592L, rx_errs:0L, rx_drop:0L, tx_bytes:852996L, tx_packets:20302L, tx_errs:0L, tx_drop:0L)

Information such as network throughput can be obtained by processing these basic data.

 4) Get disk information  

 Get the total amount and used amount of the disk, which can be obtained through dom.blockInfo(dev). This method needs to pass a parameter, you can use the libvirt API to get the domain status and get the xml configuration file. Obtain the name of each available device to be monitored through the xml tree, and then obtain the attribute field value of the device through the domain, which is the value to be monitored.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import libvirt

from xml.etree import ElementTree

conn = libvirt.open("qemu:///system")

for id in conn.listDomainsID():

    domain = conn.lookupByID(id)

    tree = ElementTree.fromstring(domain.XMLDesc())

    devices = tree.findall('devices/disk/target')

    for in devices:

        device = d.get('dev')

        try:

            devinfo = domain.blockInfo(device)

        except libvirt.libvirtError:

            pass

        print domain.name(),device,devinfo

conn.close()

1

2

[root@kvm opt]# python libvirt_test.py 

instance1 vda [42949672960L2233990656L2300968960L]

1

domain.blockInfo(device)返回结果说明:

(capacity:42949672960L, allocation:2233990656L,physical:2300968960L)

 

 Get the i/o of the disk, which can be obtained by dom.blockStats(dev).

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import libvirt

from xml.etree import ElementTree

conn = libvirt.open("qemu:///system")

for id in conn.listDomainsID():

    domain = conn.lookupByID(id)

    tree = ElementTree.fromstring(domain.XMLDesc())

    devices = tree.findall('devices/disk/target')

    for in devices:

        device = d.get('dev')

        try:

            devstats = domain.blockStats(device)

            print domain.name(),device,devstats

        except libvirt.libvirtError:

            pass

conn.close()

1

2

3

[root@kvm opt]# python libvirt_test.py 

instance1 vda (15100L240801280L48509L395756032L-1L)

instance1 hda (6L164L0L0L-1L)

domain.blockStats(device) returns a list parameter description:

(read_bytes=1412453376L,read_requests=67017L, write_bytes=2315730432L, write_requests=245180L,errors=-1L)

 

 通过上边的基础操作可以得到一些磁盘的基础数据,可以对这些数据处理得到想要的磁盘信息,如:磁盘iops等

 5)获得内存信息

 可以通过domain.memoryStats()来获取memory的相关信息。

简单示例:

1

2

3

4

5

6

7

8

9

10

11

import libvirt

conn = libvirt.open("qemu:///system")

for id in conn.listDomainsID():

    domain = conn.lookupByID(id)

    domain.setMemoryStatsPeriod(10)

    meminfo = domain.memoryStats()

    free_mem = float(meminfo['unused'])

    total_mem = float(meminfo['available'])

    util_mem = ((total_mem-free_mem) / total_mem)*100

    print (str(domain.name())+' Memory usage :' + str(util_mem))

conn.close()

1

2

[root@kvm opt]# python libvirt_test.py 

instance1 Memory usage :27.4561247103

domain.memoryStats()返回结果说明:

{'swap_out': 0L, 'available': 1884432L, 'actual': 2097152L, 'major_fault': 457L, 'swap_in': 0L, 'unused': 1367032L, 'minor_fault': 1210349717L, 'rss': 743604L}

 其中actual是启动虚机时设置的最大内存,rss是qemu process在宿主机上所占用的内存,unused代表虚机内部未使用的内存量,available代表虚机内部识别出的总内存量,

那么虚机内部的内存使用量则是可以通过(available-unused)得到。

其实可以使用libvirt的命令行工具获取并查看虚机的内存信息

具体操作如下:

1

2

3

4

$ virsh dommemstat instance1

actual 2097152

swap_in 0

rss 743604

如果出现如上情况,是因为在VM内没有安装virtio驱动,所有不能获取VM内存的详细信息。

 

正常在VM内部安装virtio驱动并且支持memballoon,执行上述操作可以看到如下结果:

1

2

3

4

5

6

7

$ virsh dommemstat instance1

actual 2097152

swap_in 0

swap_out 0

unused 1367032

available 2050112

rss 743604

注意:

 要获取VM内存使用详细信息,VM中需要安装virtio驱动并且支持memballoon。

 关于virtio驱动:Linux一般都会包含(通过 lsmod | grep virtio 查看),但是windows的virtio驱动需要自己在镜像中安装。

windows注意事项:

 首先windows需要安装virtio-win相关驱动,驱动下载地址 在这里 ,除此之外还需要启动BLNSVR服务。

在 Windows 2008r2 and Windows 2012/Win8 :

    Copy and rename as Administrator the WIN7AMD64 directory from the virtio.iso to “c:/Program files/Balloon”

    Open a CMD as Administrator and cd into “c:/Program Files/Balloon”

    Install the BLNSVR with “BLNSVR.exe -i”

在 Windows 2003 / Windows Xp :

    Download the “devcon” software on microsoft website kb311272

    devcon install BALLOON.inf “PCIVEN_1AF4&DEV_1002&SUBSYS_00051AF4&REV_00”

更多详情请参考: https://pve.proxmox.com/wiki/Dynamic_Memory_Management

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325904960&siteId=291194637