可靠的采集神器(自动发现使用场景介绍与Prometheus基于文件、DNS进行发现)
优采云 发布时间: 2021-12-13 21:16可靠的采集神器(自动发现使用场景介绍与Prometheus基于文件、DNS进行发现)
本章主要讲自动发现使用场景介绍和Prometheus基于文件和DNS的自动发现配置
当我们使用各种exporter分别监控系统、数据库、HTTP服务时,我们使用Prometheus的静态配置函数static_configs来监控所有监控指标对应的Target的运行状态和资源使用情况。
手动添加主机IP和端口,然后重新加载Prometheus要发现的服务。
对于服务器数量相对较少的测试环境,这种手动添加配置信息的方法是最简单的方法。但是,在实际生产环境中,对于数百个节点组成的大型集群或者Kubernetes这样的大型集群来说,手工方式显然被拉长了。
为此,Prometheus 提前设计了一套服务发现功能。
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)来动态配置这些节点。当然,除了实际场景中的基础设施监控需求,我们还需要监控部署在云上的各种服务,例如应用程序和中间件。实施这种集中监控系统的成本和难度是显而易见的。
对于Prometheus这个基于Pull模式的监控系统,显然不能继续使用static_configs方法来静态定义监控目标。对于 Prometheus,解决方案是引入一个中间代理(服务注册中心)。该代理持有当前所有监控目标的访问信息。Prometheus 只需要询问代理有哪些监控目标控件可用。这种模型称为服务发现。
服务转移
在不同的场景下,不同的东西会扮演代理(服务发现和注册中心)的角色。比如在AWS公有云平台或者OpenStack私有云平台中,由于这些平台自己控制着所有的资源信息,所以这些云平台此时自己就扮演了代理的角色。Prometheus 可以通过平台提供的 API 找到所有需要监控的云主机。在Kubernetes这样的容器管理平台中,Kubernetes掌握和管理着所有的容器和服务信息。这时候Prometheus只需要和Kubernetes打交道,就可以找到所有需要监控的容器和服务对象。Prometheus 也可以直接与一些开源服务发现工具集成。比如在微服务架构应用中,经常使用Consul等服务发现注册软件。Promethues 还可以与其集成,以动态发现需要监控的应用程序。服务实例。Prometheus除了可以与这些平台级的公有云、私有云、容器云、专门的服务发现注册中心集成,还支持基于DNS和文件的监控目标动态发现,大大减少了云原生、微服务的数量以及云模式下监控实施的难度。
推拉推
如上图,展示了Push系统和Pull系统的核心区别。与Push模式相比,Pull模式的优势可以简单总结如下:
基于文件的服务发现
在 Prometheus 支持的众多服务发现实现中,基于文件的服务发现是最常见的方式。这种方法不需要依赖任何平台或第三方服务。Prometheus 不可能支持所有平台或环境。在基于文件的服务发现模式下,Prometheus 会定期从文件中读取最新的 Target 信息。因此,您可以通过任何方式写入监控 Target 信息。
用户可以通过 JSON 或 YAML 格式的文件定义所有监控目标。比如下面的yaml文件中定义了两个采集任务,每个任务对应的目标列表:
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 配置文件 /data/prometheus/conf/prometheus-file-sd.yml 并添加以下内容:
- job_name: 'file_sd_test'
scrape_interval: 10s
file_sd_configs:
- files:
- /data/prometheus/static_conf/*.yml
- /data/prometheus/static_conf/*.json
这里定义了一个基于file_sd_configs的监控采集test任务,模式的任务名称是file_sd_test。在 yml 文件中,可以使用 yaml 标签覆盖默认的作业名称,然后重新加载 Prometheus 服务。
service prometheus restat
在Prometheus UI的Targets下,可以看到targets.json文件中动态获取的目标实例信息以及监控任务的采集状态。同时,在Labels栏下,会有用户添加的自定义标签:
file_sd_-test
Prometheus 默认每 5m 重新读取一次文件内容。当需要修改时,可以通过refresh_interval进行设置,例如:
- job_name: 'file_sd_test'
scrape_interval: 10s
file_sd_configs:
- refresh_interval: 30s # 30s重载配置文件
files:
- /data/prometheus/static_conf/*.yml
- /data/prometheus/static_conf/*.json
这样,Prometheus 会定期自动读取文件内容。当文件中定义的内容发生变化时,无需重启Prometheus。
这种通用的方式可以衍生出很多不同的玩法,比如结合自动化配置管理工具(Ansible),结合Cron Job等等。对于一些Prometheus不支持的云环境,比如国内的阿里云、腾讯云等,也可以使用这种方式通过一些自定义程序与平台交互,自动生成监控Target文件,从而实现基础架构在这些云环境中。自动监控支持。
基于 DNS 的发现
对于某些环境,当文件和领事服务发现不能再满足时,我们可能需要 DNS 来进行服务发现。在互联网架构中,我们通常使用不对外暴露IP的主机节点或Kubernetes集群。这就需要我们在内部局域网或专用网络中部署DNS服务器,利用DNS服务完成内部网络的域名解析工作。
这时候我们就可以使用Prometheus DNS服务发现了。Prometheus DNS 服务发现有两种方法。第一种方法是使用 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
普罗米修斯配置
# 基于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-a
DNS SRV是DNS资源记录中的一种记录类型,用于指定服务器地址和端口,可以设置每个服务器的优先级和权重。本地DNS解析器在访问服务时,从DNS服务器获取地址列表,然后根据优先级和权重选择一个地址作为本次请求的目标地址。
SRV记录格式:
_service._proto.name。TTL 类 SRV 优先权重端口目标
范围
操作说明
_服务
服务名,前缀_是为了防止与DNS标签(域名)冲突
原型
服务使用的通信协议通常是tcp udp
名称
此记录的有效域名
TTL
标准 DNS 类字段,例如 IN
优先事项
记录优先级,值越小,优先级越高。0-65535
重量
记录重量,数值越大,重量越高。0-65535
港口
服务端口
目标
使用服务的主机地址名称
这里不使用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对应的解析地址
这时候就可以在target中看到DNS自动发现的记录了。
DNS-SRV
此时,我们正在添加一条新的自动发现记录。
# 添加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.
这时候观察target,就会发现test0是可以自动找到的。
DNS-SRV-1