💫《博主主页》:
🔎 CSDN主页__奈斯DB
🔎 IF Club社区主页__奈斯、
🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(Redis)有了解
💖如果觉得文章对你有所帮助,欢迎点赞收藏加关注💖
看过我之前文章的小伙伴都清楚,在之前介绍过 [基于Prometheus+Grafana实现MySQL数据库的监控与可视化 ]
的文章,这篇文章主要是监控MySQL数据库和主从复制,但当数据库升级为高可用架构后,监控策略也需要随之升级!🔝
在运营商、金融、电商等关键业务场景中,MySQL高可用架构(如MGR、MHA、Keepalived+HA、InnoDB Cluster等)是保障"一年五个九"(99.999%可用性)的核心支柱。那么在众多MySQL高可用架构中,Keepalived+HA是实现MySQL高可用中最常见的一种方案,只需要两台服务器就可以实现MySQL的高可用,因此实时监控高可用架构状态是非常重要的一环。
那么接下来这篇文章将聚焦Keepalived+HA高可用架构,通过Prometheus打造全方位的监控体系!🚀
特别说明💥:
⚡监控MySQL HA实现如下告警
- ✅ Keepalived 服务已停止
- ✅ 主节点虚拟IP不可达
- ✅ 虚拟IP漂移到备节点
prometheus+Grafana全系列文章(实时更新🔥):
MySQL HA高可用架构信息如下:
角色 VIP IP地址 类型 HA主 110.120.100.48 110.120.100.46 读写 HA备 110.120.100.47 读(备用)
那么从上面的架构图可以推断出主库和从库分别都应该监控哪些内容:
主库:
- 监控主库上的keepalived监控
- 主节点需要检查虚拟 IP 是否不存在:正常情况下keepalived的VIP只能存在于主库上,而不能存在于除了主库的其他任意节点上
从库:
- 监控从库上的keepalived监控
- 备节点需要检查虚拟 IP 是否存在:正常情况下keepalived的VIP地址是在主节点上的,如果在从节点发现了VIP,就进行告警。这样的好处在于可以马上知晓VIP漂移到了从节点上,也可以监控是否出现了脑裂问题,如果出现了脑裂能马上进行干预和处理。PS提示:Keepalived的BACKUP主机在收到不MASTER主机报文后就会切换成为master,如果是它们之间的通信线路出现问题,无法接收到彼此的组播通知,但是两个节点实际都处于正常工作状态,这时两个节点均为master强行绑定虚拟IP,导致不可预料的后果,这就是脑裂。
现在知道了该监控哪些内容,那么开始如下配置。
一、HA主
1)编辑监控keepalived+VIP进程脚本
[root@mysql-db1 ~]# mkdir -p /opt/prometheus [root@mysql-db1 ~]# cd /opt/prometheus/ [root@mysql-db1 ~]# mkdir keepalived_exporter [root@mysql-db1 ~]# cd keepalived_exporter [root@mysql-db1 keepalived_exporter]# vi keepalived_monitor.py from flask import Flask, Response import subprocess import os app = Flask(__name__) @app.route('/metrics') def metrics(): # 检查 keepalived 服务状态 result = subprocess.run(['systemctl', 'is-active', 'keepalived'], stdout=subprocess.PIPE) keepalived_status = 1 if result.stdout.decode().strip() == 'active' else 0 # 检查虚拟 IP 是否存在于本机 ip_address = '110.120.100.48' result = subprocess.run(['ip', 'addr', 'show'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ip_status = 1 if ip_address in result.stdout.decode() else 0 # 返回 Prometheus 格式的指标 metrics_data = '# HELP keepalived_status 状态,1表示keepalived服务正在运行,0表示未运行\n' metrics_data += '# TYPE keepalived_status gauge\n' metrics_data += f'keepalived_status {keepalived_status}\n' # 检查 keepalived 服务状态 metrics_data += f'# HELP ip_reachability_primary{{ip="{ip_address}"}} 虚拟IP是否存在,1表示存在,0表示不存在\n' # 根据节点角色设置 Prometheus 格式的指标。主节点需要检查虚拟 IP 是否不存在,定义的指标项为ip_reachability_primary;备节点需要检查虚拟 IP 是否存在,定义的指标项为ip_reachability_secondary metrics_data += '# TYPE ip_reachability_primary gauge\n' metrics_data += f'ip_reachability_primary{{ip="{ip_address}"}} {ip_status}\n' return Response(metrics_data, mimetype='text/plain') if __name__ == '__main__': app.run(host='0.0.0.0', port=4399) # 监听 4399 端口
###脚本实现了两个监控:
- 检查了 keepalived 服务状态
- 检查了虚拟 IP 是否存在于本机,根据节点角色设置 Prometheus 格式的指标。主节点需要检查虚拟 IP 是否不存在,定义的指标项为ip_reachability_primary;备节点需要检查虚拟 IP 是否存在,定义的指标项为ip_reachability_secondary。虚拟ip是一个在主备节点之间共享的虚拟IP地址,永远只存在于同一个virtual_router_id组中的主节点上。也是就说监控主节点上ip是否不存在,备节点监控ip是否存在
###在如上脚本中,只需要将
ip_address = '110.120.100.48'
这里的IP替换为实际的VIP,其他地方不需要有任何变更
2)安装python和Prometheus所需依赖包
安装Python:通过yum进行安装。监控脚本是通过python实现的,因此需要安装python3,用于运行keepalived_monitor.py监控脚本
[root@mysql-db1 ~]# yum install python3 [root@mysql-db1 ~]# python3 --version
安装Flask:将Flask相关包上传至Linux的/software/Flask目录下。这里安装flask是因为在keepalived_monitor.py监控脚本中使用了 Flask 的以下关键组件
组件 用途 必要性 Flask 创建轻量级Web服务器 ✅ 必须 @app.route 暴露 /metrics 端点供Prometheus抓取 ✅ 必须 Response 返回符合Prometheus格式的监控数据 ✅ 必须 flask相关包博主已打包上传至资源,需要的小伙伴直接下载即可
[root@mysql-db1 ~]# cd /software [root@mysql-db1 ~]# unzip flask.zip [root@mysql-db1 ~]# cd flask [root@mysql-db1 ~]# pip3 install *.whl
PS小提示:如果不安装Flask。那么通过python3运行keepalived_monitor.py脚本时会报如下错误:
3)将监控脚本写入到linux启动服务项
[root@mysql-db1 ~]# cd /usr/lib/systemd/system [root@mysql-db1 ~]# vi keepalived_monitor.service [Unit] Description=Keepalived Monitor Script After=network.target [Service] Type=simple ExecStart=/usr/bin/python3 /opt/prometheus/keepalived_exporter/keepalived_monitor.py WorkingDirectory=/opt/prometheus/keepalived_exporter/ Restart=always Environment=PATH=/usr/bin:/usr/local/bin:/usr/sbin Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target [root@mysql-db1 ~]# systemctl daemon-reload [root@mysql-db1 ~]# systemctl start keepalived_monitor.service [root@mysql-db1 ~]# systemctl enable keepalived_monitor.service [root@mysql-db1 ~]# systemctl status keepalived_monitor.service
二、HA备
1)编辑监控keepalived+VIP进程脚本
[root@mysql-db2 ~]# mkdir -p /opt/prometheus [root@mysql-db2 ~]# cd /opt/prometheus/ [root@mysql-db2 ~]# mkdir keepalived_exporter [root@mysql-db2 ~]# cd keepalived_exporter [root@mysql-db2 keepalived_exporter]# vi keepalived_monitor.py from flask import Flask, Response import subprocess import os app = Flask(__name__) @app.route('/metrics') def metrics(): # 检查 keepalived 服务状态 result = subprocess.run(['systemctl', 'is-active', 'keepalived'], stdout=subprocess.PIPE) keepalived_status = 1 if result.stdout.decode().strip() == 'active' else 0 # 检查虚拟 IP 是否存在于本机 ip_address = '110.120.100.48' result = subprocess.run(['ip', 'addr', 'show'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ip_status = 1 if ip_address in result.stdout.decode() else 0 # 返回 Prometheus 格式的指标 metrics_data = '# HELP keepalived_status 状态,1表示keepalived服务正在运行,0表示未运行\n' metrics_data += '# TYPE keepalived_status gauge\n' metrics_data += f'keepalived_status {keepalived_status}\n' # 检查 keepalived 服务状态 metrics_data += f'# HELP ip_reachability_secondary{{ip="{ip_address}"}} 虚拟IP是否存在,1表示存在,0表示不存在\n' # 根据节点角色设置 Prometheus 格式的指标。主节点需要检查虚拟 IP 是否不存在,定义的指标项为ip_reachability_primary;备节点需要检查虚拟 IP 是否存在,定义的指标项为ip_reachability_secondary metrics_data += '# TYPE ip_reachability_secondary gauge\n' metrics_data += f'ip_reachability_secondary{{ip="{ip_address}"}} {ip_status}\n' return Response(metrics_data, mimetype='text/plain') if __name__ == '__main__': app.run(host='0.0.0.0', port=4399) # 监听 4399 端口
###脚本实现了两个监控:
- 检查了 keepalived 服务状态
- 检查了虚拟 IP 是否存在于本机,根据节点角色设置 Prometheus 格式的指标。主节点需要检查虚拟 IP 是否不存在,定义的指标项为ip_reachability_primary;备节点需要检查虚拟 IP 是否存在,定义的指标项为ip_reachability_secondary。虚拟ip是一个在主备节点之间共享的虚拟IP地址,永远只存在于同一个virtual_router_id组中的主节点上。也是就说监控主节点上ip是否存在,备节点监控ip是否不存在
###在如上脚本中,只需要将
ip_address = '110.120.100.48'
这里的IP替换为实际的VIP,其他地方不需要有任何变更
2)安装python和Prometheus所需依赖包
安装Python:通过yum进行安装。监控脚本是通过python实现的,因此需要安装python3,用于运行keepalived_monitor.py监控脚本
[root@mysql-db2 ~]# yum install python3 [root@mysql-db2 ~]# python3 --version
安装Flask:将Flask相关包上传至Linux的/software/Flask目录下。这里安装flask是因为在keepalived_monitor.py监控脚本中使用了 Flask 的以下关键组件
组件 用途 必要性 Flask 创建轻量级Web服务器 ✅ 必须 @app.route 暴露 /metrics 端点供Prometheus抓取 ✅ 必须 Response 返回符合Prometheus格式的监控数据 ✅ 必须 flask相关包博主已打包上传至资源,需要的小伙伴直接下载即可
[root@mysql-db2 ~]# cd /software [root@mysql-db2 ~]# unzip flask.zip [root@mysql-db2 ~]# cd flask [root@mysql-db2 ~]# pip3 install *.whl
PS小提示:如果不安装Flask。那么通过python3运行keepalived_monitor.py脚本时会报如下错误:
3)将监控脚本写入到linux启动服务项
[root@mysql-db2 ~]# cd /usr/lib/systemd/system [root@mysql-db2 ~]# vi keepalived_monitor.service [Unit] Description=Keepalived Monitor Script After=network.target [Service] Type=simple ExecStart=/usr/bin/python3 /opt/prometheus/keepalived_exporter/keepalived_monitor.py WorkingDirectory=/opt/prometheus/keepalived_exporter/ Restart=always Environment=PATH=/usr/bin:/usr/local/bin:/usr/sbin Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target [root@mysql-db2 ~]# systemctl daemon-reload [root@mysql-db2 ~]# systemctl start keepalived_monitor.service [root@mysql-db2 ~]# systemctl enable keepalived_monitor.service [root@mysql-db2 ~]# systemctl status keepalived_monitor.service
三、添加MySQL HA到prometheus中
注意:如下操作是在安装了prometheus和Grafana的主机上进行操作
1)将MySQL HA的信息加入到prometheus监控的配置文件prometheus.yml中
[root@prometheus ~]# vi /opt/prometheus/prometheus.yml 在scrape_configs下面新增如下内容: # keepalived_exporter配置 - job_name: "MySQL keepalived status" ###job_name 用来唯一标识一个监控任务。在同一个 prometheus.yml 文件中,不同的 scrape_config可以有不同的job_name,以便 Prometheus 能够区分和管理不同的监控目标和配置,用来将不同的监控目标分组。单位为监控keepalived设置一个独立的job_name scrape_interval: 15s ###指定这个job_name每隔多久从每个目标(如 Exporter、应用端点)拉取一次指标数据。优先级:会覆盖全局的 global:scrape_interval(如果存在)。 file_sd_configs: - files: - /opt/prometheus/conf.d/keepalived_targets.json # keepalived需要监控的实例都单独写在了keepalived_targets.json文件中,是为了避免prometheus.yml内容过多,看起来更简洁 [root@prometheus ~]# vi /opt/prometheus/conf.d/keepalived_targets.json [ { "targets": [ "110.120.100.46:4399" ], "labels": { "instance": "数据库HA(keepalived)主库(IP:110.120.100.46)" } }, { "targets": [ "110.120.100.47:4399" ], "labels": { "instance": "数据库HA(keepalived)从库(IP:110.120.100.47)" } } ]
2)配置告警规则文件
除了如下告警规则之外,还需要单独配置一个Targets目标不可达(up)的相关规则,因为up 是一个布尔值指标,表示 Prometheus 是否能够成功地 scrape(抓取)到指定的目标(targets)数据,用于判断目标node-exporter相关进程是否在目标主机存活。关于up的规则文件参考:【prometheus+Grafana篇】从零开始:Linux 7.6 上二进制安装 Prometheus、Grafana 和 Node Exporter
[root@prometheus ~]# cd /opt/prometheus/rules/ ###在prometheus.yml文件中定义了告警规则文件rule_files参数 [root@prometheus rules]# vi keepalived_alerts.yml groups: - name: keepalived_alerts rules: - alert: KeepalivedDown expr: keepalived_status == 0 for: 3s labels: severity: critical annotations: summary: "Keepalived 服务已停止" description: "Keepalived 服务在 {{ $labels.instance }} 上停止运行,请立即通过systemctl status keepalived检查服务状态!" - alert: PrimaryIPReachabilityDown expr: ip_reachability_primary == 0 for: 3s labels: severity: critical annotations: summary: "主节点虚拟IP不可达" description: "主节点的虚拟 IP {{ $labels.ip }} 在 {{ $labels.instance }} 上不可达,请通过systemctl status keepalived检查服务状态,并且检查虚拟 IP 是否漂移到从库上!" - alert: secondaryIPReachabilityUp expr: ip_reachability_secondary == 1 for: 3s labels: severity: critical annotations: summary: "虚拟IP漂移到备节点" description: "虚拟 IP {{ $labels.ip }} 已从主节点漂移到 {{ $labels.instance }} ,需要人工干预将其转移回主节点上运行!"
3)检查配置文件
[root@prometheus ~]# cd /opt/prometheus/ [root@prometheus ~]# ./promtool check config prometheus.yml ###用于检查 Prometheus 配置文件(prometheus.yml)的语法和格式是否正确。
执行这条命令会执行以下操作:
- 验证配置文件的语法:检查 prometheus.yml 文件是否符合 Prometheus 配置格式规范。
- 检测潜在的错误或警告:如果配置文件中存在拼写错误、格式问题、无效的配置项等问题,它会提供相关的错误信息或警告。比如告警规则写的不对,就会有提示
- 输出有用的诊断信息:如果配置文件存在问题,promtool 会输出详细的错误信息。
4)prometheus.yml文件添加了信息,所以重启prometheus进程或者重新加载配置文件(二选一)
#重载:前提是在prometheus.service启动服务项中加了–web.enable-lifecycle参数:–web.enable-lifecycle:###启用Prometheus的生命周期接口,允许通过HTTP请求来动态重新加载配置等操作。这对于在运行时更新配置或执行其他管理操作非常有用,当修改了prometheus的配置后,可以通过curl命令来重新加载配置文件,而不需要重启prometheus(推荐方式)
[root@prometheus ~]# curl -X POST http://localhost:9090/-/reload
#重启
[root@prometheus ~]# systemctl restart prometheus.service
5)在prometheus查看是否可以看到监控信息
网址:http://110.120.100.21:9090
菜单栏:Status—Targets
四、模拟主库故障,查看告警
主库:
[root@mysql-db1 ~]# service mysqld stop触发如下告警
从库:触发如下告警
那么可以看到当主库故障时,监控到了主库上的keepalived故障,并且VIP发生了漂移,也收到了VIP在从库上的告警。那么后续就是先修复主库数据后,然后人工将VIP再切换到主库上就可以了,这里博主就不演示了