现在有很多的开源的Docker监控方案的实现,我们可以很容易的搭建一套监控系统出来;但是如果你有定制化的需求,则需要自己去实现;那么我们该怎么实现呢?需要监控哪些指标呢?这些指标又是什么含义呢?应该怎样去收集呢?本文我们来一起探讨。
这里我不会介绍整个监控系统的架构,也不会去分别介绍存储、告警、展示、通知等等这些模块的实现,因为现在的开源的监控系统基本都包括这些,只会把重点放在Docker的指标上,所以内容会有些干。接触时间也不算太长,如果有错误的地方恳请指正。
我们把需要监控的对象分为三层,分别是应用层、系统层和虚拟那一层;这里我们主要关注放在在系统层(CPU、memory、IO等等),以及虚拟层(可能包括容器的OOM,运行时间等等),所以我们主要探讨一下对于这方面的监控。
一般来说,对于Docker的监控,有三种最主要的方式去获取性能指标,分别是:CGroup、Docke命令行以及Docker的API。
对于CGroup方式,就是通过CGroup的文件来读取这些指标,一般来说在/sys/fs/cgroup目录下面,例如CPU相关的指标/sys/fs/cgroup/cpuacct/docker/$CONTAINER_ID/cpuacct.stat;这里的CONTAINER_ID就是容器的ID。
对于Docker命令行,其实就是通过docker stats来获取:
$ docker stats $CONTAINER_ID
CONTAINER CPU % MEM USAGE/LIMIT MEM % NET I/O BLOCK I/O
ecb37227ac84 0.12% 71.53 MiB/490 MiB 14.60% 900.2 MB/275.5 MB 266.8 MB/872.7 MB
和上面的命令行一样,Docker API也能实时采集上面的这些指标,有两种方式来开启开启Docker的API功能,分别是添加这样的参数DOCKER_OPTS="-H=unix:///var/run/docker.sock -H=0.0.0.0:6732"来分别开启unix sock和http,其中unix sock方式是默认的。
$ echo -ne "GET /containers/$CONTAINER_ID/stats HTTP/1.1\r\n\r\n" | sudo nc -U /var/run/docker.sock
如果开放了接口,也可以直接通过接口访问,返回是一个很长的json,里面包含了CPU、memory等方面的指标。
那么对这三种采集方式来说,哪一种是最合适的呢,从排除法来看,命令行的方式获取的指标值比较有限,只能拿到基本的CPU、memory使用状况,更详细的没有,所以这个方案只适合做一个粗略的监控,有对于有些时候的排障来说,可能并不够用;再来看看Docker API的方式,这种方式需要每次发送http请求,而且有多少container就发多少次,这个开销也是不小的,所以这个方案最简单但是我们仍然没有考虑;显而易见,最后我们选择了从CGroup文件的方式来获取,下面我们就来细细说一下需要监控哪些指标,以及怎么来采集。
user CPU:CPU用户进程的时间百分比
system CPU:CPU执行系统调用的时间百分比
CPU util:总的CPU使用率
throttling (count):容器的CPU被限制的次数
throttling (time):容器的CPU使用率被限制的总时间
$ cat /sys/fs/cgroup/cpuacct/docker/$CONTAINER_ID/cpuacct.stat
> user 2441
> system 985
在x86系统中,上面的时间是按10毫秒增加,所以上面的CPU在用户进程上消耗24.41秒,在系统调用上消耗9.85秒。
$ cat /sys/fs/cgroup/cpuacct/docker/$CONTAINER_ID/cpuacct.usage_percpu
> 44154016900
上面是单个CPU使用的时间,如果容器使用的是多核的CPU,那么下面可以获取所有CPU的总的时间:
$ cat /sys/fs/cgroup/cpuacct/docker/$CONTAINER_ID/cpuacct.usage
> 44154016900
对于Throttled,可以在cpu.stat中获取:
$ cat /sys/fs/cgroup/cpu/docker/$CONTAINER_ID/cpu.stat
> nr_periods 565
> nr_throttled 559
> throttled_time 11219582971
我们知道在Docker中对CPU的限制方式有几种,可以通过--cpu-shares,--cpu-period和--cpu-quota,--cpuset-cpus来配置,具体细节这里不赘述。现在使用最多的方式是--cpu-period和--cpu-quota结合的方式,这时候CPU使用率的上限由两者共同决定,比如说A容器配置的--cpu-period=100000 --cpu-quota=50000,那么A容器就可以最多使用50%个CPU资源,如果配置的--cpu-quota=200000,那就可以使用200%个CPU资源。所有对采集到的CPU used的绝对值没有意义,还需要参考上限。还是这个例子--cpu-period=100000 --cpu-quota=50000,如果容器试图在0.1秒内使用超过0.05秒,则throttled就会触发,所有throttled的count和time是衡量CPU是否达到瓶颈的最直观指标。
另外,不像传统的host,Docker不需要采集CPU的nice,idle,iowait和irq时间。