当前位置: > Linux服务器 > Docker >

Docker高级应用之资源监控

时间:2015-04-27 15:56来源:51cto.com 作者:IT

最近忙着开发docker平台,所以挺久没有更新博客了,今天给大家分享一下,我开发docker平台里如何监控资源与进行图像展示的。

默认docker 1.5版本有stats命令查看容器的cpu使用率、内存使用量与网络流量,但此功能有2个必须:

1、必须是docker 1.5版本

2、必须使用默认docker0的网桥(如果你使用ovs这样非原生的网桥无法获取数据的)

我开发的监控里docker是1.5版本,并且通过使用ifconfig来获取容器rx或rx量来获取容器流量,解决了必须使用docker默认网桥才可以获取流量数据。

下面是容器资源监控效果图

1、平台里资源监控界面

 

Docker高级应用之资源监控

2、查看容器yangjing-test的cpu使用率资源监控

 

Docker高级应用之资源监控

3、查看内存使用量资源监控

 

Docker高级应用之资源监控

4、查看容器网络流量信息

 

Docker高级应用之资源监控

 

下面是监控数据收集脚本信息

使用python写的,由于需要往mysql里写入数据,所以需要安装MySQLdb模块以及服务端mysql开启账号


  1. [root@ip-10-10-29-201 code]# cat collect_docker_monitor_data_multi.py 
  2. #!/usr/bin/env python 
  3. #-*- coding: utf-8 -*- 
  4. #author:Deng Lei 
  5. #email: dl528888@gmail.com 
  6. from docker import Client 
  7. import os 
  8. import socket, struct, fcntl 
  9. import etcd 
  10. import MySQLdb 
  11. import re 
  12. import multiprocessing 
  13. import subprocess 
  14. import time 
  15. def get_local_ip(iface = 'em1'): 
  16.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  17.     sockfd = sock.fileno() 
  18.     SIOCGIFADDR = 0x8915 
  19.     ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14) 
  20.     try: 
  21.         res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq) 
  22.     except: 
  23.         return None 
  24.     ip = struct.unpack('16sH2x4s8x', res)[2] 
  25.     return socket.inet_ntoa(ip) 
  26. def docker_container_all(): 
  27.     docker_container=docker_client.containers(all=True) 
  28.     container_name=[] 
  29.     container_stop_name=[] 
  30.     for i in docker_container: 
  31.         container_name.append(i['Names']) 
  32.     for b in container_name: 
  33.         for c in b: 
  34.             container_stop_name.append(c[1::]) 
  35.     return container_stop_name 
  36. def docker_container_run(): 
  37.     docker_container=docker_client.containers(all=True) 
  38.     container_name=[] 
  39.     container_stop_name=[] 
  40.     for i in docker_container: 
  41.         if re.match('Up',i['Status']): 
  42.             container_name.append(i['Names']) 
  43.     for b in container_name: 
  44.         for c in b: 
  45.             container_stop_name.append(c[1::]) 
  46.     return container_stop_name 
  47. def check_container_stats(name): 
  48.     container_collect=docker_client.stats(name) 
  49.     old_result=eval(container_collect.next()) 
  50.     new_result=eval(container_collect.next()) 
  51.     container_collect.close() 
  52.     cpu_total_usage=new_result['cpu_stats']['cpu_usage']['total_usage'] - old_result['cpu_stats']['cpu_usage']['total_usage'] 
  53.     cpu_system_uasge=new_result['cpu_stats']['system_cpu_usage'] - old_result['cpu_stats']['system_cpu_usage'] 
  54.     cpu_num=len(old_result['cpu_stats']['cpu_usage']['percpu_usage']) 
  55.     cpu_percent=round((float(cpu_total_usage)/float(cpu_system_uasge))*cpu_num*100.0,2) 
  56.     mem_usage=new_result['memory_stats']['usage'] 
  57.     mem_limit=new_result['memory_stats']['limit'] 
  58.     mem_percent=round(float(mem_usage)/float(mem_limit)*100.0,2) 
  59.     #network_rx_packets=new_result['network']['rx_packets'] 
  60.     #network_tx_packets=new_result['network']['tx_packets'] 
  61.     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 
  62.     network_old_result=eval(((subprocess.Popen(network_check_command,shell=True,stdout=subprocess.PIPE)).stdout.readlines()[0]).strip('\n')) 
  63.     time.sleep(1) 
  64.     network_new_result=eval(((subprocess.Popen(network_check_command,shell=True,stdout=subprocess.PIPE)).stdout.readlines()[0]).strip('\n')) 
  65.     #unit KB 
  66.     network_rx_packets=(int(network_new_result['rx']) - int(network_old_result['rx']))/1024 
  67.     network_tx_packets=(int(network_new_result['tx']) - int(network_old_result['tx']))/1024 
  68.     collect_time=str(new_result['read'].split('.')[0].split('T')[0])+' '+str(new_result['read'].split('.')[0].split('T')[1]) 
  69.     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} 
  70.     #write_mysql(msg) 
  71.     return msg 
  72. def write_mysql(msg): 
  73.     container_name=msg['Container_name'] 
  74.     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) 
  75.     n=mysql_cur.execute(search_sql) 
  76.     container_id=[int(i[0]) for i in mysql_cur.fetchall()][0] 
  77.     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']) 
  78.     n=mysql_cur.execute(insert_sql) 
  79. if __name__ == "__main__": 
  80.     local_ip=get_local_ip('ovs1') 
  81.     if local_ip is None: 
  82.   local_ip=get_local_ip('em1') 
  83.     etcd_client=etcd.Client(host='127.0.0.1', port=4001) 
  84.     docker_client = Client(base_url='unix://var/run/docker.sock', version='1.17') 
  85.     mysql_conn=MySQLdb.connect(host='10.10.27.10',user='ops',passwd='1FE@!#@NVE',port=3306,charset="utf8") 
  86.     mysql_cur=mysql_conn.cursor() 
  87.     mysql_conn.select_db('devops') 
  88.     #docker_container_all_name=docker_container_all() 
  89.     docker_container_run_name=docker_container_run() 
  90.     if len(docker_container_run_name) == 1: 
  91.   num=1 
  92.     elif len(docker_container_run_name) >= 4 and len(docker_container_run_name) <=8: 
  93.   num=4 
  94.     elif len(docker_container_run_name) >8 and len(docker_container_run_name) <=15: 
  95.   num=8 
  96.     elif len(docker_container_run_name) >15 and len(docker_container_run_name) <=30: 
  97.   num=20 
  98.     else: 
  99.   num=40 
  100.     pool = multiprocessing.Pool(processes=num) 
  101.     scan_result=[] 
  102.     #collect container monitor data 
  103.     for i in docker_container_run_name: 
  104.         pool.apply_async(check_container_stats, (i,)) 
  105.         scan_result.append(pool.apply_async(check_container_stats, (i,))) 
  106.     pool.close() 
  107.     pool.join() 
  108.     result=[] 
  109.     for res in scan_result: 
  110.         if res.get() is not None: 
  111.       write_mysql(res.get()) 
  112.   else: 
  113.       print 'fail is %s'%res.get() 
  114.     mysql_conn.commit() 
  115.     mysql_cur.close() 
  116.     mysql_conn.close() 

下面是把此脚本放入crontab里每分钟收集一下


  1. */1 * * * * python /root/collect_docker_monitor_data_multi.py >>/root/docker_log/docker_monitor.log 2>&1 

另外说明一下,上面的监控数据图形化使用highstock,使用ajax进行动态加载数据,每次获取容器所有时间监控数据。有问题请留言。



(责任编辑:IT)
------分隔线----------------------------