Prometheus基于Consul服务发现

1、简介

在前面的文章中,我们介绍了Prometheus基于文件的服务发现方式。这种方式简单易懂,对于小型企业而言,可以较好地满足使用需求。

但在大规模的监控环境中,基于文件的方式往往会面临较多的挑战。首先,由于有大量的实例需要进行监控,运维人员得频繁地对 Prometheus 配置文件进行修改,这会给工作带来很大的负担,同时也容易出现人为的失误。

另外,在大型企业中往往会有细致的分工,服务器部署与监控的管理可能是由不同的团队成员在负责,每当实例部署完成后还需要在人员之间进行信息的传递,这更进一步增加了操作的复杂性。对此,Prometheus提供了多种动态服务发现的功能,而基于Consul的服务发现即是其中较为常见的一种方案。

2、特点

  • 服务发现和健康检查: Consul提供了可靠的服务发现功能,使应用程序能够注册和发现其他服务,无需硬编码位置信息。它还支持自定义健康检查,定期验证服务的可用性,自动将不健康的服务实例从目录中移除,确保流量只路由到可用的实例。
  • 多数据中心支持: Consul内置了对多个数据中心的本地和全局支持。这使得在不同地理位置部署的应用程序能够轻松地发现和通信,同时提供高可用性和冗余性。多数据中心支持是构建全球性应用程序的关键特性。
  • 分布式键值存储: Consul包含一个分布式键值存储系统,用于存储配置信息、共享数据和应用程序参数。这个键值存储是一种灵活的方式,用于动态配置管理和共享关键数据,有助于简化应用程序的配置和部署。
  • 与其他工具的集成: Consul与许多其他流行的工具和技术集成得很好,包括Prometheus、Docker、Kubernetes等。这意味着您可以轻松地将Consul与现有的监控、容器化和编排解决方案相结合使用,构建完整的分布式应用程序堆栈。

3、Consul工作原理

图片
  • 首先Consul支持多数据中心,在上图中有两个DataCenter,他们通过Internet互联,同时请注意为了提高通信效率,只有Server节点才加入跨数据中心的通信。
  • 在单个数据中心中,Consul分为Client和Server两种节点(所有的节点也被称为Agent),Server节点保存数据,Client负责健康检查及转发数据请求到Server;Server节点有一个Leader和多个Follower,Leader节点会将数据同步到Follower,Server的数量推荐是3个或者5个,在Leader挂掉的时候会启动选举机制产生一个新的Leader。
  • 集群内的Consul节点通过gossip协议(流言协议)维护成员关系,也就是说某个节点了解集群内现在还有哪些节点,这些节点是Client还是Server。单个数据中心的流言协议同时使用TCP和UDP通信,并且都使用8301端口。跨数据中心的流言协议也同时使用TCP和UDP通信,端口使用8302。
  • 集群内数据的读写请求既可以直接发到Server,也可以通过Client使用RPC转发到Server,请求最终会到达Leader节点,在允许数据轻微陈旧的情况下,读请求也可以在普通的Server节点完成,集群内数据的读写和复制都是通过TCP的8300端口完成。

4、Consul服务发现原理

图片
  • 首先需要有一个正常的Consul集群,有Server,有Leader。这里在服务器Server1、Server2、Server3上分别部署了Consul Server,假设他们选举了Server2上的Consul Server节点为Leader。这些服务器上最好只部署Consul程序,以尽量维护Consul Server的稳定。
  • 然后在服务器Server4和Server5上通过Consul Client分别注册Service A、B、C,这里每个Service分别部署在了两个服务器上,这样可以避免Service的单点问题。服务注册到Consul可以通过HTTP API(8500端口)的方式,也可以通过Consul配置文件的方式。Consul Client可以认为是无状态的,它将注册信息通过RPC转发到Consul Server,服务信息保存在Server的各个节点中,并且通过Raft实现了强一致性。
  • 最后在服务器Server6中Service D需要访问Service B,这时候Service D首先访问本机Consul Client提供的HTTP API,本机Client会将请求转发到Consul Server,Consul Server查询到Service B当前的信息返回,最终Service D拿到了Service B的所有部署的IP和端口,然后就可以选择Service B的其中一个部署并向其发起请求了。如果服务发现采用的是DNS方式,则Service D中直接使用Service B的服务发现域名,域名解析请求首先到达本机DNS代理,然后转发到本机Consul Client,本机Client会将请求转发到Consul Server,Consul Server查询到Service B当前的信息返回,最终Service D拿到了Service B的某个部署的IP和端口。

5、Docker部署Consul

[root@node1 ~]# docker run -d --name consul -p 8500:8500 consul:1.6.1
图片

6、配置Prometheus

[root@node1 prometheus]# grep -v '^s*#|^s*$' prometheus.yml
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
alerting:
alertmanagers:
   - static_configs:
       - targets:
rule_files:
scrape_configs:
 - job_name: "prometheus"
  static_configs:
     - targets: ["localhost:9090"]
 - job_name: 'Mysql Server'
  static_configs:
     - targets: ['124.221.97.88:9104']
     
#添加配置
 - job_name: 'consul'
  consul_sd_configs:
   - server: 117.50.163.139:8500
      services: []
     
[root@node1 prometheus]# ./promtool check config prometheus.yml
Checking prometheus.yml
SUCCESS: prometheus.yml is valid prometheus config file syntax

#热加载
[root@node1 prometheus]# ps -ef|grep prometheus
root      9406  6260  0 17:27 pts/0    00:00:00 grep --color=auto prometheus
root     16093     1  0 Sep08 ?        00:04:43 /opt/monitor/prometheus/prometheus --config.file=/opt/monitor/prometheus/prometheus.yml
[root@node1 prometheus]# kill -HUP 16093

7、Consul注册服务

[root@node1 prometheus]# curl -X PUT -d '{"id": "Linux-1","name": "Linux","address": "124.221.97.88","port": 
9100,"tags": ["service"],"checks": [{"http": "http://124.221.97.88:9100","interval": 
"5s"}]}' http://117.50.163.139:8500/v1/agent/service/register
图片

监控已添加

其中8300端口,是Consul集群中节点之间进行通信、维护一致性和管理成员的关键端口。(默认自带)

图片

8、实战:Ansible+Consul实现主机自动监控

配置Prometheus

[root@node1 prometheus]# grep -v '^s*#|^s*$' prometheus.yml
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
alerting:
alertmanagers:
   - static_configs:
       - targets:
rule_files:
scrape_configs:

#添加配置
 - job_name: 'webservers'
  consul_sd_configs:
   - server: 117.50.163.139:8500
    services: ["webservers"]

操作步骤

  • ansible批量部署node_export
  • 基于consul的服务发现
  • 将node_exporter所在机器的ip和端口注册到consul里面
  • Prometheus从consul获取所有ip和端口自动加入监控

目录结构

[root@node1 ansible]# ls
consul_register.sh   hosts node_exporter-1.6.1.linux-amd64.tar.gz node_exporter.service playbook.yml

- consul_register.sh  #consul注册脚本
- hosts  #主机列表
- node_exporter-1.6.1.linux-amd64.tar.gz  #安装包
- node_exporter.service  #systemctl启动脚本
- playbook.yml  #工作流程

注册脚本

[root@node1 ansible]# vim consul_register.sh
#!/bin/bash
#!/bin/bash
service_name=$1
instance_id=$2
ip=$3
port=$4

curl -X PUT -d '{"id": "'"$instance_id"'","name": "'"$service_name"'","address": "'"$ip"'","port": "'"$port"'","tags": ["'"$service_name"'"],"checks": [{"http": "http://'"$ip"':'"$port"'","interval": "5s"}]}'http://117.50.163.139:8500/v1/agent/service/register

主机列表(后期只需在主机列表添加机器即可)

[root@node1 ansible]# vim hosts
[webservers]
124.221.97.88  name=web1

启动脚本

[root@node1 ansible]# vim node_exporter.service
[Unit]
Description=node_exporter
[Service]
ExecStart=/usr/local/node_exporter/node_exporter
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target

流程设计

[root@node1 ansible]# vim playbook.yml
- hosts: webservers
gather_facts: no
tasks:
 - name: push node_exporter
  unarchive:
    src: node_exporter-1.6.1.linux-amd64.tar.gz
    dest: /usr/local
 - name: rename
  shell: |
     cd /usr/local
     if [ ! -d node_exporter ]
       then mv node_exporter-1.6.1.linux-amd64 node_exporter
     fi
 - name: copy systemd content
  copy:
    src: node_exporter.service
    dest: /usr/lib/systemd/system
 - name: start node_exporter
  systemd:
    name: node_exporter
    state: restarted
    enabled: yes
    daemon-reload: yes
 - name: push consul_register.sh
  copy:
    src: consul_register.sh
    dest: /usr/local/bin
 - name: register nodes into consul
  shell: /bin/bash /usr/local/bin/consul_register.sh {{ group_names[0] }} {{ name }} {{ inventory_hostname }} {{ 9100 }}

执行命令

[root@node1 ansible]# ansible-playbook -i hosts playbook.yml

PLAY [webservers] **********************************************************************

TASK [push node_exporter] **************************************************************
ok: [124.221.97.88]

TASK [rename] **************************************************************************
changed: [124.221.97.88]

TASK [copy systemd content] ************************************************************
ok: [124.221.97.88]

TASK [start node_exporter] *************************************************************
changed: [124.221.97.88]

TASK [push consul_register.sh] *********************************************************
changed: [124.221.97.88]

TASK [register nodes into consul] ******************************************************
changed: [124.221.97.88]

PLAY RECAP *****************************************************************************
124.221.97.88             : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

查看服务

图片

声明:文中观点不代表本站立场。本文传送门:http://eyangzhen.com/317167.html

(0)
联系我们
联系我们
分享本页
返回顶部