利用Grafana為OpenStack搭建現(xiàn)代化監(jiān)控系統(tǒng)

背景

首先簡單說下為什么會用grafana,最近公司在新機(jī)房上了300多臺物理機(jī),其中有80多臺分配給我做OpenStack的私有云環(huán)境。OpenStack部署很快,三下五除二很快就上線了Mitaka的版本。但是在分給各個運(yùn)維使用一段時間后,暴露一些問題。

  • 場景一

某個干壞事的小朋友在虛擬機(jī)里面搞性能測試,直接打滿cpu使用率和物理機(jī)的網(wǎng)絡(luò)IO,影響這個物理機(jī)上的其他虛擬機(jī)。(已經(jīng)通過AZ隔離了測試環(huán)境和生產(chǎn)環(huán)境)

  • 場景二

OpenStack的Cinder卷采用的LVM + Iscsi方式提供,線上虛擬機(jī)的某個在某個時間點(diǎn)同步大量數(shù)據(jù)到數(shù)據(jù)卷,造成打滿存儲網(wǎng)絡(luò)。直接表現(xiàn)的現(xiàn)象就是虛擬機(jī)里面的/dev/vdb設(shè)備掉線,造成異常。

種種現(xiàn)象表明,我需要接入一個監(jiān)控系統(tǒng),實(shí)現(xiàn)快速定位到某個物理機(jī)或者虛擬機(jī)的異常指標(biāo)。之前打算采用公司現(xiàn)有的zabbix監(jiān)控框架,但是有兩個點(diǎn)讓我放棄使用zabbix的方案。其一,zabbix在繪圖制表以及對指標(biāo)排序方面相比grafana來還是有一定差距;二來,部門負(fù)責(zé)監(jiān)控的同事太忙了,沒時間開發(fā)我提出的需求,沒辦法只有自己動手(手動苦笑臉)。

選擇

既然要自己動手,那就要選擇合適自己監(jiān)控系統(tǒng)。目前網(wǎng)上的方案太多,剛開始找的時候簡直一臉懵逼,直到我看到一片文章,標(biāo)題我忘了,大概內(nèi)容是利用Collectd + Influxdb + Grafana來做虛擬機(jī)監(jiān)控。遺憾的是,那篇文章講得很短,幾乎沒有實(shí)質(zhì)性的內(nèi)容。好吧,既然有人提出過方案,那我沒理由不試一下。

Collectd

簡單來說Collectd是用C開發(fā)一套高性能的監(jiān)控指標(biāo)采集agent,官網(wǎng)上已經(jīng)有豐富的插件,實(shí)現(xiàn)各種監(jiān)控指標(biāo)。同時也支持通過Shell、Python、Ruby、Perl等一些編程語言實(shí)現(xiàn)擴(kuò)展的監(jiān)控指標(biāo)。這里需要注意的是,自定義的監(jiān)控指標(biāo)是沒有在Collectd默認(rèn)的類型數(shù)據(jù)庫里面(/usr/share/collectd/types.db),所以如果要自定義監(jiān)控,需要創(chuàng)建一個自己的types.db,然后在collectd的配置文件里面加上
TypesDB "/usr/local/share/types.db.custom"
Github上有個collectd-rabbitmq插件,可以讓我們很好的理解collectd的采集機(jī)制。
另外,無意間發(fā)現(xiàn)一位大神的博客bolg.kankanan.com,里面Collectd相關(guān)的文章相當(dāng)不錯。

Influxdb

又一個用go語言寫出來的時序數(shù)據(jù)庫神器,廣泛用于監(jiān)控系統(tǒng)的后端存儲,對計(jì)算大量數(shù)據(jù)的指標(biāo)有著不俗的表現(xiàn)。同時提供豐富的查詢函數(shù)。最重要的是提供collectd的插件,可以讓collectd直接將采集到的指標(biāo)通過udp協(xié)議發(fā)往數(shù)據(jù)庫。

Grafana

不用多說,炫酷的監(jiān)控前端數(shù)據(jù)展示工具。支持多種數(shù)據(jù)源接入,以及多種插件。

操作

既然選好工具,那就開始動手吧。首先我選擇CentOS7系統(tǒng),添加EPEl源。

Collectd

  • 安裝
yum install collectd collectd-lvm collectd-virt

collectd 采集普通指標(biāo)
collectd-lvm 用來采集cinder-volumes指標(biāo)
collectd-virt 用來采集虛擬機(jī)指標(biāo)

  • 配置文件
#cat /etc/collectd.conf |grep -v ^#|sed '/^$/d'

LoadPlugin syslog
LoadPlugin cpu
LoadPlugin df
LoadPlugin disk
LoadPlugin interface
LoadPlugin load
LoadPlugin lvm
LoadPlugin memory
LoadPlugin network
<Plugin network>
    server "<influxdb ip>" "25826"
</Plugin>
Include "/etc/collectd.d"
  • libvirt插件配置
 cat /etc/collectd.d/libvirt.conf
 
 LoadPlugin virt
<Plugin virt>
       Connection "qemu:///system"
       RefreshInterval 60
#       Domain "name"
#       BlockDevice "name:device"
#       InterfaceDevice "name:device"
#       IgnoreSelected false
       HostnameFormat uuid
#       InterfaceFormat name
       PluginInstanceFormat  uuid
</Plugin>

配好后啟動collectd即可

安裝InfluxDB

  • 安裝
#axel -n 20 wget https://dl.influxdata.com/influxdb/releases/influxdb-1.1.1.x86_64.rpm

#yum localinstall -y influxdb-1.1.1.x86_64.rpm
  • 配置文件
/etc/influxdb/influxdb.conf
[[collectd]]
  enabled = true
  bind-address = "<本機(jī)ip>:25826"
  database = "collectd"
  retention-policy = ""
  typesdb = "/usr/share/collectd/types.db"

** 安裝Grafana**

  • 安裝
#axel -n 20 https://grafanarel.s3.amazonaws.com/builds/grafana-4.0.2-1481203731.x86_64.rpm

#yum localinstall -y grafana-4.0.2-1481203731.x86_64.rpm

構(gòu)建OpenStack的Influx索引表

由于通過Collectd采集上來的指標(biāo)中,沒有宿主機(jī)AZ,也沒有物理機(jī)與虛擬的映射關(guān)系,更沒有租戶和虛擬機(jī)的信息。這個時候就需要自己動手去構(gòu)建索引表了。我這里寫了一個很Low逼的Shell腳本,來幫助我定時向InfluxDB里面Post最新的OpenStack信息。
腳本.

#!/usr/bin/env bash

#!/bin/bash

influxdb_url="http://$influxdb:8086"
database="collectd"
write_data="${influxdb_url}/write?db=${database}"
write_data="${influxdb_url}/write?db=${database}"

log_file="/var/log/mitaka/mapping_hosts.log"
log_time=`date +%Y-%m-%d\ %T`

tmp_file="/tmp/.measurement.tmp"
map_file="/tmp/.map.tmp"
tenant_file="/tmp/.tenant_map"
cinder_map_file="/tmp/.cinder.map.tmp"

function Get_influxdb_ip_Region(){
     [[ `echo ${1} | awk -F '.' '{print $1$2}'` == "" ]] && echo "RegionOne"
     [[ `echo ${1} | awk -F '.' '{print $1$2}'` == "" ]] && echo "RegionTwo"
}

function delete_mensurement_hosts(){
    echo "$(date +%Y-%m-%d\ %T)    Delete measurement from databases collectd." >> ${log_file}

    #delete hosts
    curl -Ss -POST ${influxdb_url}/query?db=collectd --data-urlencode "q=DROP measurement hosts"  >> ${log_file}
    if [[ $? -eq 0 ]];then
        echo "$(date +%Y-%m-%d\ %T)    Delete successfully" >> ${log_file}
    else
        echo "$(date +%Y-%m-%d\ %T)    Delete faild, unknown error." >> ${log_file}
    fi

    #delete volumes
    curl -Ss -POST ${influxdb_url}/query?db=collectd --data-urlencode "q=DROP measurement volumes"  >> ${log_file}
    if [[ $? -eq 0 ]];then
        echo "$(date +%Y-%m-%d\ %T)    Delete measurements volumes successfully" >> ${log_file}
    else
        echo "$(date +%Y-%m-%d\ %T)    Delete measurements volumes faild, unknown error." >> ${log_file}
    fi
}

function get_mapping(){
    touch ${tmp_file}
    touch ${map_file}

    #get regionone vm
    source /root/.keystonerc_admin_one
    openstack server list --all --long -f value 2>&1 >> ${tmp_file}
    echo "$(date +%Y-%m-%d\ %T)    Get RegionOne mapping host." >> ${log_file}
    nova list --all-tenants|grep -E 'vlan' |awk  -F '|' '{print $2 $4}' >> ${map_file}

    #get regiontwo vm
    source /root/.keystonerc_admin_two
    openstack server list --all --long -f value 2>&1 >> ${tmp_file}
    echo "$(date +%Y-%m-%d\ %T)    Get RegionTwo mapping host." >> ${log_file}
    nova list --all-tenants|grep -E 'vlan' |awk  -F '|' '{print $2 $4}' >> ${map_file}

    #get vm to user mapping
    for uuid in `cat ${tenant_file} |awk '{print $1}'`;
    do
        user=`cat ${tenant_file} |grep $uuid | awk '{print $2}'`
        sed -i "s/${uuid}/${user}/g" ${map_file}
    done
}

function Post_measurements_hosts(){

    for uuid in `cat ${tmp_file}|awk '{print $1}'`;
    do
        availability_zone=`cat ${tmp_file} |grep -w $uuid |awk '{print $7}'`
        instance_name=`cat ${tmp_file} |grep -w $uuid |awk '{print $2}'`
        host=`cat ${tmp_file} |grep -w $uuid |awk '{print $8}'`
        ipaddress=`cat ${tmp_file} |grep -w $uuid |awk '{print $6}'`
        tenant=`cat ${map_file} |grep -w $uuid |awk '{print $2}'`
        region=`Get_influxdb_ip_Region ${ipaddress#*=}`

        #post data
        echo "$(date +%Y-%m-%d\ %T)    Post $write_data  $uuid $availability_zone $region $instance_name $host ${ipaddress#*=} ${tenant}." >> ${log_file}
        curl -Ss -i -XPOST "${write_data}" --data-binary "hosts,uuid=${uuid},instance=${instance_name},ip=${ipaddress#*=},availability_zone=${availability_zone},datacenter=${region},host=${host},tenant=${tenant} value=1" >> ${log_file}
    done
}

function get_cinder_mapping(){
    touch ${cinder_map_file}

    #get yz volume
    source /root/.keystonerc_admin_one
    openstack volume list --all -f value 2>&1 >> ${cinder_map_file}
    echo "$(date +%Y-%m-%d\ %T)    Get mapping RegionOne Cinder Volumes." >> ${log_file}

    #get zw volume
    source /root/.keystonerc_admin_twi
    openstack volume list --all -f value 2>&1 >> ${cinder_map_file}
    echo "$(date +%Y-%m-%d\ %T)    Get mapping RegionTwo Cinder Volumes." >> ${log_file}
}

function Post_measurements_volumes(){
    for uuid in `cat ${cinder_map_file} |grep Attached |awk '{print $1}'`;
    do
        volume_name=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $2}'`
        volume_disk_size=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $4}'`
        attach_vm_uuid=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $7}'`
        vm_device_name=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $9}'`

        echo "$(date +%Y-%m-%d\ %T) Post $write_data $uuid $volume_name $volume_disk_size $attach_vm_uuid $vm_device_name." >> ${log_file}
        curl -Ss -i XPOST "${write_data}" --data-binary "volumes,uuid=${uuid},name=${volume_name},status=attached,vm_uuid=${attach_vm_uuid},vm_device=${vm_device_name} size=${volume_disk_size}" >> ${log_file}
    done

    for uuid in `cat ${cinder_map_file} |grep available |awk '{print $1}'`;
    do
        volume_name=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $2}'`
        volume_disk_size=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $4}'`
        echo "$(date +%Y-%m-%d\ %T) Post $write_data $uuid $volume_name $volume_disk_size." >> ${log_file}
        curl -Ss -i XPOST "${write_data}" --data-binary "volumes,uuid=${uuid},name=${volume_name},status=available,vm_uuid=none,vm_device=none size=${volume_disk_size}" >> ${log_file}
    done

    for uuid in `cat ${cinder_map_file} |grep error |awk '{print $1}'`;
    do
        volume_disk_size=`cat ${cinder_map_file} |grep ${uuid} | awk '{print $3}'`
        echo "$(date +%Y-%m-%d\ %T) Post $write_data $uuid $volume_disk_size." >> ${log_file}
        curl -Ss -i XPOST "${write_data}" --data-binary "volumes,uuid=${uuid},name=none,status=error,vm_uuid=none,vm_device=none size=${volume_disk_size}" >> ${log_file}
    done
}

get_mapping
get_cinder_mapping
delete_mensurement_hosts
Post_measurements_hosts
Post_measurements_volumes

rm -rf ${tmp_file}
rm -rf ${map_file}
rm -rf ${cinder_map_file}

然后實(shí)現(xiàn)的效果就如下

MEASUREMENTS hosts

現(xiàn)在有了這個表,就可以愉快的在Grafana上創(chuàng)建templating了。

5.繪圖

DashBoard

dashboard主要匯總OpenStack的資源使用情況,同時對物理機(jī)和虛擬機(jī)的使用情況做排序。這樣在單位時間內(nèi),我就能知道是哪臺物理機(jī)或虛擬機(jī)占用的資源最多。

Dashboard0
Dashboard1

計(jì)算節(jié)點(diǎn)

templating

計(jì)算節(jié)點(diǎn)當(dāng)然需要索引availabilit_zone和host信息了。所以templating的配置如下

show tag values from hosts with key = "availability_zone"
show tag values from hosts with key="host" where availability_zone =~ /$Zone$/

指標(biāo)

計(jì)算節(jié)點(diǎn)展示頁面

租戶信息

templating

show tag values from hosts with key = "tenant"
show tag values from hosts with key = "availability_zone" where tenant=~ /$Tenant$/
show tag values from hosts with key = "ip" where tenant=~ /$Tenant$/ and availability_zone =~ /$Zone$/
show tag values from hosts with key = "instance" where ip =~ /$ip$/show tag values from hosts with key = "uuid" where ip =~ /$ip$/

指標(biāo)

租戶展示頁面

關(guān)于監(jiān)控的思考與不足

我們都知道OpenStack有一套自己的監(jiān)控計(jì)費(fèi)框架OpenStack-ceilometer,由于我的需求很簡單,所以部署一套ceilometer做作用有點(diǎn)殺雞用牛刀。對于私有云來說,能夠滿足快速定位虛擬機(jī)或者物理機(jī)故障即可,由于虛擬機(jī)上業(yè)務(wù)都接入自動配置系統(tǒng),理論上可以接受單個虛擬機(jī)宕機(jī)的情況。

不足

  • 由于influxdb目前不支持多表查詢,監(jiān)控查詢出來的虛擬機(jī)tag是uuid。在定位的時候還需要手動openstack server show uuid,去查虛擬機(jī)所屬的tenant。目前我這邊能夠想到的是通過聯(lián)合查詢,將libvirt采集的虛擬機(jī)virt_表和hosts表into到一個新表里,再做查詢展示。
  • 監(jiān)控?cái)?shù)據(jù)持久性,數(shù)據(jù)采集量跟隨系統(tǒng)擴(kuò)展而變大,這里不得不設(shè)置一條數(shù)據(jù)庫的數(shù)據(jù)保留策略,用于控制數(shù)據(jù)庫的增長。

數(shù)據(jù)保留30天

CREATE RETENTION POLICY "mitaka" ON "collectd" DURATION 720h REPLICATION 1 DEFAULT;

> SHOW RETENTION POLICIES ON collectd
name        duration    shardGroupDuration  replicaN    default
----        --------    ------------------  --------    -------
mitaka      720h0m0s    24h0m0s         1       true
  • Grafana的監(jiān)控告警,目前OpenStack的告警還是通過Zabbix發(fā)送信息到郵件和短信網(wǎng)關(guān),至于Grafana的告警暫時還沒有找到好用的方式,有知曉的朋友可以交流一下
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Zabbix簡介 Zabbix官方網(wǎng)站Zabbix中文文檔 本文系統(tǒng)環(huán)境是CentOS7x86_64, Zabbi...
    Zhang21閱讀 8,289評論 0 37
  • 導(dǎo)讀:容器對于物理機(jī)和虛擬機(jī),單從監(jiān)控上看就不是一個數(shù)量級的,但監(jiān)控又是至關(guān)重要的,沒有監(jiān)控如同閉眼開車。 本次分...
    優(yōu)云數(shù)智閱讀 2,270評論 0 4
  • 本文遵循「知識共享許可協(xié)議 CC-BY-NC-SA 4.0 International」,未經(jīng)作者(laiwei)...
    laiwei閱讀 13,426評論 7 18
  • 一、準(zhǔn)備搭建環(huán)境 1.系統(tǒng):CentOS 7.3 2.軟件:Zabbix 3.2 二、安裝前的準(zhǔn)備 最小化安裝Ce...
    塵世不擾閱讀 4,391評論 8 31
  • 隨著線上服務(wù)的全面docker化,對docker容器的監(jiān)控就很重要了。SA的監(jiān)控系統(tǒng)是物理機(jī)的監(jiān)控,在一個物理機(jī)跑...
    __七把刀__閱讀 14,341評論 3 22

友情鏈接更多精彩內(nèi)容