要在 Prometheus 中监控 IP 地址 192.168.123.123 是否在特定机器上,通常需要结合一些自定义的 Exporter 来提供这一信息,因为 Prometheus 本身不直接处理这类主机状态监控。下面是两个如何实现这一目标的完整方案:
使用py自定义脚本
自定义 Exporter
你可以编写一个简单的自定义 Exporter,该 Exporter 检查 IP 地址是否绑定在特定机器上,并将其状态暴露为 Prometheus 可以抓取的格式。以下是一个使用 Python 的示例:
示例 Python Exporter
安装 Prometheus 客户端库:
你需要安装 prometheus_client 库来创建自定义指标:
pip install prometheus_client
创建 Exporter 脚本:
编写一个 Python 脚本来检查 IP 地址的绑定状态,并将其暴露为 Prometheus 指标:
from prometheus_client import start_http_server, Gauge
import subprocess
import time
创建一个 Gauge 类型的指标
ip_check_gauge = Gauge('ip_check_status', '0 if IP 192.168.200.16 is bound to the machine, 1 otherwise')
def check_ip_binding(ip_address):
try:
# 使用 `ip` 命令检查 IP 地址绑定
result = subprocess.run(['ip', 'addr', 'show'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = result.stdout.decode('utf-8') # 手动解码为字符串
return ip_address in output
except subprocess.CalledProcessError as e:
print(f"Error executing 'ip addr show' command: {e}")
return False
except Exception as e:
print(f"Unexpected error: {e}")
return False
def main():
# 启动 HTTP 服务器,监听 19099 端口
start_http_server(19099)
print("Prometheus HTTP server started on port 19099")
while True:
# 检查 IP 地址绑定状态
ip_address = '192.168.200.16'
is_bound = check_ip_binding(ip_address)
ip_check_gauge.set(0 if is_bound else 1)
print(f"IP {ip_address} bound: {not is_bound}")
time.sleep(10) # 每 10 秒更新一次
if __name__ == '__main__':
main()
这个脚本将启动一个 HTTP 服务器,Prometheus 可以通过这个服务器的 /metrics 端点抓取到 ip_check_status 指标。
运行 Exporter:
保存这个脚本为 ip_exporter.py 并运行:
python3 ip_exporter.py
你的 Exporter 将在 http://localhost:8000/metrics 上提供指标数据。
配置 Prometheus
将你编写的 Exporter 配置为 Prometheus 的抓取目标。
编辑 Prometheus 配置文件(通常是 prometheus.yml):
scrape_configs:
- job_name: 'ip_exporter'
static_configs:
- targets: ['localhost:8000'] # 替换为你的 Exporter 地址
重新启动 Prometheus:
使配置生效,重新启动 Prometheus 服务。
sudo systemctl restart prometheus
可视化和警报设置
在Grafana 中可视化:
你可以在 Grafana 中创建一个面板,查询 ip_check_status 指标,并以图表或其他可视化方式显示结果。
在 Grafana 中添加 Prometheus 数据源。
创建一个新的仪表盘,并添加一个面板,选择 ip_check_status 指标来显示 IP 地址绑定状态。
设置警报:
可以设置 Prometheus 警报规则来监控 IP 地址的绑定状态,并在 IP 地址不绑定时发出警报。
groups:- name: ip_alerts
rules:
- alert: IPNotBound
expr: ip_check_status == 0
for: 5m
labels:
severity: critical
annotations:
summary: "IP 192.168.123.123 is not bound to the machine"
description: "The IP address 192.168.123.123 is not currently bound to the monitored machine."
将警报规则添加到 Prometheus 警报配置文件中,然后重启 Prometheus 服务以使其生效。
使用shell自定义脚本
vip-exporter配置支持自定义监控
在需要自定义监控的node上创建目录
在keepalive运行的机器上均要创建此目录
mkdir /apps/prometheus/textfile
修改node-exporter 配置支持自定义监控
vim node-exporter.yaml
如果原来有配置collector.textfile.directory,那就不用做以下操作
- name: textfile
mountPath: /apps/prometheus/textfile/
- name: textfile
hostPath:
path: /apps/prometheus/textfile
- --collector.textfile.directory=/apps/prometheus/textfile


判断脚本
vim /apps/prometheus/textfile/check_vip.sh
修改脚本中的变量,根据实际情况填写
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#cron 的执行环境与交互式 shell 环境有所不同,缺少一些配置或路径设置
DATE=$(date +%s)
VIP_ADDRESS="192.168.200.16"
checkStatus() {
echo "# HELP $1 check"
echo "# TYPE $1 gauge"
echo "$1{node_vip=\"$VIP_ADDRESS\"} $2"
}
IP_CMD="/sbin/ip"
if $IP_CMD addr show | grep -q "$VIP_ADDRESS"; then
IP_FOUND="1"
else
IP_FOUND="0"
fi
#VIP_status
checkStatus "keepalive_vip_status" "$IP_FOUND"
#update_time
checkStatus "keepalive_file_update_time" "$DATE"
chmod +x /apps/prometheus/textfile/check_vip.sh
启动定时任务
crontab -l
*/1 * * * * /apps/prometheus/textfile/check_vip.sh > /apps/prometheus/textfile/vip.prom
如果原来node-exporter.yaml有配置collector.textfile.directory,定时任务就输出到原来配置的路径下
cat /apps/prometheus/textfile/check_vip.prom
# HELP keepalive_vip_status check
# TYPE keepalive_vip_status gauge
keepalive_vip_status{node_vip="192.168.200.16"} 1
# HELP keepalive_file_update_time check
# TYPE keepalive_file_update_time gauge
keepalive_file_update_time{node_vip="192.168.200.16"} 1725852061
prometheus 页面查看监控指标
keepalive状态检测

告警项
keepalive脑裂:sum(keepalive_vip_status) by(vip) > 1
vip丢失:sum(keepalive_vip_status) by(vip) = 0
vip漂移:changes(keepalive_vip_status[1m])>0
定时任务执行异常:time() - keepalive_file_update_time >120

479

被折叠的 条评论
为什么被折叠?



