软文一件采集器(自动发现使用场景介绍与Prometheus基于文件、DNS的应用 )
优采云 发布时间: 2022-01-17 07:14软文一件采集器(自动发现使用场景介绍与Prometheus基于文件、DNS的应用
)
本章主要讲自动发现使用场景的介绍以及Prometheus中基于文件和DNS的自动发现的配置
当我们使用各种exporter监控系统、数据库和HTTP服务指标采集时,所有监控指标对应的目标运行状态和资源使用情况都是使用Prometheus的静态配置函数static_configs来实现的
手动添加主机 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等服务发现注册软件。Prometheus 也可以与其集成,动态发现需要监控的应用。服务实例。Prometheus除了与这些平台级公有云、私有云、容器云、专用服务发现注册中心集成外,还支持DNS和基于文件的监控目标动态发现,大大降低了对云原生、微服务和监控的需求云模式的实施难度。
如上图,Push 系统和 Pull 系统的核心区别就展示出来了。与Push模式相比,Pull模式的优势可以简单总结如下:
基于文件的服务发现
在 Prometheus 支持的众多服务发现实现中,基于文件的服务发现是最常见的。这种方法不需要依赖任何平台或第三方服务。Prometheus 也不可能支持所有平台或环境。在基于文件的服务发现模式下,Prometheus 会定期从文件中读取最新的 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 配置文件 /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的监控采集测试任务,其中模式的任务名称为file_sd_test。在 yml 文件中,可以使用 yaml 标签覆盖默认的作业名,然后重新加载 Prometheus 服务。
service prometheus restat
在 Prometheus UI 的 Targets 下,可以看到从 targets.json 文件中动态获取的当前 Target 实例信息以及监控任务的 采集 状态。同时,Labels 列会收录用户添加的自定义标签:
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 的发现
对于某些环境,当无法满足基于文件和consul的服务发现时,我们可能需要DNS来进行服务发现。在 Internet 架构中,我们通常使用主机节点或 Kubernetes 集群,而不会将 IP 暴露给外界,这就需要我们在内部局域网或专用网络中部署 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 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对应的解析地址
此时可以在targets中看到DNS auto-discovery的记录。
目前,我们正在为自动发现添加新记录。
# 添加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.
这时候我去观察targets的时候,发现test0可以被自动发现了。