设为首页 收藏本站
查看: 1065|回复: 0

[经验分享] [zz]OpenStack中虚拟机的监控

[复制链接]

尚未签到

发表于 2015-4-12 10:52:12 | 显示全部楼层 |阅读模式
整个方案的基本思想是由host负责运行程序,采集数据,额外一台服务器作为server收集每台host的数据进行分析。本文涉及的程序代码均可以从Github上下载,虚拟化使用kvm,使用libvirt作为C API。
AD:







  本文涉及的程序代码均可以从我的github上下载, 并且持续更新代码
  虚拟化使用kvm,使用libvirt作为C API
  基本思想:host负责运行程序,采集数据,额外一台服务器作为server收集每台host的数据进行分析
  程序介绍:
  首先我们需要打开一个和hypervisor的连接,需要一个virConnectPtr的指针
  virConnectOpenReadOnly(char *) 返回的就是这麽一个指针。初始化程序例如:

void conn_init(char *ip, virConnectPtr *conn) {
    *conn = NULL; /* the hypervisor connection */
    char *p;
    p = (char *)malloc(35*sizeof(char));
    *conn = virConnectOpenReadOnly(p);
    free(p);
    if (*conn == NULL) {
        fprintf(stderr, "Failed to connect to hypervisor\n");
    }
}
  第二个参数是一个指向virConnectPtr变量的指针,这裡的p指向的是类似“qemu+ssh://10.0.0.1/system”的字符串,10.0.0.1是你的host ip
  关闭连接的函数

void conn_close(virConnectPtr *conn) {
    if (*conn != NULL)
        virConnectClose(*conn);
}
  现在我们有了一个指向host的hypervisor的连接,我们可以用他来获得host上跑的虚拟机的情况

void list_id_domain(virConnectPtr conn) {
    int ids[10];
    int maxids=10;
    int num, i;
    num = virConnectListDomains(conn, ids, maxids);
    for(i = 0;i < num;i++) {
        printf("%d\n",ids);
    }
}
  这个函数使用上面得到的conn这个指针,列出host上跑的实例的id号
  有了id号我们就可以获取每个实例的详细信息,假设我有一个id为7的虚拟机实例:

virDomainPtr dom = NULL;
dom = virDomainLookupByID(conn, 7);
  dom这个变量就是以后我们要一直用到的,释放函数:

virDomainFree(dom);
  cpu监控程序:

void list_info_domain(virDomainPtr domain) {
    virDomainInfo info;
    int interval = 2;
    struct timeval startTime;
    struct timeval endTime;
    int realTime;
    int cpuTime;
    double cpuUsage;
    virDomainGetInfo(domain, &info);
    unsigned long long startCpuTime = info.cpuTime;
    if (gettimeofday(&startTime, NULL) == -1) {
        printf("Failed to get start time\n");
    }
    sleep(interval);
    virDomainGetInfo(domain, &info);
    unsigned long long endCpuTime = info.cpuTime;
    if (gettimeofday(&endTime, NULL) == -1) {
        printf("Failed to get end time\n");
    }
    cpuTime = (endCpuTime - startCpuTime)/1000;
    realTime = 1000000 * (endTime.tv_sec - startTime.tv_sec) + (endTime.tv_usec - startTime.tv_usec);
    cpuUsage = cpuTime / (double)(realTime);
    printf("\t\tstate is %d\n", info.state);
    printf("\t\tvCPU is %d\n", info.nrVirtCpu);
    printf("\t\tMAXmemory is %ld\n", info.maxMem/1024);
    printf("\t\tmemory is %ld\n", info.memory/1024);
    printf("\t\tcpuUsage is %.2f%\n", cpuUsage*100);
}
  解释一下程序,首先virDomainGetInfo函数,传入刚才我们得到的domain,另外一个参数是要返回的virDomainInfo的结构体变量,其中包含了cpu个数,分配的时间,和分配的mem信息。我们分别取了间隔为2妙的info信息,使用裡面的info.cpuTime运行时间,把后一次减去前一次,然后再除以实际的gettimeofday函数得到host的cpu运行时间,得到一个近似的百分比,反应的是此虚拟机实例的cpu使用情况在整个host的cpu使用情况中的百分比。
  磁盘监控:

void list_disk_domain(virDomainPtr domain) {
    virDomainBlockStatsStruct stats;
    size_t size;
    const char *disk = "vda";
    size = sizeof(stats);
    int interval = 2;
    virDomainBlockStats(domain, disk, &stats, size);
    long long start_rd_bytes = stats.rd_bytes;
    long long start_wr_bytes = stats.wr_bytes;
    sleep(interval);
    virDomainBlockStats(domain, disk, &stats, size);
    long long end_rd_bytes = stats.rd_bytes;
    long long end_wr_bytes = stats.wr_bytes;
    long rd_bytes = end_rd_bytes - start_rd_bytes;
    long wr_bytes = end_wr_bytes - start_wr_bytes;
    int rd_usage = rd_bytes/interval;
    int wr_usage= wr_bytes/interval;
// printf("%s:\n", virDomainGetName(domain));
    printf("\t\tread: %dbytes/s\n", rd_usage);
    printf("\t\twrite: %dbytes/s\n", wr_usage);
    printf("\t\trd_req: %lld\n", stats.rd_req);
    printf("\t\trd_bytes: %lld\n", stats.rd_bytes);
    printf("\t\twr_req: %lld\n", stats.wr_req);
    printf("\t\twr_bytes: %lld\n", stats.wr_bytes);
}
  磁盘使用情况的方法和cpu类似,这裡用到的是virDomainBlockStats(domain, disk, &stats, size)这个函数,disk指向的字符串这裡为“vda”,实际使用甚麽你要根据xml裡面的信息
  网络部份这裡我们要用到libvirt中的Network Filters
  openstack实例的libvirt.xml在nova.conf中定义的实例目录下,里面有

...









...
  filterref中包括了其他的filters,默认在/etc/libvirt/nwfilter目录下
  你也可以使用virsh管理工具查看具体filter内容

# virsh nwfilter-dumpxml nova-instance-instance-00000007-02163e23f37d
Filtering chains
  Filtering chains就是你在目录下看到的许多filters的文件。譬如有arp, 有dhcp, mac等
  在程序中使用libvirt

int list_network_domain(virDomainPtr domain) {
    const char *path;
    virDomainInterfaceStatsStruct stats;
    size_t size;
    size = sizeof(stats);
    path = "vnet1";
    int interval = 2;
    if( virDomainInterfaceStats(domain, path, &stats, size) )
        return FALSE;
    long long start_rx_bytes = stats.rx_bytes;
    long long start_tx_bytes = stats.tx_bytes;
    sleep(interval);
    if( virDomainInterfaceStats(domain, path, &stats, size) )
        return FALSE;
    long long end_rx_bytes = stats.rx_bytes;
    long long end_tx_bytes = stats.tx_bytes;
    int rx_usage = (end_rx_bytes - start_rx_bytes)/interval;
    int tx_usage = (end_tx_bytes - start_tx_bytes)/interval;
    printf("\t\trx usage: %d bytes/s", rx_usage);
    printf("\trx bytes: %lld bytes", stats.rx_bytes);
    printf("\t\trx packets: %lld", stats.rx_packets);
    printf("\trx errs: %lld\n", stats.rx_errs);
    printf("\t\ttx usage: %d bytes/s", tx_usage);
    printf("\ttx bytes: %lld bytes", stats.tx_bytes);
    printf("\t\ttx packets: %lld", stats.tx_packets);
    printf("\ttx errs: %lld\n", stats.tx_errs);
}
  这个函数很重要,其中将返回stats指针所指向的内容便是domain中各个网口的信息。这裡有个问题,就是path的值,他是由domain中网卡的名字,不是eth0也不是em0等,而是要通过获取domain的xml中网卡的interface部分中这一部分中的vnet0,同理前面说得disk裡面的“vda”也是从这裡获取,
  所以你需要运行一下这个程序

    char *xmldesc;
    xmldesc = virDomainGetXMLDesc(dom, 0);
    if ((fp = fopen(virDomainGetName(dom), "w")) == NULL) {
        printf("Cannot open file test\n");
    }
    fprintf(fp,xmldesc);
    fclose(fp);
    free(xmldesc);
  返回的是字符串指针指向了xml的内容,记住这个程序运行好需要free指针。
  via livemoon的博客
  【编辑推荐】


  • 专题:OpenStack简介与入门指南汇总
  • OpenStack Compute(Nova)功能分析
  • 以公司实际应用讲解OpenStack到底是什么(入门篇)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-56225-1-1.html 上篇帖子: OpenStack: 让虚拟机自己管理DHCP 下篇帖子: 【转】 [官版翻译]OpenStack centos版安装(一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表