libvirt-java怎么获得kvm虚拟机内存使用率

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了libvirt-java怎么获得kvm虚拟机内存使用率相关的知识,希望对你有一定的参考价值。

  在云平台中,基本都需要这样一个功能,就是收集虚拟机监控数据,比如cpu使用率、内存使用率、磁盘io、网络io等信息。通常这些信息Hypervisor都会提供接口供获取,这种获取方式成本是低廉的,通常不会对整个虚拟化环境有影响。想要获取更多的监控详情信息,那么则需要在虚机里面安装agent来收集监控数据,这种方式获取成本高,有时候可能不会接受镜像里面有agent的事实,这好比被安装了后门一样。两种方式各有优劣,看各自的需求场景,具体使用具体分析。

  KVM内存虚拟化

  KVM在内存虚拟化上有哪些相关技术可以使用。

  对于客户机的内存分配上,KVM提供了ballooning机制,其本质就是可以根据宿主机系统内存使用的紧张程度来动态增加或回收客户机的内存占用。 如果云计算环境准备实施oversell,那么这个机制是十分有用的,因为宿主机上的客户机不可能同时满载,这样便可以有效利用物理内存。

  如果宿主机上跑着很多相同镜像的客户机,那么这些客户机的内存段是有相同之处的,KVM提供了一个KSM(Kernel Samepage Merging)机制,可以将相同的内存合并。 这就意味着在ballooning机制基础上还能更进一步优化内存使用率。但是KSM的开销也很大,尤其是当客户机的镜像耦合非常低会造成KSM效率非常低,不仅内存合并效果不佳, 还会影响宿主机的系统性能,进而影响所有客户机的性能,需要慎重使用。

  此外还有HugePage和Transparent HugePage技术。前者可以给客户机分配一块大内存独占使用,但是因为独占导致很多不灵活,不能在宿主机内存紧张的时候换出; 而后者则是继承了HugePage的优点并弥补了这个缺点。大页技术的使用也需要慎重,如果客户机运行的应用比较依赖内存性能(Redis之流),那么开启这个是值得的。

  下面就是解析一下OpenStack获取虚机内存的方式,以及一些需要注意的坑。

  获取接口

  使用libvirt的命令行工具可以获取虚机的内存信息,方式如下:

  $ virsh list
  Id    Name                           State
  ----------------------------------------------------

  46    instance-0000081a              running
  117   instance-000008c0              running
  122   instance-00000920              running

  $ virsh dommemstat 46
  actual 2097152
  swap_in 0
  rss 1031060

  actual是启动虚机时设置的最大内存,rss是qemu process在宿主机上所占用的内存,可以通过 grep VmRSS /proc/$(pidof qemu-system-x86_64)/status 得到。但是要获取的是虚机内部的内存使用情况,这样明显不能满足需求。

  还需要给虚机做些配置,给虚机的libvirt.xml描述文件添加下面的内容:

  #每10s钟收集一次
  <memballoon model="virtio">
  <stats period="10"/>
  </memballoon>

  再次查询虚机的内存信息,得到:

  actual 2097152
  swap_in 0
  swap_out 0
  unused 1904816
  available 2050112
  rss 299952

  unused代表虚机内部未使用的内存量,available代表虚机内部识别出的总内存量,那么虚机内部的内存使用量则是(available-unused)的结果。


  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”


  OpenStack中的使用

  在OpenStack中,ceilometer组件的meter项有一个memory.usage,这一项便是采样虚机内存使用量信息,在I版本是不能获取到的,这个BP并有相关的实现,代码已经合并到master,且在Juno版本中放出。

参考技术A 最近在用Nagios监控Xen PV虚拟机的时候出现了问题,在被监控的服务器上是采用nrpe来采集数据的。但是在进程里无法看到PV虚拟机的进程,虽然可以通过xm top vpsname的方式来获取名为vpsname虚拟机的cpu使用率情况,但是不便于采集数据,通过xm list可以采集到cpu时间,根据CPU时间的差值,可以计算CPU使用率,可是该命令只能root执行,因为该命令可以进行关闭,重启虚拟机等重要操作,所以如果把权限给了nrpe,将可能造成严重的安全问题。
幸好livirt提供了API,所以我打算尝试用API写一个Nagios的插件来满足的我的需求,我的想法就是分别2次获得虚拟机的CPU时间,并分别记录2次取得数据时的系统时间,然后根据差值来计算,在理论上是存在一些误差的。
1.要使用API,首先需要安装libvirt-devel
[root@aikaiyuan ~]# yum -y install libvirt-devel

2.我的代码如下,文件名为vCpu.c
/**
* Program Name: vCpu.c
* Author: steptodream
* Description:A simple plugin to get vps cpu usage
* for nagios(nrpe) by libvirt api
* Compile:gcc -o vCpu vCpu.c -lvirt
*/
#include <stdlib.h>
#include <stdio.h>
#include <libvirt/libvirt.h>
/* define the exit status for nagios */
#define OK 0
#define WARNING 1
#define CRITICAL 2
#define UNKNOWN 3
/* get cpu time of the given name */
double getCpuTime(char *vpsName,virConnectPtr conn)
virDomainInfo info;
virDomainPtr domain = NULL;
int ret;
/* Find the domain of the given name */
domain = virDomainLookupByName(conn, vpsName);
if (domain == NULL)
printf("Failed to find the vps called %sn", vpsName);
exit(OK);

/* Get the information of the domain */
ret = virDomainGetInfo(domain, &info);
virDomainFree(domain);
if (ret < 0)
printf("Failed to get information for %sn", vpsName);
exit(OK);

return info.cpuTime;

int main(int argc,char * argv[])

char *vpsName; /* vps name */
int interval = 1; /* check interval */
double warning; /* warning value */
double critical; /* critical value */
double cpuUsage; /* cpu usage of the vps */
struct timeval startTime; /* time of the first time to get cpu time */
struct timeval endTime; /* time of the second time to get cpu time */
int realTime; /* real interval between two times */
long long startCpuTime; /* cpu time of the first time */
long long endCpuTime; /* cpu time of the second time */
int cpuTime; /* value of startCpuTime - endCpuTime */
char *output; /* output data for nagios */
int ret; /* exit status for nagios */
virConnectPtr conn; /* connection pointer */
switch (argc)
case 5:
interval = atoi(argv[4]);
case 4:
vpsName = argv[1];
warning = atof(argv[2]);
critical = atof(argv[3]);
break;
default:
printf("Usage:vCpu <vName> <warning> <critical> [interval]nn");
return OK;

/* connect to local Xen Host */
conn = virConnectOpenReadOnly(NULL);
if (conn == NULL)
printf("Failed to connect to local Xen Hostn");
return OK;

/* get cpu time the first time */
startCpuTime = getCpuTime(vpsName, conn);
/* get start time */
if (gettimeofday(&startTime, NULL) == -1)
printf("Failed to get start timen");
return OK;

/* wait for some seconds */
sleep(interval);
/* get cpu time the second time */
endCpuTime = getCpuTime(vpsName, conn);
/* get end time */
if (gettimeofday(&endTime, NULL) == -1)
printf("Failed to get end timen");
return OK;

/* colose connection */
virConnectClose(conn);
/* calculate the usage of cpu */
cpuTime = (startCpuTime - endCpuTime) / 1000;
realTime = 1000000 * (startTime.tv_sec - endTime.tv_sec) +
(startTime.tv_usec - endTime.tv_usec);
cpuUsage = cpuTime / (double)(realTime);
/* display cpuUsage by percentage */
cpuUsage *= 100;

/* make output data and exit status for nagios*/
if (cpuUsage > critical)
output = "CRITICAL";
ret = CRITICAL;
else if (cpuUsage > warning)
output = "WARNING";
参考技术B 使用libvirt的命令行工具可以获取虚机的内存信息,方式如下:
$ virsh list
Id Name State
----------------------------------------------------
46 instance-0000081a running
117 instance-000008c0 running
122 instance-00000920 running

$ virsh dommemstat 46
actual 2097152
swap_in 0
rss 1031060

actual是启动虚机时设置的最大内存,rss是qemu process在宿主机上所占用的内存,可以通过 grep VmRSS /proc/$(pidof qemu-system-x86_64)/status 得到。但是我们要获取的是虚机内部的内存使用情况,这样明显不能满足需求。
我们还需要给虚机做些配置,给虚机的libvirt.xml描述文件添加下面的内容:
#每10s钟收集一次
<memballoon model="virtio">
<stats period="10"/>
</memballoon>

再次查询虚机的内存信息,得到:
actual 2097152
swap_in 0
swap_out 0
unused 1904816
available 2050112
rss 299952

unused代表虚机内部未使用的内存量,available代表虚机内部识别出的总内存量,那么虚机内部的内存使用量则是(available-unused)的结果。本回答被提问者采纳

centos7虚拟机怎么安装kvm

PRE-INSTALL

=============================================================

kvm相关安装包及其作用

qemu-kvm 主要的KVM程序包

python-virtinst 创建虚拟机所需要的命令行工具和程序库

virt-manager GUI虚拟机管理工具

virt-top 虚拟机统计命令

virt-viewer GUI连接程序,连接到已配置好的虚拟机

libvirt C语言工具包,提供libvirt服务

libvirt-client 为虚拟客户机提供的C语言工具包

virt-install 基于libvirt服务的虚拟机创建命令

bridge-utils 创建和管理桥接设备的工具

==========================================

1.确定机器有VT 
终端输入命令:

cat /proc/cpuinfo |grep vmx  #intel cpu
cat /proc/cpuinfo |grpe svm  # amd cpu

如果flags: 里有vmx 或者svm就说明支持VT;如果没有任何的输出,说明你的cpu不支持,将无法使用KVM虚拟机。

2.确保BIOS里开启VT:  Intel(R) Virtualization Tech [Enabled]  使用如下命令

lsmod | grep kvm
modprobe kvm-intel

3.桥接网络

a、安装bridge-utils ,用来管理网桥的工具brctl

yum -y install bridge-utils 

安装完之后systemctl restart network重启下网络

b、创建ifcfg-br0文件,输入下面的内容,修改红色部分为真实相关环境。

TYPE="Bridge"

BOOTPROTO="static"

DEFROUTE="yes"

PEERDNS="yes"

PEERROUTES="yes"

IPV4_FAILURE_FATAL="no"

IPV6INIT="yes"

IPV6_AUTOCONF="yes"

IPV6_DEFROUTE="yes"

IPV6_PEERDNS="yes"

IPV6_PEERROUTES="yes"

IPV6_PRIVACY="no"

IPV6_FAILURE_FATAL="no"

STP="yes"

DELAY="0"

NAME="br0"

DEVICE="br0"

ONBOOT="yes"

IPADDR="172.16.10.215"  #要桥接的网卡上的IP

PREFIX="16"

GATEWAY="172.16.11.1"

DNS1="8.8.4.4"

DOMAIN="ANS.kvm"

c、修改要桥接的网卡配置文件,记得备份下

#TYPE="Ethernet"

#BOOTPROTO="static"

#DEFROUTE="yes"

#PEERDNS="yes"

#PEERROUTES="yes"

#IPV4_FAILURE_FATAL="no"

#IPV6INIT="yes"

#IPV6_AUTOCONF="yes"

#IPV6_DEFROUTE="yes"

#IPV6_PEERDNS="yes"

#IPV6_PEERROUTES="yes"

#IPV6_PRIVACY="no"

#IPV6_FAILURE_FATAL="no"

NAME="eno16777736"

UUID="dad441c6-d806-4b24-98f2-46e606a83288"

DEVICE="eno16777736"

ONBOOT="yes"

#IPADDR="172.16.10.215"

#PREFIX="16"

#GATEWAY="172.16.11.1"

#DNS1="8.8.4.4"

#DOMAIN="anskvm"

BRIDGE="br0"

d、重启网络,并查看网桥状态

systemctl restart  network

brctl show

4、安装kvm

yum -y install libcanberra-gtk2 qemu-kvm.x86_64 qemu-kvm-tools.x86_64  libvirt.x86_64 libvirt-cim.x86_64 libvirt-client.x86_64 libvirt-java.noarch  libvirt-python.x86_64 libiscsi-1.7.0-5.el6.x86_64  dbus-devel  virt-clone tunctl virt-manager libvirt libvirt-python python-virtinst

5、安装x-windows,使用图形界面管理虚拟机

yum groupinstall "X Window System"

6、安装中文字符,解决界面乱码问题

yum install dejavu-lgc-sans-fonts
yum groupinstall "Fonts" -y

7、启用libvirt 

systemctl start libvirtd

systemctl enable libvirtd

8、使用virt-manager管理kvm

本地需要安装xmanager和xshell工具 ,并使用xshell建立连接时勾选x11转移。


9. 上传ISO或者qcow2文件到/var/lib/libvirt/images   #(该目录为KVM的镜像仓库)

使用xshell(使用步骤8进行连接)连接到主机之后,使用virt-manager进行创建虚拟机,需要在安装前进行配置,否则安装过程中键盘和鼠标没法使用。


参考技术A centos7虚拟机怎么安装kvm详见:https://wenku.baidu.com/view/c795c10e240c844768eaeecb.html

以上是关于libvirt-java怎么获得kvm虚拟机内存使用率的主要内容,如果未能解决你的问题,请参考以下文章

使用libvirt-java采集KVM虚拟机状态信息

kvm虚拟机存储速度

KVM虚拟化之安装KVM虚拟机

kvm虚拟机简单定制之一:构建kvm虚拟机(centos7)

kvm虚拟机vcpu和内存管理

linux 哪个虚拟机好???