docker发展到这么久,涌现了很是多的延伸工具,有的甚至自成一套系统。相信你们都对各种编排工具备所了解。而各种监控方案也都应运而生。linux内核以及cgroup技术其实已经为监控的技术可行性提供了全部的基础。这里咱们列举一些监控工具:node
docker 提供了command方法(docker stats CID)和API: http://$dockerip:2375/containers/$containerid/stats 其本质是读文件,提供了CPU,内存,BIO,NIO的监控,想探究其实现的同窗能够去查阅开源项目libcontainer,或阅读浅谈k8s+docker 资源监控了解详细的技术内容。linux
cAdvisor是一个被k8s集成的监控agent(谷歌自家用),与docker原生监控同样采用了libcontainer的接口。cadvisor还增长了对宿主机的监控,包括CPU,内存,网卡和磁盘设备,甚至还调用了docker的api,去整合了容器的基本信息如labels,resource limits等。能够说cadvisor的监控已经比较全面了,然而容易引人吐槽的是:至今cadvisor尚未推出一个稳定的大版本,最新版本是0.24.1,可它的API版本已经出到2.1版了。这里列出几个cadvisor的关键API(只采用最新的v2.1 api):nginx
1. http://localhost:4194/api/v2.1/stats/:containerid 查看容器的资源数据
2. http://localhost:4194/api/v2.1/machine 查看机器的信息
3. http://localhost:4194/api/v2.1/machinestats 查看机器的资源数据,包括磁盘的读写数据
4. http://localhost:4194/api/v2.1/spec/:containerid 查看容器的基础信息
5. http://localhost:4194/api/v2.1/summary:containerid 查看容器在几个时间片的各项指标状态分布值
6. http://localhost:4194/api/v2.1/storage/:containerid 查看容器中的磁盘挂载状况
须要注意的是,此处的containerid由podID和container ID,以必定规则,按照不一样的QoS命名,如: /kubepods/burstable/pode0f6a540-90af-11e8-8ae8-fa163edcbbdb/2bb0179713a20d3f96c85d7fcd1354277270c413f7970b7b6c0db8363bbf892b 表示一个没有定义容器resources.requests 和resources.limits 的pod(pod的uuid:e0f6a540-90af-11e8-8ae8-fa163edcbbdb)中的容器(容器id:2bb0179713a20d3f96c85d7fcd1354277270c413f7970b7b6c0db8363bbf892b ) /kubepods/podc3b4fc59-9462-11e8-9fcd-fa163edcbbdb/282755d06a51d84c1dc0d3153b1bf4604cc37ae2ccb26c69b3855176894da50c 表示一个定义了容器resources.requests 和resources.limits 的pod中的容器。git
以上几个接口其实看名字就能大概知道是什么意思,有兴趣的同窗不妨在本身的机器上部署kubernetes,而后在计算节点运行这几个api试试。 cadvisor默认监听咋在4194端口,而kubelet其实也代理了cadvisor的监控,因此,咱们除了上述的接口,还能够经过访问kubelet(10255端口)来获取监控数据。github
这里还要再提一下heapster,cadvisor+heapster能够很好的实现kubernetes容器集群的资源监控。heapster在发布稳定版本(1.0)后,增长了对pause容器的识别,能够更直观地经过heapster的API查看到Pod级别的网络IO。数据存储用elasticsearch/influxDB/hawkular等各类存储均可以(heapster支持用户以storage driver plugin的形式将抓取的metrics sink 自由整合并推送给存储服务)数据展现使用grafana,这就打造了一套基本完整的的数据监控服务。而使用k8s能够将三个组件(heapster+influxdb+grafana)一键部署。 *k8s1.9后heapster已经被社区废弃。社区将使用metrics-server进行基础的集群性能监控,并使用prometheus来支持更细致的指标监控。docker
Zabbix更面向裸机和IaaS虚拟机,容器监控是他的软肋,而openfalcon则被许多企业或docker团队选型为容器集群监控的方案。openfalcon有完整的监控项,增长了邮件告警功能,可自定义的agnet SDK。但整套系统模块繁多,学习成本大。要想用好,还须要针对容器/kubernetes进行二次开发。segmentfault
prometheus是一套很是成熟的监控,它能够监控不少细节的性能指标,好比http请求次数,磁盘读写io和延迟,cpu负载等,同时prometheus友好地支持自定义指标的采集,用户能够以此为基础设计本身服务的QPS监控、访问延迟监控、业务处理速度监控等。目前prometheus已经被不少厂商用于生产环境,也所以它已经顺利从CNCF项目中毕业。api
metrics-server严格来讲是heapster的替代品,它做为kubernetes的“周边”,在集群中以deployment方式部署,metrics-server会注册一套用于监控的api,监控数据则是从当前集群的全部node中拉取(也就是上文提到的kubelet代理的监控接口)。在集群中部署好metrics-server后,过一分钟咱们能够经过执行kubectl top node *** 查看一个node节点的cpu和内存使用状况。 metrics-server主要应用在社区的HPA(horizontal pod autoscaler)功能中。缓存
在linux中,一切都是文件,因此基于LXC技术的虚拟化方案中,对资源的监控其实也是文件,咱们知道docker依赖cgroup作资源的限制,而实际上cgroup也记录了资源的使用状况。咱们在容器宿主机的/sys/fs/cgroup/目录下能够看到诸如cpu,memory,blkio的子目录,他们分别存放了对机器上某些进程的资源限制和使用状况。好比: /sys/fs/cgroup/blkio/docker/1c04cedf48560c37cbac695809f8d50d632faa6b1aaeaf40d269756eb912597b/blkio.throttle.io_service_bytes 记录了某个容器的块设备IO字节数。 而容器的网络设备流量,咱们能够在/sys/class/net/目录下根据对应的网卡设备名,找到统计数据文件: /sys/class/net/vethc56160e/statistics/tx_bytes 记录了某个网卡的发出字节数。 (更多知识能够学习cgroup的资源限制)服务器
可见,监控数据的抓取并非难事,真正困难的是将这些数据以容器维度,甚至k8s的Pod,RC维度整合。
网易云计算基础服务在自研的云监控服务的基础上,结合开源组件cadvisor二次开发,实现了云计算基础服务的监控系统。
实际上,咱们不创造监控,咱们是监控的搬运工。网易云平台已经有成熟的自研监控系统(NMS)为咱们提供了监控数据的存储,整理和展现。开源组件cadvisor也提供了cpu,内存,网络等指标的监控支持和数据缓存(保证监控数据的可读性)。 本着实用性和可用性的原则,咱们还作了以下设计:
经过一个独立的agent模块,去收集cadvisor采集的数据,并推送给云监控。咱们这么设计的初衷,最主要为了不对cadvisor作侵入式开发,避免后续cadvisor的版本更新带来的大范围代码改动。cadvisor自己是一个pull server,不是一个push agent,强行加入push 模块会增长kubelet的复杂性和性能负担,也会提升整个系统的耦合度;二是云监控有本身一套API,对数据的维度和监控的demision都有其规范,好比,咱们将每次push给云监控的CPU使用率以Namespace#Service#Pod#Container为标识,确保该监控数据能匹配到制定的容器,从而实现页面上的展现。而引入这套规范到cadvisor中也会提升整个系统的耦合度。
在agent的部署上咱们直接利用了kubernetes的DaemonSet特性。
咱们知道,k8s最经常使用的两个资源是pod和replication,daemonset是一个刚趋于稳定的特性,和deployment相似,然而十分的实用。使用daemonset会保证这个agent Pod会在每个计算节点上启动并保持一个实例。agent调用cadvisor的接口收集数据,根据云计算基础服务产品的需求,对数据作过滤和加工,最后推送给云监控。agent既是kubernetes集群监控的组件,也是k8s-DaemonSet的应用范例。
云计算基础服务实现了有状态服务的部署,并支持挂载云硬盘,针对用户的反馈,咱们了解到必须增长对容器的系统盘、数据盘使用率的监控(后续还会提供inode,IOPS,BPS这些指标),提出阈值预警,避免用户的误操做致使的不良影响进一步扩大。cadvisor的几个接口(下文会列出)会分别提供一部分磁盘的监控数据,可是并无作好整合(能够看到容器stats API中Filesystem字段的内容并非咱们想要的数据).
基于cadvisor的接口和对linux底层的认识,咱们是这么实现对磁盘的监控的:
1.为了避免破坏cadvisor原来的代码结构,在v2.1中新增一个API,提供维度为一个/多个容器的全部挂载设备的监控信息。监控信息包括:容器名、负载名、容器挂载的云盘类型、挂载目录、云盘uuid等。这里挂载路径能够经过容器的描述文件(或直接docker inspect)获得。
2.经过原生接口/api/v2.1/stats/machinestats,咱们能看到容器挂载的全部磁盘设备的IOPS和BPS(JSON中的io_serviced字段和io_service_bytes字段记录了累计值,经过计算能够求出IOPS和BPS)。结合步骤1的数据,整合出一个容器挂载的全部云盘的使用率、inode使用率、IOPS和BPS;
3.结合咱们在kubernetes使用过程当中的规范,区分确认系统盘(容器系统盘通常挂载在容器的/目录下)和数据盘(来自网易云存储NBS提供的卷信息),按不一样维度推送给云监控。好比cloud#deployment:netease#nginx#ng1 维度,表示cloud namespace、deployment:netease、pod:nginx,容器名:ng1 。
4.云监控处理监控数据时,根据维度进行数据聚合,以此提供多视角(容器视角、pod视角、负载视角)的监控展现。
若是读者们阅读过cadvisor的代码,会发现里面对机器的描述信息、文件系统的描述信息,是全局的(感兴趣的能够在源码中阅读如下machineInfo、fsInfo两个变量),且在一个cadvisor Manager对象初始化后就不会再被修改。这致使咱们在测试环境发现:动态挂载一个云盘到宿主机上,并挂载做为容器的数据盘时,cadvisor没法读取新挂的磁盘的数据,除非重启kubelet(至关于从新初始化cadvisor中的fsInfo)。咱们在cadvisor的代码中增长了自检逻辑,当检查到机器上有新挂载的云盘时,对machineInfo、fsInfo作更新(需加锁,不然会引入竟态)。但这个更改没有被社区采纳。
网易云容器服务为用户提供了无服务器容器,让企业可以快速部署业务,轻松运维服务。容器服务支持弹性伸缩、垂直扩容、灰度升级、服务发现、服务编排、错误恢复及性能监测等功能,点击可免费试用。
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经做者黄扬受权发布。