本章节主要讲自动发现使用场景介绍与Prometheus基于文件、DNS的自动发现配置.php
当咱们使用各种exporter分别对系统、数据库和HTTP服务进行监控指标采集,对于全部监控指标对应的Target的运行状态和资源使用状况,都是用Prometheus的静态配置功能 static_configs
来 手动添加主机IP和端口,而后重载服务让Prometheus发现。数据库
对于一组比较少的服务器的测试环境中,这种手动方式添加配置信息是最简单的方法。可是实际生产环境中,对于成百上千的节点组成的大型集群又或者Kubernetes这样的大型集群,很明显,手动方式捉襟见肘了。为此,Prometheus提早已经设计了一套服务发现功能。json
Prometheus 服务发现可以自动检测分类,而且可以识别新节点和变动节点。也就是说,能够在容器或者云平台中,自动发现并监控节点或更新节点,动态的进行数据采集和处理。目前 Prometheus 已经支持了不少常见的自动发现服务,好比 consul
ec2
gce
serverset_sd_config
openStack
kubernetes
等等。咱们经常使用的就是sd_config、DNS、kubernetes、consul这些足够了。若是有须要其余配置的探讨,能够与我交流,我能够补上来。服务器
本章节中会对Prometheus自动发现中的基于文件、DNS进行发现讲解,consul
在后面会单独展开来说,如何可使其完美的解决当前场景下常见的各种服务发现监控。网络
在基于云(IaaS或者CaaS)的基础设施环境中用户能够像使用水、电同样按需使用各类资源(计算、网络、存储)。按需使用就意味着资源的动态性,这些资源能够随着需求规模的变化而变化。例如在AWS中就提供了专门的AutoScall服务,能够根据用户定义的规则动态地建立或者销毁EC2实例,从而使用户部署在AWS上的应用能够自动的适应访问规模的变化。架构
这种按需的资源使用方式对于监控系统而言就意味着没有了一个固定的监控目标,全部的监控对象(基础设施、应用、服务)都在动态的变化。对于Nagias这类基于Push模式传统监控软件就意味着必须在每个节点上安装相应的Agent程序,而且经过配置指向中心的Nagias服务,受监控的资源与中心监控服务器之间是一个强耦合的关系,要么直接将Agent构建到基础设施镜像当中,要么使用一些自动化配置管理工具(如Ansible、Chef)动态的配置这些节点。固然实际场景下除了基础设施的监控需求之外,咱们还须要监控在云上部署的应用,中间件等等各类各样的服务。要搭建起这样一套中心化的监控系统实施成本和难度是显而易见的。app
而对于Prometheus这一类基于Pull模式的监控系统,显然也没法继续使用的static_configs的方式静态的定义监控目标。而对于Prometheus而言其解决方案就是引入一个中间的代理人(服务注册中心),这个代理人掌握着当前全部监控目标的访问信息,Prometheus只须要向这个代理人询问有哪些监控目标控便可, 这种模式被称为服务发现。dom
在不一样的场景下,会有不一样的东西扮演者代理人(服务发现与注册中心)这一角色。好比在AWS公有云平台或者OpenStack的私有云平台中,因为这些平台自身掌握着全部资源的信息,此时这些云平台自身就扮演了代理人的角色。Prometheus经过使用平台提供的API就能够找到全部须要监控的云主机。在Kubernetes这类容器管理平台中,Kubernetes掌握并管理着全部的容器以及服务信息,那此时Prometheus只须要与Kubernetes打交道就能够找到全部须要监控的容器以及服务对象。Prometheus还能够直接与一些开源的服务发现工具进行集成,例如在微服务架构的应用程序中,常常会使用到例如Consul这样的服务发现注册软件,Promethues也能够与其集成从而动态的发现须要监控的应用服务实例。除了与这些平台级的公有云、私有云、容器云以及专门的服务发现注册中心集成之外,Prometheus还支持基于DNS以及文件的方式动态发现监控目标,从而大大的减小了在云原生,微服务以及云模式下监控实施难度。tcp
如上所示,展现了Push系统和Pull系统的核心差别。相较于Push模式,Pull模式的优势能够简单总结为如下几点:ide
只要Exporter在运行,你能够在任何地方(好比在本地),搭建你的监控系统;
你能够更容易的查看监控目标实例的健康状态,而且能够快速定位故障;
更利于构建DevOps文化的团队;
松耦合的架构模式更适合于云原生的部署环境。
在Prometheus支持的众多服务发现的实现方式中,基于文件的服务发现是最通用的方式。这种方式不须要依赖于任何的平台或者第三方服务。对于Prometheus而言也不可能支持全部的平台或者环境。经过基于文件的服务发现方式下,Prometheus会定时从文件中读取最新的Target信息,所以,你能够经过任意的方式将监控Target的信息写入便可。用户能够经过JSON或者YAML格式的文件,定义全部的监控目标。例如,在下面的yaml文件中分别定义了2个采集任务,以及每一个任务对应的Target列表:
yaml格式
- targets: ['192.168.1.220:9100']labels:app: 'app1'env: 'game1'region: 'us-west-2'- targets: ['192.168.1.221:9100']labels:app: 'app2'env: 'game2'region: 'ap-southeast-1'
json格式
[{"targets": [ "192.168.1.221:29090"],"labels": {"app": "app1","env": "game1","region": "us-west-2"}},{"targets": [ "192.168.1.222:29090" ],"labels": {"app": "app2","env": "game2","region": "ap-southeast-1"}}]
同时还能够经过为这些实例添加一些额外的标签信息,例如使用env标签标示当前节点所在的环境,这样从这些实例中采集到的样本信息将包含这些标签信息,从而能够经过该标签按照环境对数据进行统计。
在Prometheus配置文件中添加如下内容:
- job_name: 'file_sd_test'scrape_interval: 10sfile_sd_configs:- files:- /data/prometheus/static_conf/*.yml- /data/prometheus/static_conf/*.json
这里定义了一个基于file_sd_configs的监控采集test任务,其中模式的任务名称为file_sd_test。在yml文件中可使用yaml标签覆盖默认的job名称,而后重载Prometheus服务。
service prometheus restat
在Prometheus UI的Targets下就能够看到当前从targets.json文件中动态获取到的Target实例信息以及监控任务的采集状态,同时在Labels列下会包含用户添加的自定义标签:
Prometheus默认每5m从新读取一次文件内容,当须要修改时,能够经过refresh_interval进行设置,例如:
- job_name: 'file_sd_test'scrape_interval: 10sfile_sd_configs:- refresh_interval: 30s # 30s重载配置文件files:- /data/prometheus/static_conf/*.yml- /data/prometheus/static_conf/*.json
经过这种方式,Prometheus会自动的周期性读取文件中的内容。当文件中定义的内容发生变化时,不须要对Prometheus进行任何的重启操做。
这种通用的方式能够衍生了不少不一样的玩法,好比与自动化配置管理工具(Ansible)结合、与Cron Job结合等等。对于一些Prometheus还不支持的云环境,好比国内的阿里云、腾讯云等也可使用这种方式经过一些自定义程序与平台进行交互自动生成监控Target文件,从而实现对这些云环境中基础设施的自动化监控支持。
对于一些环境,可能基于文件与consul服务发现已经没法知足的时候,咱们可能就须要DNS来作服务发现了。在互联网架构中,咱们使用主机节点或者Kubernetes集群一般是不对外暴露IP的,这就要求咱们在一个内部局域网或者专用的网络中部署DNS服务器,使用DNS服务来完成内部网络中的域名解析工做。这个时候咱们就可使用Prometheus的DNS服务发现,Prometheus的DNS服务发现有俩种方法,第一种是使用DNA A记录来作自动发现,第二种方法是DNS SRV,第一种显然没有没有SRV资源记录更为便捷,在这里就把俩种配置所有作一遍,对于取决用什么,根据你本身的环境来抉择。
DNA A记录发现配置,首先你内网须要有一个DNS服务器,或者直接自行配置解析记录便可,我这里使用的dnsmasq服务在内网测试
# 验证 test1 DNS记录nslookup test1.example.comServer: 127.0.0.53Address: 127.0.0.53#53
Non-authoritative answer:Name: test1.example.comAddress: 192.168.1.221# 验证 test2 DNS记录nslookup test2.example.comServer: 127.0.0.53Address: 127.0.0.53#53
Non-authoritative answer:Name: test2.example.comAddress: 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 # 端口
重启Prometheus 在targets中能够看到dns-a记录
DNS SRV是DNS资源记录中的一种记录类型,用来指定服务器地址与端口,而且能够设置每一个服务器的优先级和权重。访问到服务的时候,本地的DNS resolver 从DNS服务器获取一个地址列表,而后根据优先级和权重来选择一个地址做为本次请求的目标地址。
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.confaddress=/test1.example.com/192.168.1.221address=/test2.example.com/192.168.1.222# 添加 SRV 记录cat /etc/dnsmasq.confsrv-host =_prometheus._tcp.example.com,test1.example.com,29100srv-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.comoutput..._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.confaddress=/test1.example.com/192.168.1.221address=/test2.example.com/192.168.1.222address=/test0.example.com/192.168.1.220
# 添加 test0 SRV 记录cat /etc/dnsmasq.confsrv-host =_prometheus._tcp.example.com,test1.example.com,29100srv-host =_prometheus._tcp.example.com,test2.example.com,29100srv-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.
这个时候在去观察targets就发现已经能够自动发现test0了。