找回密码
 注册
查看: 4279|回复: 1

docker监控脚本

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2018-6-20 19:05:42 | 显示全部楼层 |阅读模式
监控套件有三个脚本,一个是自动发现主机上的docker容器脚本,另一个是用python写的获取每个docker容器的系统状态,包括CPU使用率,内存使用率以及网络资源使用率,最后这个脚本添加了一些我公司常用的应用的状态监控,包括应用占用内存,cpu资源以及进程的存活状态,至于读者们需要监控其他docker里面的应用,可以依照我的脚本来进行修改。
需要编辑自动发现docker中容器个数的脚本
# cat /usr/local/zabbix/scripts/docker_low_discovery.sh

4 o- x0 y: g; U3 o6 k  y5 D' P  q
#!/bin/bash
9 p$ \+ S, H7 L! g! u
#Fucation:docker low-level discovery

' h! [# ?0 w6 v9 t# ?/ e! t3 l3 m) h
docker() {
. l) \, u% q7 l1 ?+ I# F
            port=($(sudo docker ps -a|grep -v "CONTAINER ID"|awk '{print $NF}'))
9 m  O: W. B! ^
            printf '{\n'

0 p0 k. y  K3 r
            printf '\t"data":[\n'

' t" y7 q, s% Q+ q; [
               for key in ${!port[@]}

0 x! D) ]" Y7 L' G& N$ {& }9 r+ B7 A  K
                   do
9 p6 n' a* l; B8 U4 p( \
                       if [[ "${#port[@]}" -gt 1 && "${key}" -ne "$((${#port[@]}-1))" ]];then
5 O- N, B* l; R
                          printf '\t {\n'

! C3 O7 e( h6 {( W2 S2 u7 \
                          printf "\t\t\t\"{#CONTAINERNAME}\":\"${port[${key}]}\"},\n"

" @4 _  U6 B1 p& T
  
% A; R' V- e) q: O
                     else [[ "${key}" -eq "((${#port[@]}-1))" ]]
. j8 i$ E0 v# H; l' U( q
                          printf '\t {\n'

, U4 q! ^# K/ G) G8 J
                          printf "\t\t\t\"{#CONTAINERNAME}\":\"${port[${key}]}\"}\n"

- v9 N" _1 ^3 ~8 ?$ k  ]- r* X
  

6 J- z) [0 O/ X1 T
                       fi

& s& F# u1 N$ Z) y& r
               done
4 K% f, \! W6 ^" G( D& R: Q6 F6 H
  

# ^' t4 l" {6 p5 K. C
                          printf '\t ]\n'

; D8 y  K; L. \" u
                          printf '}\n'

' I7 H( Z0 h! W( l3 ~# n9 Z  M- _
}

- T, J5 p/ N  \' k
case $1 in
7 {- Z; K! x7 M# m# m4 k
docker)

$ T8 \9 e/ h% u3 y
docker

7 Z& c8 f$ d( f
;;
( H- |, N; ~' |6 z; `4 g
*)

9 C/ F) V* c( Y0 R. F
echo "Usage:`basename $0` {docker}"
* {; x8 F! l3 w5 ?- m) a
;;
/ Z5 T6 B( i+ {/ P* E4 C/ J2 o0 [3 X, i
esac
上面这个脚本是用来获取到docker里面应用的容器,并对其进行json化输出的,效果如下:
' y# ~  g; g, V
# sh /usr/local/zabbix/scripts/docker_low_discovery.sh docker

6 l- h: ?0 ~" A4 R
{
* R6 B, \) _6 G/ T3 o. U' D
"data":[

0 \: k6 {0 S& P2 N
{

7 ]; W7 @0 ~( Q! I, f- k3 H
"{#CONTAINERNAME}":"hopeful_brown"},

% f; F0 y7 e. ]7 F
{

; M9 U: R, n7 [/ X$ ^
"{#CONTAINERNAME}":"happy_einstein"}
: z# f# @) Y" U5 `+ m- |
3 r/ f' _5 O2 x* {1 M- _5 R
}

/ I; _! y- o( v  U, G
这样就能被zabbix_server获取到了,然后是python脚本,使用python获取docker的参数需要使用一个扩展包,可以通过pip或者easy_install安装docker-py扩展:
pip install docker-py或者easy_install docker-py或者不想这样安装的话可以去python官网下载docker-py的安装包,解压后使用docker docker-py-1.4.0/setup.py install命令安装,扩展包我将会打包放在附件中。

/ S' s( ~5 y$ t- B+ p3 v
- o0 c/ V. w' y0 d, A4 I
# cat /usr/local/zabbix/scripts/docker_monitor.py
5 S) A: ^' L# ]- q; k8 e
#!/usr/bin/env python
" \& n+ f7 u- M. {
#-*- coding: utf-8 -*-
4 @# K7 d6 I4 m) s) i
#author:Xianglin Hu
1 m4 X! D$ Y- n! @

7 J& S' p/ Y0 d3 i: f, l; X+ A
from docker import Client

4 N8 l0 P5 b. B0 v  t1 {
import sys

8 U5 }) P& g0 @/ e
import subprocess
% L8 M& c& N( n& u
import os

$ @" l: \  D1 k' i4 C  C+ J5 A0 z. p/ _
def check_container_stats(container_name,collect_item):
8 n7 H! m: _! b
    container_collect=docker_client.stats(container_name)
0 Q4 L% y; Y8 U: A& C3 d/ s# q/ Z: r
    old_result=eval(container_collect.next())
* a- p# t8 Q1 i% A- R
    new_result=eval(container_collect.next())

: ]+ \* i/ S( K& ?; e
    container_collect.close()

! a( A+ ]8 m4 k3 A6 }$ F7 L! R
    if collect_item == 'cpu_total_usage':
1 r5 ^2 S) k0 v& ^, T0 x
        result=new_result['cpu_stats']['cpu_usage']['total_usage'] - old_result['cpu_stats']['cpu_usage']['total_usage']

$ \7 F1 z0 f0 [1 R. n; p
    elif collect_item == 'cpu_system_usage':
; u, S+ W  b& D1 `1 J
        result=new_result['cpu_stats']['system_cpu_usage'] - old_result['cpu_stats']['system_cpu_usage']

+ J+ W3 u1 E4 V$ j. K  M
    elif collect_item == 'cpu_percent':

; x$ d; ~( l4 j0 |& P
        cpu_total_usage=new_result['cpu_stats']['cpu_usage']['total_usage'] - old_result['cpu_stats']['cpu_usage']['total_usage']
% B6 m" C/ ?2 P5 @
        cpu_system_uasge=new_result['cpu_stats']['system_cpu_usage'] - old_result['cpu_stats']['system_cpu_usage']

2 X$ [5 _0 R" P, M/ }
        cpu_num=len(old_result['cpu_stats']['cpu_usage']['percpu_usage'])
8 e+ Q. {/ f9 j& C0 [' I
        result=round((float(cpu_total_usage)/float(cpu_system_uasge))*cpu_num*100.0,2)
8 U: L& d! j" P+ ^( @2 H5 [
    elif collect_item == 'mem_usage':
: k2 H4 s# I* {" ^5 Q# H
        result=new_result['memory_stats']['usage']

( y  ]! i) g  n+ L
    elif collect_item == 'mem_limit':
5 u& Q3 X( R' w- F, B
        result=new_result['memory_stats']['limit']
, z2 Y; S8 m7 Q4 B  V
    elif collect_item == 'mem_percent':

- @" R' J& V7 ]0 S5 o& @! b
        mem_usage=new_result['memory_stats']['usage']
1 P. r5 `* n3 D. k, m
        mem_limit=new_result['memory_stats']['limit']
" O/ O% f6 T3 y+ M% g, r
        result=round(float(mem_usage)/float(mem_limit)*100.0,2)
/ K; ^3 r: `! {$ j5 x
    elif collect_item == 'network_rx_bytes':
$ m2 r9 ^- u4 S7 ~# p6 ^
        network_check_command="""sudo /usr/bin/docker exec %s cat /proc/net/dev|sed -n 3p|awk '{print $2,$10}'"""%container_name
% n$ w! h2 l+ ^) J- g  f+ B7 S; C
        result=os.popen(network_check_command).read().split()[0]

: H7 p! n, z& p
    elif collect_item == 'network_tx_bytes':

( ]5 p! s/ t6 t4 P
        network_check_command="""sudo /usr/bin/docker exec %s cat /proc/net/dev|sed -n 3p|awk '{print $2,$10}'"""%container_name
" j* A! P; V: G: P! Q3 K
        result=os.popen(network_check_command).read().split()[1]
, L- L* W' s3 N7 ^2 d$ J2 N+ _
    return result
! a) e& g/ i$ k# e) M
if __name__ == "__main__":
" r5 z( E' \0 J' N0 B- i8 b5 M
    docker_client = Client(base_url='unix://var/run/docker.sock', version='1.17')
' q  Q) v3 _3 k! o0 y8 c+ i
    container_name=sys.argv[1]

. a9 N+ P, V! S6 k- u  ?9 r6 w" E' V
    collect_item=sys.argv[2]
/ A9 H* F3 w' H" ^- }: T
    print check_container_stats(container_name,collect_item)
" t" U0 ]) p7 y
这里面使用到了docker里面的Client类,获取到某个docker容器的当前状态信息,然后进行运算,返回运算结果。但是容器当前信息那个dict中的network的key获取到的信息不准确,于是我使用了docker exec命令来获取docker容器内部的网络流量信息。这也是我在大神的基础上进行改进的地方,这里的改进将python脚本的执行时间缩短了,将有助于server获取duocker容器信息时减少长连接的数量,提升zabbix_server的性能。这里的docker exec命令将会在下一个脚本中大量使用来获取docker容器中的应用状态信息。

% A! t( L3 E6 m/ p6 M+ h7 L# w
下面是获取容器应用状态信息的脚本:
# cat docker_processmonitor.sh
6 n7 Y4 O+ J) }7 W( Q+ c" J
#!/bin/bash
7 y, [/ q  l$ d* Q/ e
#license:GPL
" O) B6 N) o5 {1 V1 n9 ?
#mail:a714585725@qq.com

- g% A: I9 k* H% L( y
#date:2015.09.22
3 [+ `" p/ K9 A* U
processmem(){
" m% k9 s, C: c% c  C6 g
        sudo /usr/bin/docker exec $1 ps aux|grep $2|grep -v "grep"|grep -v "processstatus.sh"|awk '{sum+=$6}; END{print sum}'
' j4 O- ]& E! P
}
, ~& H$ b$ t$ [) Q& d/ v8 s
processcpu(){
+ c  @, j0 h# A! ?* \! }1 [* V
        sudo /usr/bin/docker exec $1 ps aux|grep $2|grep -v "grep"|grep -v "processstatus.sh"|awk '{sum+=$3}; END{print sum}'
: Y9 |& O9 i/ o2 x% N3 n, m% S* Q
}
# ^3 P4 H& ^/ ^
processport(){

; h) d3 V; \, A: ]1 h8 M
        sudo /usr/bin/docker exec $1 ss -antlp|grep $2|grep LISTEN|wc -l

2 W2 o8 p: a1 T: c; r# A
}
" ?, X7 y1 j5 E. U
case "$3" in

' r: w6 ]+ H. e% M% y) N1 ^8 b
mem)
7 A# ~/ W0 `8 D/ H* Y
processmem $1 $2
' t3 w6 s* O- b: d. g
;;
3 x$ k$ O) N6 ~! C4 d
cpu)
) z. [: ]" l; s4 `% ]
processcpu $1 $2
  `1 s: B9 N: l. G: U" H
;;

7 \8 Y1 ~7 ]- Y2 G* S7 b; o
port)

& a: ]5 @6 j- J1 y% s
processport $1 $2

6 {: [# E- b4 S4 _9 `+ n; t8 r/ e
;;
/ q+ ?+ a- h  M' x
*)

! V2 f2 @5 J" y9 g* O
echo "Usage: $0 {docker_containername}{processname}{mem|cpu|port}"
" A" v) c5 X7 n7 ?, e) l8 f
;;

0 ?- K+ t* k7 e% Q; q
esac

* [- \& r4 T/ M# D. ]0 {* V

' _  G; ^6 _7 r/ O
这个脚本其实没啥说的,从我以前写的那个脚本上面修改来的,使用了一个case来判断需要获取的docker容器的名称以及该容器中应用的状态信息,只不过这里获取docker容器状态信息使用的是docker exec命令来进行获取。另外这里面添加了对于应用是否存活的状态监测,那就是检测该应用是否侦听了网络端口,假如该应用侦听的网络端口个数为0的话,可以认为该应用存在异常。这些应用只是我公司使用比较多的应用,各位读者可以根据自己需求修改相应应用的监控。
由于docker是以root权限来启用的,而zabbix监控是使用zabbix用户来执行的,所以需要给予zabbix用户相应的权限,需要编辑visudo:
echo "zabbix ALL=(root) NOPASSWD:/bin/docker,/usr/bin/python,/usr/local/zabbix/scripts/docker_monitor.py,/usr/local/zabbix/scripts/docker_low_discovery.sh,/usr/local/zabbix/scripts/docker_processmonitor.sh">>/etc/sudoers
并且还需要注释掉这条记录:#Defaults    requiretty(PS:注意,这条记录是要求使用sudo命令时需要有终端界面,注释掉这一条之后就可以不需要终端执行sudo命令了。)

7 V. g" n1 q6 p: F, ~4 y6 \& w) v
# tail -3 /usr/local/zabbix/etc/zabbix_agentd.conf
, O4 Y4 k2 S1 p8 {/ ?
UserParameter=docker_low_discovery
  • ,/bin/bash /usr/local/zabbix/scripts/docker_low_discovery.sh $1
  • + K" q1 C& P+ \
    UserParameter=docker_stats
  • ,sudo /usr/bin/python /usr/local/zabbix/scripts/docker_monitor.py $1 $2
  • * \( t+ e! h% V# f' X$ J5 O$ e
    UserParameter=docker_process
  • ,/bin/bash /usr/local/zabbix/scripts/docker_processmonitor.sh $1 $2  $3
  • : A  x0 K9 J, b2 |1 q- J; E* C4 e
    6 ?( m- {& n; C; p1 [% ~; p& y
    保存配置并重启zabbix_agentd服务,然后修改脚本的属主属组以及权限:
    chown zabbix.zabbix /usr/local/zabbix/scripts/*
    chmod 755 /usr/local/zabbix/scripts/*
    然后可以在zabbix_server端测试是否能够获取到相应的数据:
    [root@test1 ~]# /usr/local/zabbix-2.4.4/bin/zabbix_get -s x.x.x.x -k"docker_low_discovery[docker]"

    * b: h  f# I0 w5 v! n& S
    {
    , ?3 t/ G; y  k2 S6 }
    "data":[
    8 z7 c& h2 a, R2 F$ @
    {
    ; K6 w/ J  V' q) G" m- Q
    "{#CONTAINERNAME}":"hopeful_brown"},

    ) A! {$ K& S! M/ M* }
    {
    3 f% e  L5 g; V. }2 U
    "{#CONTAINERNAME}":"happy_einstein"}
    6 @2 c8 r" Q6 S  J
    ) N2 J0 O3 t6 Y& p( Z
    }
    4 I: i5 ?; ]$ t
    [root@test1 ~]# /usr/local/zabbix-2.4.4/bin/zabbix_get -s x.x.x.x -k"docker_stats[happy_einstein,network_tx_bytes]"
    3 r% m9 N. v' J  q
    9664252
    9 d( B& x$ R/ b4 t" S
    [root@test1 ~]# /usr/local/zabbix-2.4.4/bin/zabbix_get -s x.x.x.x -k"docker_process[happy_einstein,nginx,port]"
    4 Z# K# u5 I- {2 B4 n
    2
      E  Q# F6 e' K" f& a& v' w+ _& J8 s

    & w; M: h# f, g6 a6 M7 X

    1

    主题

    0

    回帖

    12

    积分

    管理员

    积分
    12
    QQ
     楼主| 发表于 2018-6-20 19:10:02 | 显示全部楼层
    这里的IP地址我就用x.x.x.x代替了,这里应该填写客户端的IP地址。如上所示,能够正确获取到agentd的数据以后,然后就需要在zabbix_server这边配置监控模版了,关于监控模版的配置我在之前的文章中提及了很多次,相信大家应该都不会陌生了,这回就不详细描述模板的建立了,稍后我会将模板打包一起上传至附件中,这个模板目前还是半成品,各位可以根据模板进行修改,可以根据你们的需求来做,下面,演示一下监控出来的效果(PS:只是在测试环境小规模的部署,项目还不错,于是没有做成筛选出来。)
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

    GMT+8, 2026-6-12 00:30 , Processed in 0.026333 second(s), 23 queries .

    Powered by Discuz! X5.0

    © 2001-2026 Discuz! Team.

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