工作笔记(2)—Prometheus服务发现机制

工作笔记(2)—Prometheus服务发现机制

一、场景问题

在云原生、容器化的场景下,按需分配的方式成为主要的资源获取和使用方式。在这种情况下,所有的监控对象(基础设施、应用以及服务等)都在动态的变化。传统的基于Push模式的监控系统失去了一个固定地监控目标,不能很好的实时、准确地上报资源使用情况。

工作笔记(2)—Prometheus服务发现机制

Prometheus是一种典型的基于Pull模式的监控系统框架,其主要通过定义static_configs配置文件,静态地去监控对象。为了解决上述问题,Prometheus引入可服务发现模式。其基本的解决方法就是引入一个服务中心代理,可以存储所有监控对象的访问信息,Prometheus只需要发送请求到服务注册中心就可以获取对应信息。

工作笔记(2)—Prometheus服务发现机制

如上所示,体现PushPull的核心差异。相较于Push模式,Pull模式的优点可以简单总结为以下几点:

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

二、服务发现方式

根据Prometheus的相关代码,总结目前支持的服务发现方式:

// 代码源于prometheus/discovery/config/config.go
type ServiceDiscoveryConfig struct {
    StaticConfigs []*targetgroup.Group `yaml:"static_configs,omitempty"`
    DNSSDConfigs []*dns.SDConfig `yaml:"dns_sd_configs,omitempty"`
    FileSDConfigs []*file.SDConfig `yaml:"file_sd_configs,omitempty"`
    ConsulSDConfigs []*consul.SDConfig `yaml:"consul_sd_configs,omitempty"`
    ServersetSDConfigs []*zookeeper.ServersetSDConfig `yaml:"serverset_sd_configs,omitempty"`
    NerveSDConfigs []*zookeeper.NerveSDConfig `yaml:"nerve_sd_configs,omitempty"`
    MarathonSDConfigs []*marathon.SDConfig `yaml:"marathon_sd_configs,omitempty"`
    KubernetesSDConfigs []*kubernetes.SDConfig `yaml:"kubernetes_sd_configs,omitempty"`
    GCESDConfigs []*gce.SDConfig `yaml:"gce_sd_configs,omitempty"`
    EC2SDConfigs []*ec2.SDConfig `yaml:"ec2_sd_configs,omitempty"`
    OpenstackSDConfigs []*openstack.SDConfig `yaml:"openstack_sd_configs,omitempty"`
    AzureSDConfigs []*azure.SDConfig `yaml:"azure_sd_configs,omitempty"`
    TritonSDConfigs []*triton.SDConfig `yaml:"triton_sd_configs,omitempty"`
}

对应的模板如下:

# List of Azure service discovery configurations.
azure_sd_configs:
  [ - <azure_sd_config> ... ]

# List of Consul service discovery configurations.
consul_sd_configs:
  [ - <consul_sd_config> ... ]

# List of DNS service discovery configurations.
dns_sd_configs:
  [ - <dns_sd_config> ... ]

# List of EC2 service discovery configurations.
ec2_sd_configs:
  [ - <ec2_sd_config> ... ]

# List of OpenStack service discovery configurations.
openstack_sd_configs:
  [ - <openstack_sd_config> ... ]

# List of file service discovery configurations.
file_sd_configs:
  [ - <file_sd_config> ... ]

# List of GCE service discovery configurations.
gce_sd_configs:
  [ - <gce_sd_config> ... ]

# List of Kubernetes service discovery configurations.
kubernetes_sd_configs:
  [ - <kubernetes_sd_config> ... ]

# List of Marathon service discovery configurations.
marathon_sd_configs:
  [ - <marathon_sd_config> ... ]

# List of AirBnB's Nerve service discovery configurations.
nerve_sd_configs:
  [ - <nerve_sd_config> ... ]

# List of Zookeeper Serverset service discovery configurations.
serverset_sd_configs:
  [ - <serverset_sd_config> ... ]

# List of Triton service discovery configurations.
triton_sd_configs:
  [ - <triton_sd_config> ... ]

2.1 基于文件的服务发现

用户可以通过JSONYAML格式的文件,定义所有的监控目标。例如,在下面的JSON文件(targets.json)中分别定义了3个采集任务,以及每个任务对应的Target列表:

[
  {
    "targets": [ "localhost:8080"],
    "labels": {
      "env": "localhost",
      "job": "cadvisor" #默认是prometheus.yml中配置的file_ds(见下),此cadvisor会覆盖前者
    }
  },
  {
    "targets": [ "localhost:9104" ],
    "labels": {
      "env": "prod",
      "job": "mysqld"
    }
  },
  {
    "targets": [ "localhost:9100"],
    "labels": {
      "env": "prod",
      "job": "node"
    }
  }
]

创建Prometheus配置文件/etc/prometheus/prometheus-file-sd.yml,并添加以下内容:

global:  
	scrape_interval: 15s
    scrape_timeout: 10s
    evaluation_interval: 15s scrape_configs:
    - job_name: 'file_ds'
    file_sd_configs: 
   	 - files:
   	 	- /opt/prometheus/file_sd_configs/targets.json #也可以模糊匹配多个文件
    refresh_interval: 10s

通过这种方式,Prometheus会自动的周期性读取文件中的内容。当文件中定义的内容发生变化时,不需要对Prometheus进行任何的重启操作。

使用参考:https://www.cnblogs.com/xiangsikai/p/11289101.html

2.2 基于Consul的服务发现

Consul是由HashiCorp开发的一个支持多数据中心的分布式服务发现和键值对存储服务的开源软件,被大量应用于基于微服务的软件架构当中。

Consul作为一个通用的服务发现和注册中心,记录并且管理了环境中所有服务的信息。Prometheus通过与Consul的交互可以获取到相应Exporter实例的访问信息。在Prometheus的配置文件当可以通过以下方式与Consul进行集成:

- job_name: node_exporter
metrics_path: /metrics
scheme: http
consul_sd_configs:
- server: localhost:8500 #指定了consul的访问地址
services:   #为注册到consul中的实例信息
- node_exporter - cadvisor

consul_sd_configs定义当中通过server定义了Consul服务的访问地址,services则定义了当前需要发现哪些类型服务实例的信息,这里限定了只获取node_exportercadvisor的服务实例信息。

使用参考:https://blog.csdn.net/aixiaoyang168/article/details/103022342,https://www.jianshu.com/p/a5dde3af8e18

2.3 DNS服务发现

PrometheusDNS服务发现有俩种方法,第一种是使用DNA A记录来做自动发现,第二种方法是DNS SRV,第一种显然没有SRV资源记录更为便捷,在这里就把俩种配置全部做一遍,对于取决用什么,根据你自己的环境来抉择。

DNA A记录发现配置,首先你内网需要有一个DNS服务器,或者直接自行配置解析记录即可,这里使用的dnsmasq服务在内网测试

# 验证 test1 DNS记录
nslookup test1.example.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	test1.example.com
Address: 192.168.1.221
# 验证 test2 DNS记录
nslookup test2.example.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	test2.example.com
Address: 192.168.1.222

Prometheus配置

  # 基于DNS A记录发现
  - job_name: 'DNS-A'                  # job 名称
    metrics_path: "/metrics"            # 路径
    dns_sd_configs:
    - names: ["test1.example.com", "test2.example.com"]   # A记录
      type: A                                   # 解析类型
      port: 29100                     # 端口

重启Prometheustargets中可以看到dns-a记录。

DNS SRVDNS资源记录中的一种记录类型,用来指定服务器地址与端口,并且可以设置每个服务器的优先级和权重。访问到服务的时候,本地的DNS resolverDNS服务器获取一个地址列表,然后根据优先级和权重来选择一个地址作为本次请求的目标地址。

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 使用服务的主机地址名称

这里没有使用named,而是使用的dnsmasq来做的测试,添加SRV记录完成后,需要重启dnsmasq服务使其生效。

# 配置dns解析
cat /etc/dnsmasq.d/localdomain.conf
address=/test1.example.com/192.168.1.221
address=/test2.example.com/192.168.1.222
# 添加 SRV 记录
cat /etc/dnsmasq.conf
srv-host =_prometheus._tcp.example.com,test1.example.com,29100
srv-host =_prometheus._tcp.example.com,test2.example.com,29100

# 验证srv服务是否正确,192.168.1.123 是内部DNS服务器,
dig @192.168.1.123 +noall +answer SRV _prometheus._tcp.example.com
output...
_prometheus._tcp.example.com. 0	IN	SRV	0 0 9100 test1.example.com.
_prometheus._tcp.example.com. 0	IN	SRV	0 0 9100 test2.example.com.

Prometheus配置完成以后,重载Prometheus服务。

  - job_name: 'DNS-SRV'                # 名称
    metrics_path: "/metrics"            # 获取数据的路径
    dns_sd_configs:                     # 配置使用DNS解析
    - names: ['_prometheus._tcp.example.com']   # 配置SRV对应的解析地址

这个时候在targets中可以看到DNS自动发现的记录了。

这个时候,我们在新加一个记录,用来做自动发现。

# 添加test0解析
cat /etc/dnsmasq.d/localdomain.conf
address=/test1.example.com/192.168.1.221
address=/test2.example.com/192.168.1.222
address=/test0.example.com/192.168.1.220

# 添加 test0 SRV 记录
cat /etc/dnsmasq.conf
srv-host =_prometheus._tcp.example.com,test1.example.com,29100
srv-host =_prometheus._tcp.example.com,test2.example.com,29100
srv-host =_prometheus._tcp.example.com,test0.example.com,19100

# 验证dns SRV记录是否成功
dig @192.168.1.123 +noall +answer SRV _prometheus._tcp.example.com
_prometheus._tcp.example.com. 0	IN	SRV	0 0 19100 test0.example.com.
_prometheus._tcp.example.com. 0	IN	SRV	0 0 29100 test2.example.com.
_prometheus._tcp.example.com. 0	IN	SRV	0 0 29100 test1.example.com.

168.1.123 +noall +answer SRV _prometheus._tcp.example.com
_prometheus._tcp.example.com. 0 IN SRV 0 0 19100 test0.example.com.
_prometheus._tcp.example.com. 0 IN SRV 0 0 29100 test2.example.com.
_prometheus._tcp.example.com. 0 IN SRV 0 0 29100 test1.example.com.


这个时候在去观察targets就发现已经可以自动发现test0了。
上一篇:Prometheus Operator使用ServiceMonitor自定义监控


下一篇:Android IO、序列化、dex 随记