第7章 Prometheus服务发现

7.1 Prometheus与服务发现

在基于云(IaaS或者CaaS)的基础设施环境中用户可以像使用水、电一样按需使用各种资源(计算、网络、存储)。按需使用就意味着资源的动态性,这些资源可以随着需求规模的变化而变化。例如在AWS中就提供了专门的AutoScall服务,可以根据用户定义的规则动态地创建或者销毁EC2实例,从而使用户部署在AWS上的应用可以自动的适应访问规模的变化。

这种按需的资源使用方式对于监控系统而言就意味着没有了一个固定的监控目标,所有的监控对象(基础设施、应用、服务)都在动态的变化。对于Nagias这类基于Push模式传统监控软件就意味着必须在每一个节点上安装相应的Agent程序,并且通过配置指向中心的Nagias服务,受监控的资源与中心监控服务器之间是一个强耦合的关系,要么直接将Agent构建到基础设施镜像当中,要么使用一些自动化配置管理工具(如Ansible、Chef)动态的配置这些节点。当然实际场景下除了基础设施的监控需求以外,我们还需要监控在云上部署的应用,中间件等等各种各样的服务。要搭建起这样一套中心化的监控系统实施成本和难度是显而易见的。

而对于Prometheus这一类基于Pull模式的监控系统,显然也无法继续使用的static_configs的方式静态的定义监控目标。而对于Prometheus而言其解决方案就是引入一个中间的代理人(服务注册中心),这个代理人掌握着当前所有监控目标的访问信息,Prometheus只需要向这个代理人询问有哪些监控目标控即可, 这种模式被称为服务发现。

基于服务发现与注册中心动态发现监控目标

在不同的场景下,会有不同的东西扮演者代理人(服务发现与注册中心)这一角色。比如在AWS公有云平台或者OpenStack的私有云平台中,由于这些平台自身掌握着所有资源的信息,此时这些云平台自身就扮演了代理人的角色。Prometheus通过使用平台提供的API就可以找到所有需要监控的云主机。在Kubernetes这类容器管理平台中,Kubernetes掌握并管理着所有的容器以及服务信息,那此时Prometheus只需要与Kubernetes打交道就可以找到所有需要监控的容器以及服务对象。Prometheus还可以直接与一些开源的服务发现工具进行集成,例如在微服务架构的应用程序中,经常会使用到例如Consul这样的服务发现注册软件,Promethues也可以与其集成从而动态的发现需要监控的应用服务实例。除了与这些平台级的公有云、私有云、容器云以及专门的服务发现注册中心集成以外,Prometheus还支持基于DNS以及文件的方式动态发现监控目标,从而大大的减少了在云原生,微服务以及云模式下监控实施难度。

Push系统 vs Pull系统

如上所示,展示了Push系统和Pull系统的核心差异。相较于Push模式,Pull模式的优点可以简单总结为以下几点:

  • 只要Exporter在运行,你可以在任何地方(比如在本地),搭建你的监控系统;
  • 你可以更容易的查看监控目标实例的健康状态,并且可以快速定位故障;
  • 更利于构建DevOps文化的团队;
  • 松耦合的架构模式更适合于云原生的部署环境。

7.2 基于文件的服务发现

前面我们配置监控任务都是直接在Prometheus的配置文件中添加配置信息,然后重启Prometheus。这里有两个问题,一是有大量的任务的时候,一个Prometheus的配置文件变得很大,难以维护;二是每次的修改都要重启Prometheus,非常麻烦。基于文件的服务发现就是解决这两个问题的。

在Prometheus支持的众多服务发现的实现方式中,基于文件的服务发现是最通用的方式。这种方式不需要依赖于任何的平台或者第三方服务。对于Prometheus而言也不可能支持所有的平台或者环境。通过基于文件的服务发现方式下,Prometheus会定时从文件(json或者yaml格式)中读取最新的Target信息,因此,你可以通过任意的方式将监控Target的信息写入即可。

要定义文件发现服务非常简单,只需要在配置文件中添加对应的标签:

 file_sd_configs:
  - files:
    - yourfile.yml

比如,我要把我之前监控的node exporter独立到一个配置文件里面,我这么配置:

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['192.168.113.52:9090']

  #采集node exporter监控数据
  - job_name: node_exporter
    file_sd_configs:
      - files: ['/usr/local/prometheus/sd_config/node_exporter.yml']

上面我们定义了自动发现的配置,node_exporter这个任务的具体配置会从定义的文件中读取,默认每5分钟读取一次。我们新建这样的一个文件。

mkdir /usr/local/prometheus/sd_config
vim /usr/local/prometheus/sd_config/node_exporter.yml

yml文件里面定义了三个监控目标

- targets: ['192.168.113.52:9100']
- targets: ['192.168.113.70:9100']
- targets: ['192.168.1.174:9100']

然后重启Prometheus,让配置生效。在web页面上我们可以看到这个监控任务

然后,我们修改下node_exporter.yml,给两个目标增加标签,5分钟后查看Prometheus有没有自动更新这些配置:

- targets: ['192.168.113.52:9100']
  labels:
    instance: prometheus02-192.168.113.52
- targets: ['192.168.113.70:9100']
  labels:
    instance: docker01-192.168.113.70
- targets: ['192.168.1.174:9100']

5分钟后,我们看到 Labels 这一栏,明显发生了变化,也就是说我们的配置被自动加载进去了,如果要加快刷新的频率,可以修改Prometheus的配置文件:

scrape_configs:
  #采集node exporter监控数据
  - job_name: node_exporter
  - refresh_interval: 1m
    file_sd_configs:
      - files: ['/usr/local/prometheus/sd_config/node_exporter.yml']

7.3 基于Consul的服务发现

上面介绍的服务发现是基于文件的,如果我有多个Prometheus那就是要维护多套的配置文件了,这样似乎不够智能。有没有一种像,zookeeper那样的注册中心呢?Prometheus只要定期从注册中心获取信息即可。

在Prometheus技术栈里面,使用的工具是Consul。具体使用不做介绍,可以查看原文点我。

7.4 服务发现与Relabel

在上面的基础上有个更加难搞的需求,那就是线上环境有多套的集群比如:dev, stage, prod。不同的团队要采集的集群是不一样的,有没有什么方法可以过滤这些不同的信息么?或者说有什么方法可以给这些集群打标签呢?

这里使用的是 Prometheus的Relabeling机制,具体的介绍和使用参考原文点我

你可能感兴趣的:(第7章 Prometheus服务发现)