【博文推薦】Docker高級(jí)應(yīng)用之資源監(jiān)控
本篇博文出自51CTO博客博主吟—技術(shù)交流,有任何問題請(qǐng)進(jìn)入博主頁面互動(dòng)討論! |
最近忙著開發(fā)docker平臺(tái),所以挺久沒有更新博客了,今天給大家分享一下,我開發(fā)docker平臺(tái)里如何監(jiān)控資源與進(jìn)行圖像展示的。
默認(rèn)docker 1.5版本有stats命令查看容器的cpu使用率、內(nèi)存使用量與網(wǎng)絡(luò)流量,但此功能有2個(gè)必須:
1、必須是docker 1.5版本
2、必須使用默認(rèn)docker0的網(wǎng)橋(如果你使用ovs這樣非原生的網(wǎng)橋無法獲取數(shù)據(jù)的)
我開發(fā)的監(jiān)控里docker是1.5版本,并且通過使用ifconfig來獲取容器rx或rx量來獲取容器流量,解決了必須使用docker默認(rèn)網(wǎng)橋才可以獲取流量數(shù)據(jù)。
下面是容器資源監(jiān)控效果圖
1、平臺(tái)里資源監(jiān)控界面
2、查看容器yangjing-test的cpu使用率資源監(jiān)控
3、查看內(nèi)存使用量資源監(jiān)控
4、查看容器網(wǎng)絡(luò)流量信息
#p#
下面是監(jiān)控?cái)?shù)據(jù)收集腳本信息
使用python寫的,由于需要往mysql里寫入數(shù)據(jù),所以需要安裝MySQLdb模塊以及服務(wù)端mysql開啟賬號(hào)
- [root@ip-10-10-29-201 code]# cat collect_docker_monitor_data_multi.py
- #!/usr/bin/env python
- #-*- coding: utf-8 -*-
- #author:Deng Lei
- #email: dl528888@gmail.com
- from docker import Client
- import os
- import socket, struct, fcntl
- import etcd
- import MySQLdb
- import re
- import multiprocessing
- import subprocess
- import time
- def get_local_ip(iface = 'em1'):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sockfd = sock.fileno()
- SIOCGIFADDR = 0x8915
- ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
- try:
- res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
- except:
- return None
- ip = struct.unpack('16sH2x4s8x', res)[2]
- return socket.inet_ntoa(ip)
- def docker_container_all():
- docker_container=docker_client.containers(all=True)
- container_name=[]
- container_stop_name=[]
- for i in docker_container:
- container_name.append(i['Names'])
- for b in container_name:
- for c in b:
- container_stop_name.append(c[1::])
- return container_stop_name
- def docker_container_run():
- docker_container=docker_client.containers(all=True)
- container_name=[]
- container_stop_name=[]
- for i in docker_container:
- if re.match('Up',i['Status']):
- container_name.append(i['Names'])
- for b in container_name:
- for c in b:
- container_stop_name.append(c[1::])
- return container_stop_name
- def check_container_stats(name):
- container_collect=docker_client.stats(name)
- old_result=eval(container_collect.next())
- new_result=eval(container_collect.next())
- container_collect.close()
- cpu_total_usage=new_result['cpu_stats']['cpu_usage']['total_usage'] - old_result['cpu_stats']['cpu_usage']['total_usage']
- cpu_system_uasge=new_result['cpu_stats']['system_cpu_usage'] - old_result['cpu_stats']['system_cpu_usage']
- cpu_num=len(old_result['cpu_stats']['cpu_usage']['percpu_usage'])
- cpu_percent=round((float(cpu_total_usage)/float(cpu_system_uasge))*cpu_num*100.0,2)
- mem_usage=new_result['memory_stats']['usage']
- mem_limit=new_result['memory_stats']['limit']
- mem_percent=round(float(mem_usage)/float(mem_limit)*100.0,2)
- #network_rx_packets=new_result['network']['rx_packets']
- #network_tx_packets=new_result['network']['tx_packets']
- network_check_command="""docker exec %s ifconfig eth1|grep bytes|awk -F ':' '{print $2,$3}'|awk -F '(' '{print $1,$2}'|awk -F ')' '{print $1}'|awk '{print "{\\"rx\\":"$1",\\"tx\\":"$2"}"}'"""%name
- network_old_result=eval(((subprocess.Popen(network_check_command,shell=True,stdout=subprocess.PIPE)).stdout.readlines()[0]).strip('\n'))
- time.sleep(1)
- network_new_result=eval(((subprocess.Popen(network_check_command,shell=True,stdout=subprocess.PIPE)).stdout.readlines()[0]).strip('\n'))
- #unit KB
- network_rx_packets=(int(network_new_result['rx']) - int(network_old_result['rx']))/1024
- network_tx_packets=(int(network_new_result['tx']) - int(network_old_result['tx']))/1024
- collect_time=str(new_result['read'].split('.')[0].split('T')[0])+' '+str(new_result['read'].split('.')[0].split('T')[1])
- msg={'Container_name':name,'Cpu_percent':cpu_percent,'Memory_usage':mem_usage,'Memory_limit':mem_limit,'Memory_percent':mem_percent,'Network_rx_packets':network_rx_packets,'Network_tx_packets':network_tx_packets,'Collect_time':collect_time}
- #write_mysql(msg)
- return msg
- def write_mysql(msg):
- container_name=msg['Container_name']
- search_sql="select dc.id from docker_containers dc,docker_physics dp where dc.container_name='%s' and dp.physics_internal_ip='%s';"%(container_name,local_ip)
- n=mysql_cur.execute(search_sql)
- container_id=[int(i[0]) for i in mysql_cur.fetchall()][0]
- insert_sql="insert into docker_monitor(container_id,cpu_percent,memory_usage,memory_limit,memory_percent,network_rx_packets,network_tx_packets,collect_time) values('%s','%s','%s','%s','%s','%s','%s','%s');"%(container_id,msg['Cpu_percent'],msg['Memory_usage'],msg['Memory_limit'],msg['Memory_percent'],msg['Network_rx_packets'],msg['Network_tx_packets'],msg['Collect_time'])
- n=mysql_cur.execute(insert_sql)
- if __name__ == "__main__":
- local_ip=get_local_ip('ovs1')
- if local_ip is None:
- local_ip=get_local_ip('em1')
- etcd_client=etcd.Client(host='127.0.0.1', port=4001)
- docker_client = Client(base_url='unix://var/run/docker.sock', version='1.17')
- mysql_conn=MySQLdb.connect(host='10.10.27.10',user='ops',passwd='1FE@!#@NVE',port=3306,charset="utf8")
- mysql_cur=mysql_conn.cursor()
- mysql_conn.select_db('devops')
- #docker_container_all_name=docker_container_all()
- docker_container_run_name=docker_container_run()
- if len(docker_container_run_name) == 1:
- num=1
- elif len(docker_container_run_name) >= 4 and len(docker_container_run_name) <=8:
- num=4
- elif len(docker_container_run_name) >8 and len(docker_container_run_name) <=15:
- num=8
- elif len(docker_container_run_name) >15 and len(docker_container_run_name) <=30:
- num=20
- else:
- num=40
- pool = multiprocessing.Pool(processes=num)
- scan_result=[]
- #collect container monitor data
- for i in docker_container_run_name:
- pool.apply_async(check_container_stats, (i,))
- scan_result.append(pool.apply_async(check_container_stats, (i,)))
- pool.close()
- pool.join()
- result=[]
- for res in scan_result:
- if res.get() is not None:
- write_mysql(res.get())
- else:
- print 'fail is %s'%res.get()
- mysql_conn.commit()
- mysql_cur.close()
- mysql_conn.close()
下面是把此腳本放入crontab里每分鐘收集一下
- */1 * * * * python /root/collect_docker_monitor_data_multi.py >>/root/docker_log/docker_monitor.log 2>&1
另外說明一下,上面的監(jiān)控?cái)?shù)據(jù)圖形化使用highstock,使用ajax進(jìn)行動(dòng)態(tài)加載數(shù)據(jù),每次獲取容器所有時(shí)間監(jiān)控?cái)?shù)據(jù)。有問題請(qǐng)留言。