docker高级应用之资源监控

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介:

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

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

1、必须是docker 1.5版本

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

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

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

1、平台里资源监控界面

wKiom1U0bCPzgt01AAFNUwAKwiw657.jpg

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

wKiom1U0bGjjlqoEAAGYHE6vta0864.jpg

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

wKioL1U0bfyz4qP5AAGV0vt88-k050.jpg

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

wKiom1U0bNuj1dw4AAHrnfjn2rA970.jpg

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
[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  in  docker_container:
         container_name.append(i[ 'Names' ])
     for  in  container_name:
         for  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  in  docker_container:
         if  re.match( 'Up' ,i[ 'Status' ]):
             container_name.append(i[ 'Names' ])
     for  in  container_name:
         for  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  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  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
* /1  * * * * python  /root/collect_docker_monitor_data_multi .py >> /root/docker_log/docker_monitor .log 2>&1

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







 本文转自 reinxu 51CTO博客,原文链接:http://blog.51cto.com/dl528888/1635951,如需转载请自行联系原作者
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
3月前
|
Kubernetes Docker Python
Docker 与 Kubernetes 容器化部署核心技术及企业级应用实践全方案解析
本文详解Docker与Kubernetes容器化技术,涵盖概念原理、环境搭建、镜像构建、应用部署及监控扩展,助你掌握企业级容器化方案,提升应用开发与运维效率。
734 108
|
2月前
|
Prometheus 监控 Cloud Native
基于docker搭建监控系统&日志收集
Prometheus 是一款由 SoundCloud 开发的开源监控报警系统及时序数据库(TSDB),支持多维数据模型和灵活查询语言,适用于大规模集群监控。它通过 HTTP 拉取数据,支持服务发现、多种图表展示(如 Grafana),并可结合 Loki 实现日志聚合。本文介绍其架构、部署及与 Docker 集成的监控方案。
332 122
基于docker搭建监控系统&日志收集
|
1月前
|
监控 Kubernetes 安全
还没搞懂Docker? Docker容器技术实战指南 ! 从入门到企业级应用 !
蒋星熠Jaxonic,技术探索者,以代码为笔,在二进制星河中书写极客诗篇。专注Docker与容器化实践,分享从入门到企业级应用的深度经验,助力开发者乘风破浪,驶向云原生新世界。
还没搞懂Docker? Docker容器技术实战指南 ! 从入门到企业级应用 !
|
2月前
|
前端开发 JavaScript 应用服务中间件
在Docker部署的前端应用中使用动态环境变量
以上步骤展示了如何在 Docker 配置过程中处理并注入环墨遁形成可执行操作流程,并确保最终用户能够无缝地与之交互而无须关心背后复杂性。
167 13
|
4月前
|
存储 监控 Java
如何对迁移到Docker容器中的应用进行性能优化?
如何对迁移到Docker容器中的应用进行性能优化?
331 59
|
6月前
|
Prometheus 监控 Cloud Native
除了Prometheus,还有哪些工具可以监控Docker Swarm集群的资源使用情况?
除了Prometheus,还有哪些工具可以监控Docker Swarm集群的资源使用情况?
521 79
|
7月前
|
监控 Java Go
无感改造,完美监控:Docker 多阶段构建 Go 应用无侵入观测
本文将介绍一种基于 Docker 多阶段构建的无侵入 Golang 应用观测方法,通过此方法用户无需对 Golang 应用源代码或者编译指令做任何改造,即可零成本为 Golang 应用注入可观测能力。
390 85