过去的一年中,关于 Docker 的话题从未断过,而现在,从尝试 Docker 到最终决定使用 Docker 的转化率依然在逐步升高,关于 Docker 的讨论更是有增无减。另外一方面,你们的注意力也渐渐从 “Docker 是什么”转移到“实践 Docker”与“监控 Docker”上。html
本文转自刘斌博文「如何选择 Docker 监控方案 」,文中刘斌从技术的角度深刻解释了 Docker 监控的数据采集原理,介绍了现有开源的监控方案,以及可以对 Docker 进行监控功能的主流 SaaS 服务工具。ios
##斌哥是谁? 刘斌,拥有 10 多年编程经验,曾参与翻译过「第一本 Docker 书」、「GitHub 入门与实践」、「Web 应用安全权威指南」等多本技术书籍,主讲过「Docker入门与实践 」课程的 Cloud Insight 后台工程师。sql
##为何监控,监控什么内容? 做为一名工程师,咱们要对本身系统的运行状态了如指掌,有问题及时发现,而不是让用户先发现系统不能使用,打电话找客服,再反映到开发。这个过程很长,并且对工程师来讲,是一件比较没面子的事情。docker
当领导问咱们这个月的 MySQL 并发什么状况?slowsql 处于什么水平,平均响应时间超过 200ms 的占比有百分之多少的时候,回答不出来这个问题很尴尬。尽管你工做很辛苦,可是却没有拿得出来的成果。不能由于暂时没出问题就掉以轻心,换位想一想,站在领导的角度,领导什么都不干,你提案,他签字,出了谁背锅?shell
监控目的数据库
减小宕机时间编程
扩展和性能管理缓存
资源计划安全
识别异常事件服务器
故障排除、分析
为何须要监控咱们的服务?其中有一些显而易见的缘由,好比须要监控工具来提醒服务故障,好比经过监控服务的负载来决定扩容或缩容。若是机器广泛负载不高,则能够考虑缩减一下机器规模,若是数据库链接常常维持在一个高位水平,则能够考虑一下是否能够进行拆库处理,优化一下架构。
##Docker监控面临的挑战
Docker特色
微服务 集群
全方位
容器为咱们的开发和运维带来了更多的方向和可能性,咱们也须要一种现代的监控方案来应对这种变化。
随着不可变基础设施概念的普及,云原生应用的兴起,云计算组件已经愈来愈像搭建玩具的积木块。不少基础设施生命周期变短,不光容器如此,云主机、VM也是。
在云计算出现以前,一台机器可能使用三、5年甚至更长都不须要重装,主机名也不会变,而如今,可能升级一个版本,就要重建一个云主机或从新启动一个容器。监控对象动态变化,并且很是频繁。即便所有实现自动化,也会在负载和复杂度方面带来不利影响。
监控还有助于进行内部统制,尤为是对安全比较敏感的行业,好比证券、银行等。好比服务器受到攻击时,咱们须要分析事件,找到根本缘由,识别相似攻击,发现未知的被攻击系统,甚至完成取证等工做。
集群的出现,使应用的拓扑结构也变得复杂,不一样应用的指标和日志格式也不统一,再加上要考虑应对多租户的问题,这些都给监控带来了新挑战。
传统的监控内包括对主机、网络和应用的监控,可是Docker出现以后,容器这一层很容易被忽略,成为三无论地区,即监控的盲点。
有人说,容器不就是个普通的OS么?装个Zabbix的探针不就好了么?Docker host和Docker 容器都要装 Zabbix探针……其实问题不少。
除了容器内部看到的cpu内存状况不许以外,并且容器生命周期短,重启以后host名,ip地址都会变,因此最好在Docker host上安装Zabbix agent。
若是每一个容器都像OS那样监控,则metric数量将会很是巨大,并且这些数据极可能几分钟以后就无效率了(容器已经中止)。容器生命周期短暂,一旦容器结束运行,以前收集的数据将再也不有任何意义。
主要的解决方式就是以App或者Service为单位进行监控(经过Tag等方式)。
##Docker 监控技术基础
docker stats
Remote API
伪文件系统
咱们能够经过 docker stats 命令或者Remote API以及Linux的伪文件系统来获取容器的性能指标。
使用API的话须要注意一下,那就是不要给Docker daemon带来性能负担。若是你一台主机有200个容器,若是很是频繁的采集系统性能可能会大量占据CPU时间。
最好的方式应该就是使用伪文件系统。若是你只是想经过shell来采集性能数据,则 docker stats 多是最简单的方式了。
docker stats 命令
该命令默认以流式方式输出,若是想打印出最新的数据并当即退出,可使用 no-stream=true 参数。
文件位置大概在(跟系统有关,这是 Systemd 的例子):
Docker各个版本对这三种方式的支持程度不一样,取得metric的方式和详细程度也不一样,其中网络metric是在1.6.1以后才能从伪文件系统获得。
Memory
内存的不少性能指标都来自于 memory.stat 文件:
前面的不带total的指标,表示的是该cgroup中的process所使用的、不包括子cgroup在内的内存量,而total开头的指标则包含了这些进程使用的包括子cgroup数据。这里咱们看到的数据都是同样的,因为这里并无子cgroup。
两个比较重要的指标:
进程的全部数据堆、栈和memory map等。rss能够进一步分类为active和inactive(activeanon and inactiveanon)。在内存不够须要swap一部分到磁盘的时候,会选择inactive 的rss进行swap 。
缓存到内存中的硬盘文件的大小。好比你读写文件的时候,或者使用mapped file的时候,这个内存都会增长。这类内存也能够再细分为active和inactive的cache,即activefile和inactivefile。若是系统须要更多内存,则inactive的cache会被优先重用。
CPU
可是比较遗憾,Docker 不会报告nice,idle和iowait等事件。
System也叫kernel时间,主要是系统调用所耗费的部分,而user则指本身程序的耗费CPU,若是User时间高,则须要好好检查下本身的程序是否有问题,可能须要进行优化。
Blkio
优先从CFQ(Completely Fair Queuing 彻底公平的排队)拿数据,拿不到从这两个文件拿: · blkio.throttle.ioservicebytes,读写字节数 · blkio.throttle.io_serviced,读写次数
Throttle这个单纯可能有误导,实际这些都不是限制值,而是实际值。每一个文件的第一个字段是 major:minor 这样格式的device ID。
网络数据
针网络的监控要精确到接口级别,即网卡级别。每一个容器在host上都有一个对应的virtual Ethernet,咱们能够从这个设备得到tx和rx信息。
不过找到容器在主机上对应的虚拟网卡比较麻烦。这时候能够在宿主机上经过 ip netns 命令从容器内部取得网络数据。
为了在容器所在网络命名空间中执行 ip netns 命令,咱们首先须要找到这个容器进程的PID。
或者:
实际上Docker的实现也是从伪文件系统中读取网络metric的:
以上,是否是意犹未尽呢? 下一部分,斌哥将为你们介绍: 《Docker 监控方案的实现》
超好用的监控软件 Cloud Insight 不只能监控 Docker,还能对 Nagios 进行更好的可视化哦~
阅读更多技术文章,请访问 OneAPM 官方博客。 本文转自 OneAPM 官方博客