目 录CONTENT

文章目录

Prometheus系列03-服务发现

cplinux98
2022-08-30 / 0 评论 / 0 点赞 / 361 阅读 / 2,043 字 / 正在检测是否收录...

00:文章简介

介绍prometheus的服务发现。

01:服务发现介绍

对于中大型的系统环境或具有较强动态性的云计算环境来说,静态配置显然难以适用。因此,Prometheus为此专门设计了一组服务发现机制,以便于能够基于服务注册中心(服务总线)自动发现、检测、分类可被监控的各Target,以及更新发生了变动的Target。

1.1:指标抓取生命周期

image-20220318160059668

  • 在每个scrape_interval期间,Prometheus都会检查执行的作业(Job)
  • 这些作业首先会根据Job上指定的发现配置生成target列表,此服务的发现过程
    • 服务会发现返回一个Target列表,其中包含一组称为元数据的标签,这些标签都以"__meta_"为前缀;
    • 服务发现还会根据目标配置来设置其他标签,这些标签带有"__“前缀和后缀,包括"scheme”、“address” 和"metrices_path",分别保存有target支持适用协议(http或https,默认http)、target的地址及指标的URI路径(默认为/metrics);
    • 若这些URI路径中存在任何参数,则他们的前缀会被设置为"__param_";
    • 这些目标列表和标签会返回给Prometheus,其中的一些标签也可以在配置中被覆盖
  • 配置标签会在抓取的生命周期中被重复利用以生成其他标签,
    • 例如指标上的instance标签的默认值就来自于__address__标签的值

1.2:可集成的服务发现机制

  • 公有或私有IaaS自身保存有平台上的所有资源信息,其API Server便可作为Prometheus的服务发现媒介
    • azure、ec2、digitalocean、gce、hetzner等
  • Prometheus也可以集成到多种不同的开源服务发现工具上,以动态发现需要监控的目标;
    • consul、eureka zookeep serverset或airbnb nerve等
  • Prometheus也可以很好的集成到kubernetes平台上,通过其API Server动态发现各类被监控的Pod、Service、Endpoint、Ingress和Node对象
    • 它也支持基于dockerswarm和marathon两款编排工具进行服务发现
  • Prometheus还支持基于DNS或文件的动态发现机制

02:基于文件的服务发现

基于文件的服务发现是仅仅略优于静态配置的服务发现方式,它不依赖于任何平台或第三方服务,因而也是最简单和通用的实现方式。

  • Prometheus Server定期从文件中加载Target信息
    • 文件可适用JSON和YAML格式,它含有定义的Target列表,以及可选的标签信息
  • 这些文件可由另一个系统生成,例如Puppet、Ansible或Saltstack等配置管理系统,也可能是由脚本基于CMDB定期查询生成

文件示例:

每个类型的主机单独放置在一个文件中

image-20220318191546267

2.1:配置文件发现

在配置文件同级目录下,创建保存主机发现的yaml文件

├── prometheus.yml
└── targets
    ├── node-linux.yaml
    └── prometheus-server.yaml

targets/node-linux.yaml

- targets:
  - 192.168.31.11:9100
  - 192.168.31.12:9100
  - 192.168.31.13:9100
  - 192.168.31.21:9100
  - 192.168.31.22:9100
  - 192.168.31.23:9100
  labels:  # 自定义标签
    app: node_exporter

targets/prometheus-server.yaml

- targets:
  - 192.168.31.206:9090
  labels:
    app: prometheus-server

配置prometheus的配置文件

scrape_configs:
  - job_name: "prometheus"
    file_sd_configs:  # 指明从文件中发现
    - files:  # 发现的文件列表
      - targets/prometheus-*.yaml
      refresh_interval: 1m  # 重载文件的时间间隔

  - job_name: "nodes"
    metrics_path: '/metrics'
    file_sd_configs:
    - files:
      - targets/node*.yaml
      refresh_interval: 1m

配置完成后,重启服务

2.2:查看效果

Status -> Service Discovery

image-20220318204810877

03:基于DNS的服务发现

参考地址:https://blog.51cto.com/rzxwang/2524136

基于DNS的服务发现有两种模式

  • A记录
    • 通过对DNS的A记录进行解析IP地址,从而找到最终target
    • 每一个A记录对应一个主机
  • SRV记录
    • 通过对DNS的SRV记录解析,通讯协议+IP地址+端口
    • 一个SRV记录可以对应多个服务提供主机
    • 主机信息通过SRV解析得到target,然后添加到job中

SRV的记录格式 _service._proto.name. TTL class SRV priority weight port target

参数 说明
_service 服务名称,前缀 _ 是为了防止与DNS 标签(域名)冲突
proto 服务使用的通讯协议 通常是 tcp udp
name 此记录有效域名
TTL 标准DNS class 字段 如 IN
priority 记录优先级,数值越小,优先级越高。 [0-65535]
weight 记录权重,数值越大,权重越高。[0-65535]
port 服务使用端口
target 使用服务的主机地址名称

3.1:安装一个dns

对于简单测试,使用dnsmasq即可,配置如下

# A记录
address=/master01.linux98.com/192.168.31.11
address=/master02.linux98.com/192.168.31.12

# SRV记录
srv-host =_prometheus._tcp.linux98.com,master01.linux98.com,9100
srv-host =_prometheus._tcp.linux98.com,master02.linux98.com,9100

因为我们内网已经有基于bind9的dns服务了,这里配置bind9作为实验测试。

在zone文件中添加

master01.linux98.com.   IN      A       192.168.31.11
master02.linux98.com.   IN      A       192.168.31.12
master03.linux98.com.   IN      A       192.168.31.13

_prometheus._tcp.linux98.com.   1H      IN      SRV     0      0      9100    master01.linux98.com.
_prometheus._tcp.linux98.com.   1H      IN      SRV     0      0      9100    master02.linux98.com.
_prometheus._tcp.linux98.com.   1H      IN      SRV     0      0      9100    master03.linux98.com.

添加完成后重载服务,测试是否能解析

dig @dns_server +noall +answer SRV _prometheus._tcp.linux98.com.

3.2:配置SRV dns发现

/usr/local/prometheus/cfg/prometheus.yml

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "nodes"
    metrics_path: '/metrics'
    dns_sd_configs:
    - names: ['_prometheus._tcp.linux98.com.']

发现结果

image-20220319191718102

3.3:配置A记录dns发现

对于A记录的prometheus配置如下

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "nodes"
    metrics_path: '/metrics'
    dns_sd_configs:
    - names: ['master01.linux98.com', 'master02.linux98.com']
      type: A  # 不写默认是SRV类型
      port: 9100

04:基于CMDB的服务发现

对于成熟的运维团队来说,应该已经有了CMDB资产管理系统,而且Prometheus可以基于json格式去发现资源,我们在CMDB上开放一个接口,可以生成类似下面格式的返回值,即可让Prometheus进行资源发现。

[
    {
        "targets": ["10.0.10.2:9100", "10.0.10.3:9100", "10.0.10.4:9100", "10.0.10.5:9100"],
        "labels": {
            "__meta_datacenter": "london",
            "__meta_prometheus_job": "node"
        }
    },
    {
        "targets": ["10.0.40.2:9100", "10.0.40.3:9100"],
        "labels": {
            "__meta_datacenter": "london",
            "__meta_prometheus_job": "alertmanager"
        }
    },
    {
        "targets": ["10.0.40.2:9093", "10.0.40.3:9093"],
        "labels": {
            "__meta_datacenter": "newyork",
            "__meta_prometheus_job": "alertmanager"
        }
    }
]

在prometheus的配置文件中使用http资源发现,并指向CMDB提供的需要监控主机清单:

global:
  scrape_interval: 60s
  evaluation_interval: 60s

scrape_configs:

  - job_name: 'http-other'
    http_sd_configs:
     - url: http://my:8080/api/hosts

4.1:模拟CMDB主机接口

这里我们使用flask模拟一下CMDB的主机接口,只要访问/api/hosts这个URI,就返回一个类似上面的JSON数据

from flask import Flask, jsonify

app = Flask('cmdb')

data = [
    {
        "targets": ["192.168.31.11:9100", "192.168.31.12:9100", "192.168.31.13:9100", "192.168.31.21:9100"],
        "labels": {
            "__meta_datacenter": "london",
            "__meta_prometheus_job": "node"
        }
    },
]


@app.route('/api/hosts', methods=['GET'])
def hosts():
    return jsonify(data)


if __name__ == '__main__':
    app.run('0.0.0.0', 80, True)

4.2:修改prometheus发现方式

scrape_configs:
  - job_name: "from cmdb"
    metrics_path: '/metrics'
    http_sd_configs:
    - url: http://192.168.31.89:80/api/hosts
      refresh_interval: 10s

修改完成后重启prometheus查看网页

4.3:发现结果

image-20220319193711179

0

评论区