您的位置:首页 > 运维架构 > Docker

Docker 监控实战

2017-06-21 11:10 267 查看
如今,越来越多的公司开始使用 Docker 了,现在来给大家看几组数据:2 / 3 的公司在尝试了 Docker 后最终使用了它,也就是说 Docker 的转化率达到了 67%,而且转化时长也控制在 60 天内。



越大型的公司越早开始使用 Docker

研究发现主机数量越多的公司,越早开始使用 Docker。而主机数量多,在这个研究里就默认等同于是大型公司了。



Docker 优势

那为什么 Docker 越来越火呢?一谈起 Docker 总是会跟着让人联想到轻量这个词,甚至会有一种通过 Docker 启动一个服务会节省很多资源的错觉。然而
Docker 的「轻」也只是相对于传统虚拟机而已。传统虚拟机和 Docker 的对比如图:



从图中可以看出 Docker 和 虚拟机的差异,虚拟机的 Guest OS 和 Hypervisor 层在 Docker 中被 Docker
Engine 层所替代,Docker 有着比虚拟机更少的抽象层。
由于 Docker 不需要通过 Hypervisor 层实现硬件资源虚拟化,运行在 Docker 容器上的程序直接使用实际物理机的硬件资源。因此在
CPU、内存利用率上 Docker 略胜一筹。
Docker 利用的是宿主机的内核,而不需要 Guest OS,因此,当新建一个容器时,Docker 不需要和虚拟机一样重新加载一个操作系统内核,因此新建一个
Docker 容器只需要几秒钟。
总结一下 Docker 容器相对于 VM 有以下几个优势:启动速度快、资源利用率高、性能开销小。

Docker 监控方案

那么,既然 Docker 这么火,Docker 监控是不是也该提上日程?或许具体问题要具体分析,但是似乎大家都在使用开源的监控方案,来解决
Docker监控的问题。
就拿腾讯游戏来说吧,我们看看尹烨(腾讯互娱运营部高级工程师, 干货 | 腾讯游戏是如何使用 Docker 的? )怎么说:
容器的监控问题也花了我们很多精力。监控、告警是运营系统最核心的功能之一,腾讯内部有一套很成熟的监控告警平台,而且开发运维同学已经习惯这套平台,如果我们针对
Docker
容器再开发一个监控告警平台,会花费很多精力,而且没有太大的意义。所以,我们尽量去兼容公司现有的监控告警平台。每个容器内部会运行一个代理,从
/proc 下面获取 CPU、内存、IO 的信息,然后上报公司的监控告警平台。但是,默认情况下,容器内部的 proc 显示的是 Host
信息,我们需要用 Host 上 cgroup 中的统计信息来覆盖容器内部的部分 proc 信息。我们基于开源的
lxcfs,做了一些改造实现了这个需求。



这些解决方案都是基于开源系统来实现的,当然,我们也会把我们自己觉得有意义的修改回馈给社区,我们给 Docker、Kubernetes 和 lxcfs 等开源项目贡献了一些 patch。融入社区,与社区共同发展,这是一件很有意义的事情。

在没有专业运维团队来监控 Docker 的情况下,并且还想加快 Docker 监控的进程,该怎么办呢?
为了能够更精确的分配每个容器能使用的资源,我们想要实时获取容器运行时使用资源的情况,怎样对 Docker 上的应用进行监控呢?Docker
的结构会不会加大监控难度?
我们都了解, container 相当于小型 host,可以说存在于 hosts 与应用之间的监控盲区,无论是传统的基础组件监控还是应用性能监控的方式,都很难有效地监控
Docker。了解了一下现有的 Docker 相关监测 App 和服务,包括简单的开源工具和复杂的企业整体解决方案,下面列举其中的几种作为参考:

1. cAdvisor

谷歌的 container introspection 解决方案是 cAdvisor,这是一个 Docker 容器内封装的工具,能够采集、处理和导出运行中的容器的数据。通过它可以看到
CPU 的使用率、内存使用率、网络吞吐量以及磁盘空间利用率等。同时,你还可以通过点击在网页顶部的 Docker Containers 链接,选择某个容器来详细了解它的使用情况。cAdvisor
部署和使用简单,但它只可以监视在同一个 host 上运行的容器,对多节点部署不是太管用。

2. Cloud Insight

在我们列举的几个监控 Docker 的服务或平台中,这是唯一一款国内产品。 Cloud Insight支持多种操作系统、云主机、数据库和中间件的监控,原理是在平台服务仪表盘和自定义仪表盘中,采集并处理 Metric,对数据进行聚合与分组等计算,提供曲线图、柱状图等多样化的展现形式。优点是监控的指标很全,简单易用,可以期待一下。

3. Scout

Scout 是一款监视服务,并不是一个独立的开源项目。它有大量的插件,除了 Docker 信息还可以吸收其他有关部署的数据。因此 Scout
算是一站式监控系统,无需对系统的各种资源来安装各种不同的监控系统。 Scout 的一个缺点是,它不显示有关每个主机上单独容器的详细信息。此外,每个监控的主机十美元这样略微昂贵的价格也是是否选择
Scout 作为监控服务的一个考虑因素,如果运行一个有多台主机的超大部署,成本会比较高。

4. Sematext

Sematext 也是一款付费监控解决方案,计划收费方案是3.5美分/小时。同样也支持 Docker 监控,还包括对容器级事件的监测(停止、开始等等)和管理容器产生的日志。

5. Prometheus

Prometheus 由 SoundCloud 发明,适合于监控基于容器的基础架构。支持监控容器的资源和运行特性,支持多维度查询,能聚合 Docker
监控数据。

Docker 监控实践

数据的聚合&分组,是运维2.0时代的重头戏,因此我们重点选取其中比较有这个方面代表性的两个监控方案来看看具体的 Docker 监控过程。
先借鉴「Monitor Docker Containers with Prometheus](http://5pi.de/2015/01/26/monitor-docker-container」一文中的介绍,来说说这套开源的 Docker 监控方案:Prometheus;而此篇文字的原文地址:Monitor Docker Containers with Prometheus
Prometheus 由 SoundCloud 发明,可用于监控基于容器的基础架构。Prometheus
特点是高维度数据模型,时间序列是通过一个度量值名字和一套键值对识别。灵活的查询语言允许查询和绘制数据。它采用了先进的度量标准类型像汇总(summaries),从指定时间跨度的总数构建比率或者是在任何异常的时候报警并且没有任何依赖,中断期间使它成为一个可靠的系统进行调试。
Prometheus 支持维度数据,你可以拥有全局和简单的指标名像
container_memory_usage_bytes
,使用多个维度来标识你服务的指定实例。
可以创建一个简单的
container-exporter
来收集 Docker 容器的指标以及输出给
Prometheus 来消费。这个输出器使用容器的名字,id 和 镜像作为维度。额外的
per-exporter
维度可以在
prometheus.conf
中设置。
如果你使用指标名字直接作为一个查询表达式,它将返回有这个使用这个指标名字作为标签的所有时间序列。
container_memory_usage_bytes{env="prod",id="23f731ee29ae12fef1ef6726e2fce60e5e37342ee9e35cb47e3c7a24422f9e88",instance="http://1.2.3.4:9088/metrics",job="container-exporter",name="haproxy-exporter-int",image="prom/haproxy-exporter:latest"}    11468800.000000

container_memory_usage_bytes{env="prod",id="57690ddfd3bb954d59b2d9dcd7379b308fbe999bce057951aa3d45211c0b5f8c",instance="http://1.2.3.5:9088/metrics",job="container-exporter",name="haproxy-exporter",image="prom/haproxy-exporter:latest"}    16809984.000000

container_memory_usage_bytes{env="prod",id="907ac267ebb3299af08a276e4ea6fd7bf3cb26632889d9394900adc832a302b4",instance="http://1.2.3.2:9088/metrics",job="container-exporter",name="node-exporter",image="prom/container-exporter:latest"}

...
...
如果你运行了许多容器,这个看起来像这样:



为了帮助你使得这数据更有意义,你可以过滤(filter) and/or 聚合(aggregate) 这些指标。
使用 Prometheus 的查询语言,你可以对你想的任何维度的数据切片和切块。如果你对一个给定名字的所有容器感兴趣,你可以使用一个表达式像
container_memory_usage_bytes{name="consul-server"}
,这个将仅仅显示
name == "consul-server"
的时间序列。
像多维度的数据模型,来实现数据聚合、分组、过滤,不单单是 Prometheus。OpenTSDB 和 InfluxDB 这些时间序列数据库和系统监控工具的结合,让系统监控这件事情变得更加的多元。
如果你是阿里云的用户,或者使用过 Zabbix,那么你会明显感受到一个痛点:没有办法对数据做聚合,只能挨个查看主机的性能指标,更不用说有管理的功能。正因为如此我们才对数据聚合&分组抱有极大兴趣。如果想更多地了解数据聚合和分组的相关内容也可以阅读一下 数据聚合 & 分组:新一代系统监控的核心功能这篇文章。
现在我们来对比 Prometheus 和 Cloud Insight 在数据聚合、分组(切片)上的展现效果和功能。

数据聚合

根据不同的 Container Name 或 Image Name 对内存使用量或 Memeory Cache 进行聚合。



数据分组(切片)

根据不同的 Container Name 或 Image Name 对内存使用量或 Memeory Cache进行分组(切片)。



单方面监控 Docker 可能并不太适合与业务挂钩的应用,当业务量上涨,不单单是 Docker 的负载上升,其他 JVM 指标也能也会出现上升的趋势。如果我们利用
Acme 模拟真实应用环境,再通过 Cloud Insight 进行监控的话,需要新建一个用于此次监控的仪表盘,依次将想要获取的指标统统添加进去。
可以添加以下指标:
docker.cpu.user
docker.cpu.sysytem
docker.containers.running
jvm.heap_memory
jvm.non_heap_memory
jvm.gc.cms.count
jvm.heap_memory_max
jvm.gc.parnew.time
应用 Acme 部署在四台 servers 上,我们开启四台 servers, 然后用 JMeter 给应用加压。随着时间 JMeter 不断给应用加压,当
users 人数达到 188 时,我们来看一下仪表盘的视图。



根据 JMeter 里的数据,CPU 占用和错误率都有所提升;与此同时,在指标
docker.cpu.user
这幅图中,蓝色的线所代表的
Container CPU 占用率已经超过 50%,逐渐接近 75%,系统剩余的 CPU 资源逐渐下降。
而指标
docker.cpu.system
图中同样可以看到蓝色的那条数据在 18:29 左右出现了一个波峰,代表系统
CPU 资源消耗突然增大。通过这两幅图,我们可以定位到 CPU 占用率过高的 Container ,及时而主动地去了解性能瓶颈,从而优化性能,合理分配资源。
jvm.heap_memory
的值去比左图
jvm.heap_memory_max
的值,将能清楚的反映
JVM 堆内存的消耗情况。而
jvm.gc.parnew.time
图中显示了新生代并行 GC
的时间数据。GC 是需要时间和资源的,不好的 GC 会严重影响系统的系能,良好的 GC 是 JVM 高性能的保证。
无法被监控的软件是很危险的,通过解读这张 Docker 仪表盘总览图,我们也许可以了解到 Docker 实时性能状况,精准定位到性能薄弱的环节,从而优化我们的应用。

总结

Docker 兼容相比其他的数据库、系统、中间件监控,要复杂一些。由于需要表现不同 Container 的性能消耗,来了解不同应用的运行情况,所以数据的聚合、切片(分组)和过滤,在
Docker 监控中成为了必备功能。
所以推荐大家使用时间序列数据库,或者类似设计逻辑的监控方案,如Prometheus等。而 Docker 单方面的监控,可能不太满足一些大型公司的需求,如果一个工具在监控
Docker 同时能够监控其他组件,那就更好了。国外的 Graphite、Grafana 和 Host Graphite,以及国内的 Cloud
Insight,都是能够让用户将不同数据来源都集中在同一个地方进行展现,大家页可以对比和试用一下。
参考文章:
Monitor Docker Containers with Prometheus
8 Surprising Fact about Real Docker
六个下一代 Docker 监控工具
关于作者:张璐,OneAPM工程师。 (责编/仲浩)

Monitor Docker Containers with Prometheus

26 January 2015

Monitoring Docker

Running all your services in containers makes it possible to get
in-depth resource and performance characteristics, since every container
runs in their own cgroup and the Linux kernel provides us with all kind
of useful metrics.
Although there are a few other Docker monitoring tools out there, I'll show you why I think that SoundCloud's newly released Prometheus is a perfect fit for monitoring container-based infrastructures.
Prometheus features a highly dimensional data model in which a time series is identified by a metric name and a set of key-value pairs. A flexible query language allows querying and graphing this data. It features advanced metric types like summaries, building rates from totals over specified time spans or alerting on any expression and has no dependencies, making it a dependable system for debugging during outages.
I will focus on why especially the data model and query language
makes it such a good fit in a containerized, dynamic infrastructure
where you think in clusters of services instead of single instances and
servers as cattle instead of pets.

Classic Approach

Let’s say you want to monitor the memory usage of your containers.
Without support for dimensional data, such a metric for the container
named
webapp123
might be called
container_memory_usage_bytes_webapp123
.
But what if you want to show the memory usage of all your
webapp123
containers? More advanced monitoring solutions like graphite support that. It features a hierarchic, tree-like data model in which such metric might be called
container.memory_usage_bytes.webapp123
. Now you can use wildcards like
container.memory_usage_bytes.webapp*
to graph the memory usage of all your 'webapp' containers. Graphite also supports functions like
sum()
to aggregate the memory usage of your application across all your machines by using an expression like
sum(container.memory_usage_bytes.webapp*)
.
That's all great and very useful, but limited. What if you don't want
to aggregate all containers with a given name but with a given image?
Or you want to compare the deployments to your canary with those on your
prod machines?
It's possible to come up with a hierarchy for each use case, but not
one to support them all. And reality shows, you often don't know in
advance which questions you need to answer once things go dark and you
start investigating.

Prometheus

With Prometheus’s support for dimensional data, you can have global and straightforward metric names like
container_memory_usage_bytes
with multiple dimensions to identify the specific instances of your service.
I've created a simple container-exporter
to gather Docker Container metrics and expose them for Prometheus to
consume. This exporter uses the container's name, id and image as
dimensions. Additional per-exporter dimension can be set in the
prometheus.conf
.
If you use the metric name directly as a query expression, it will
return all time series with their labels for this metric name:
container_memory_usage_bytes{env="prod",id="23f731ee29ae12fef1ef6726e2fce60e5e37342ee9e35cb47e3c7a24422f9e88",instance="http://1.2.3.4:9088/metrics",job="container-exporter",name="haproxy-exporter-int",image="prom/haproxy-exporter:latest"}    11468800.000000
container_memory_usage_bytes{env="prod",id="57690ddfd3bb954d59b2d9dcd7379b308fbe999bce057951aa3d45211c0b5f8c",instance="http://1.2.3.5:9088/metrics",job="container-exporter",name="haproxy-exporter",image="prom/haproxy-exporter:latest"}    16809984.000000
container_memory_usage_bytes{env="prod",id="907ac267ebb3299af08a276e4ea6fd7bf3cb26632889d9394900adc832a302b4",instance="http://1.2.3.2:9088/metrics",job="container-exporter",name="node-exporter",image="prom/container-exporter:latest"}
...
...
If you run lot of containers, this looks something like this:



To help you make sense of this data, you can filter and/or aggregate these metrics

Slice & Dice

With Prometheus’s query language, you can slice and dice data by any
dimension you want. If you're interested in all containers with a given
name, you can use an expression like
container_memory_usage_bytes{name="consul-server"}
, which would show only the time series for which
name == "consul-server"
.
Prometheus also supports regular expressions, so instead of matching the full script you can do
container_memory_usage_bytes{name=~"^consul"}
, which would show something like this:



You can use any other dimension for filtering as well, so you can get
metrics about all containers on a given host, in a given environment or
zone.

Aggregation

Similar to Graphite, Prometheus supports aggregation functions but
due to its dimensions this gets even more powerful. Summing up the
memory usage of all your "consul-*" works as expected with
sum(container_memory_usage_bytes{name=~"^consul"})
.
Now let’s say you want to see the difference in average memory usage
between your 'consul' and 'consul-server' containers. This is achieved
by providing the dimensions to keep in the aggregated result like this
avg(container_memory_usage_bytes{name=~"^consul"}) by (name)
:



If you have services in multiple zones and configure the zone name as
an additional label pair, you can also keep that dimension to show the
memory usage per name and zone by using an expression like
avg(container_memory_usage_bytes{name=~"^consul"}) by (name,zone)
.

Using Prometheus + Container-Exporter

As you know, I like to run everything in containers, including the container-exporter and Prometheus itself. Running the container-exporter should be as easy as this:
docker run -p 8080:8080 -v /sys/fs/cgroup:/cgroup \
-v /var/run/docker.sock:/var/run/docker.sock prom/container-exporter
Now you need to install Prometheus. For that refer to the official documentation.
To make Prometheus pull the metrics from the container-exporter, you
need to add it as a target to the configuration. For example:
job: {
name: "container-exporter"
scrape_interval: "1m"
target_group: {
labels: {
label: {
name: "zone"
value: "us-east-1"
}
label: {
name: "env"
value: "prod"
}
}
target: "http://1.2.3.4:8080/metrics"
}
}
Now rebuild your image as described in the documentation and start
it. Prometheus should now poll your container-exporter every 60s.

Conclusion

Because of Prometheus flexibility, its performance and minimal requirements, it's the monitoring system of my choice.
This is why I introduced Prometheus beginning last year at Docker where we use it as our primary monitoring system.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  docker 监控