Prometheus 是一个非常优秀的监控工具。准确的说,应该是监控方案。Prometheus 提供了监控数据搜集、存储、处理、可视化和告警一套完整的解决方案。
一 、Prometheus架构
Prometheus 重要组件的架构如下:
官网上的原始架构图比上面这张要复杂一些,只保留了最重要的组件。
Prometheus Server
负责从Exporter拉取和存储监控数据,并提供一套灵活的查询语言(PromQL)工用户使用
Exporter
负责收集目标对象(host、container)的性能数据,并通过HTTP接口供 Prometheus Server 获取
可视化组件
监控数据的可视化展示对于监控方案至关重要。以前Prometheus自己开发了一套工具,不够后来放弃了,因为开源社区出现了更为优秀的产品 Grafana。Grafana能够与 Prometheus无缝集成,提供完美的数据展示能力。
Alertmanager
用户可以定义基于监控数据的告警规则,规则会触发告警。一旦Alertmanager收到告警,会通过预定义的方式发出告警通知。支持的方式包括 email、PagerDuty、Webhook等
Prometheus 与 其他监控工具(zabbix、graphite、nagios等)相比,最大的亮点和先进性是他的多维数据模型。
二 、Prometheus的优势特点
比如要监控容器 webapp1
的内存使用情况,最传统和典型的方法是定义一个指标 container_memory_usage_bytes_webapp1
来记录 webapp1
的内存使用数据。假如每1分钟取一次样,那么在数据库里就会有类似下面的记录。
好,现在需求发生了点变化,我们需要知道所有 webapp 容器的内存使用情况。如果还是采用前面的方法,就不得不增加新的指标 container_memory_usage_bytes_webapp2
、container_memory_usage_bytes_webapp3
…
像 Graphite 这类更高级的监控方案采用了更为优雅的层次化数据模型。为了满足上面的需求,Graphite 会定义指标 container.memory_usage_bytes.webapp1
、container.memory_usage_bytes.webapp2
、container.memory_usage_bytes.webapp3
…
然后就可以用 container.memory_usage_bytes.webapp*
获取所有的 webapp 的内存使用数据。
此外,Graphite 还支持 sum()
等函数对指标进行计算和处理,比如 sum(container.memory_usage_bytes.webapp*)
可以得到所有 webapp 容器占用的总内存量。
目前为止问题处理得都很好。但客户总是会提出更多的需求:现在不仅要按容器名字统计内存使用量,还要按镜像来统计;或者想对比一下某一组容器在生产环境和测试环境中对内存使用的不同情况。
当然你可以说:只要定义更多的指标就能满足这些需求。比如 container.memory_usage_bytes.image1.webapp1
、container.memory_usage_bytes.webapp1.prod
等。
但问题在于我们没办法提前预知客户要用这些数据回答怎样的问题,所以我们没办法提前定义好所有的指标。
下面来看看 Prometheus 的解决方案。
Prometheus 只需要定义一个全局的指标 container_memory_usage_bytes
,然后通过添加不同的维度数据来满足不同的业务需求。
比如对于前面 webapp1 的三条取样数据,转换成 Prometheus 多维数据将变成:
后面三列 container_name
、image
、env
就是数据的三个维度。想象一下,如果不同 env
(prod、test、dev),不同 image
(mycom/webapp:1.2、mycom/webapp:1.3)的容器,它们的内存使用数据中标注了这三个维度信息,那么将能满足很多业务需求,比如:
-
计算 webapp2 的平均内存使用情况:avg(container_memory_usage_bytes{container_name=“webapp2”})
-
计算运行 mycom/webapp:1.3 镜像的所有容器内存使用总量:sum(container_memory_usage_bytes{image=“mycom/webapp:1.3”})
-
统计不同运行环境中 webapp 容器内存使用总量:sum(container_memory_usage_bytes{container_name=~“webapp”}) by (env)
这里只列了几个例子,不过已经能够说明 Prometheus 数据模型的优势了:
-
通过维度对数据进行说明,附加更多的业务信息,进而满足不同业务的需求。同时维度是可以动态添加的,比如再给数据加上一个
user
维度,就可以按用户来统计容器内存使用量了。 -
Prometheus 丰富的查询语言能够灵活、充分地挖掘数据的价值。前面示例中的 avg、sum、by 只是查询语言中很小的一部分功能,已经为我们展现了 Prometheus 对多维数据进行分片、聚合的强大能力。
安装部署
Docker Host:192.168.56.102 和 192.168.56.103,监控 host 和容器两个层次的数据。
按照架构图,我们需要运行如下组件:
Prometheus Server
Prometheus Server 本身也将以容器的方式运行在 host 192.168.56.103 上。
Exporter
Prometheus 有很多现成的 Exporter,完整列表请参考 https://prometheus.io/docs/instrumenting/exporters/
我们将使用:
-
Node Exporter,负责收集 host 硬件和操作系统数据。它将以容器方式运行在所有 host 上。
-
cAdvisor,负责收集容器数据。它将以容器方式运行在所有 host 上。
Grafana
显示多维数据,Grafana 本身也将以容器方式运行在 host 192.168.56.103 上
运行 Node Exporter
在两个 host 上执行如下命令:
docker run -d -p 9100:9100 \
-v "/proc:/host/proc" \
-v "/sys:/host/sys" \
-v "/:/rootfs" \
--net=host \
prom/node-exporter \
--path.procfs /host/proc \
--path.sysfs /host/sys \
--collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
注意,这里我们使用了 --net=host
,这样 Prometheus Server 可以直接与 Node Exporter 通信。
Node Exporter 启动后,将通过 9100 提供 host 的监控数据。在浏览器中通过 http://192.168.56.102:9100/metrics 测试一下。
运行 cAdvisor
在两个 host 上执行如下命令:
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
--net=host \
google/cadvisor:latest
注意,这里我们使用了 --net=host
,这样 Prometheus Server 可以直接与 cAdvisor 通信。
cAdvisor 启动后,将通过 8080 提供 host 的监控数据。在浏览器中通过 http://192.168.56.102:8080/metrics 测试一下。
运行 Prometheus Server
在 host 192.168.56.103 上执行如下命令:
docker run -d -p 9090:9090 \
-v /root/prometheus.yml:/etc/prometheus/prometheus.yml \
--name prometheus \
--net=host \
prom/prometheus
注意,这里我们使用了 --net=host
,这样 Prometheus Server 可以直接与 Exporter 和 Grafana 通信。
prometheus.yml 是 Prometheus Server 的配置文件。
最重要的配置是:
static_configs:
- targets: ['localhost:9090','localhost:8080','localhost:9100','192.168.56.102:8080','192.168.56.102:9100']
指定从哪些 exporter 抓取数据。这里指定了两台 host 上的 Node Exporter 和 cAdvisor。
另外 localhost:9090
就是 Prometheus Server 自己,可见 Prometheus 本身也会收集自己的监控数据。同样地,我们也可以通过 http://192.168.56.103:9090/metrics 测试一下。
在浏览器中打开 http://192.168.56.103:9090 ,点击菜单 Status -> Targets
。
如下图所示:
所有 Target
的 State
都是 UP
,说明 Prometheus Server 能够正常获取监控数据
运行 Grafana
在 host 192.168.56.103 上执行如下命令:
docker run -d -i -p 3000:3000 \
-e "GF_SERVER_ROOT_URL=http://grafana.server.name" \
-e "GF_SECURITY_ADMIN_PASSWORD=secret" \
--net=host \
grafana/grafana
注意,这里我们使用了 --net=host
,这样 Grafana 可以直接与 Prometheus Server 通信。
-e "GF_SECURITY_ADMIN_PASSWORD=secret
指定了 Grafana admin
用户密码 secret
。
Grafana 启动后。在浏览器中打开 http://192.168.56.103:3000/
登录后,Grafana 将引导我们配置 Data Source。
Name
为 Data Source 命名,例如 prometheus
。
Type
选择 Prometheus
。
Url
输入 Prometheus Server 的地址 http://192.168.56.103:9090
其他保持默认值,点击 Add
。
如果一切顺利,Grafana 应该已经能够访问 Prometheus 中存放的监控数据了,那么如何展示呢?
Grafana 是通过 Dashboard 展示数据的,在 Dashboard 中需要定义:
-
展示 Prometheus 的哪些多维数据?需要给出具体的查询语言表达式。
-
用什么形式展示,比如二维线性图,仪表图,各种坐标的含义等。
可见,要做出一个 Dashboard 也不是件容易的事情。幸运的是,我们可以借助开源社区的力量,直接使用现成的 Dashboard。
访问 https://grafana.com/dashboards?dataSource=prometheus&search=docker,将会看到很多用于监控 Docker 的 Dashboard。
我们可以下载这些现成的 Dashboard,然后 import 到我们的 Grafana 中就可以直接使用了。
比如下载 Docker and system monitoring
,得到一个 json 文件,然后点击 Grafana 左上角菜单 Dashboards -> Import
。
导入我们下载的 json 文件。
Dashboard 将立刻展示出漂亮的图表。
在这个 Dashboard 中,上部分是 host 的数据,我们可以通过 Node
切换不同的 host。
Dashboard 的下半部分展示的是所有的容器监控数据。Grafana 的 Dashboard 是可交互的,我们可以在图表上只显示指定的容器、选取指定的时间区间、重新组织和排列图表、调整刷新频率,功能非常强大。
docker启动的时候提示WARNING: IPv4 forwarding is disabled. Networking will not work.
修改配置文件:
vim /usr/lib/sysctl.d/00-system.conf
追加
net.ipv4.ip_forward=1
接着重启网络
[root@localhost mytomcat]# systemctl restart network