今年年初的样子,老杨报上去了一个Prometheus高可用的项目. 因为有一次 Prometheus 突然挂了,告警、可视化全线失灵,整整40分钟我们像“瞎了眼”一样。所以我下定决心,要把监控体系升级成高可用、可扩展、易维护的架构。本期内容,我就来分享一下这次从单实例 Prometheus 到高可用集群的迁移过程,以及踩过的坑和解决方案。
最初,我们的监控体系很简单:一个 Prometheus 实例,搭配 Node Exporter 和 Blackbox 采集数据,Grafana 做可视化,Alertmanager 推送到飞书和钉钉。运行初期没啥问题,但那次40分钟的“失明”让我们意识到,单点故障的风险太大了。目标很明确:打造一套容灾能力强、支持横向扩展、能统一历史数据存储的监控系统。
在决定方案之前,我们调研了好几个选项。简单总结一下:
方案 | 优点 | 缺点 |
---|---|---|
Prometheus + 双实例副本 | 部署简单,实现基本高可用 | 无法统一存储,查询结果不一致 |
Prometheus + Thanos | 原生兼容 Prometheus,支持高可用、数据去重、长期存储 | 组件多,学习成本高 |
Cortex | 微服务架构,支持多租户 | 配置复杂,维护成本大 |
VictoriaMetrics | 简洁高效,写入性能好 | 社区较小,生态不如 Thanos 成熟 |
最终,我们选了 Prometheus + Thanos。原因?它不破坏现有 Prometheus 的采集机制,社区成熟、文档丰富,还支持 S3 兼容的对象存储,查询也能去重合并,完美契合我们的需求。
整个架构可以这样概括:
┌────────────┐ ┌────────────┐
│ Node Exporter ─────▶ │ Prometheus A │
└────────────┘ └────┬───────┘
│
┌────────────┐ ┌────▼───────┐
│ Blackbox ─────▶ │ Prometheus B │
└────────────┘ └────┬───────┘
│
┌────▼────┐
│ Thanos Sidecar │
└────┬────┘
│
┌─────────────────────────────────┐
│ Thanos Store Gateway │
│ Thanos Compactor │
│ Thanos Query Frontend │
└─────────────────────────────────┘
│
┌────────▼────────┐
│ S3/MinIO │
└────────────────┘
wget
, tar
, systemd
, mc
(MinIO Client), jq
, curl
wget https://github.com/prometheus/prometheus/releases/download/v2.47.2/prometheus-2.47.2.linux-amd64.tar.gz
tar zxvf prometheus-2.47.2.linux-amd64.tar.gz
cp -r prometheus-2.47.2.linux-amd64 /opt/prometheus-A
cp -r prometheus-2.47.2.linux-amd64 /opt/prometheus-B
在 /opt/prometheus-A/prometheus.yml
和 /opt/prometheus-B/prometheus.yml
中,确保 scrape_configs
一致,并增加 relabel_configs
:
scrape_configs:
- job_name: node
static_configs:
- targets: ['node01:9100','node02:9100']
relabel_configs:
- source_labels: [__address__]
target_label: replica
replacement: "A" # B 实例请替换为 "B"
cat <<EOF | sudo tee /etc/systemd/system/prometheus-A.service
[Unit]
Description=Prometheus A
After=network.target
[Service]
Type=simple
ExecStart=/opt/prometheus-A/prometheus \
--config.file=/opt/prometheus-A/prometheus.yml \
--storage.tsdb.path=/opt/prometheus-A/data
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus-A
systemctl status prometheus-A
wget https://github.com/thanos-io/thanos/releases/download/v0.35.1/thanos-0.35.1.linux-amd64.tar.gz
tar zxvf thanos-0.35.1.linux-amd64.tar.gz
cp thanos-0.35.1.linux-amd64/thanos /opt/prometheus-A/
cp thanos-0.35.1.linux-amd64/thanos /opt/prometheus-B/
cat <<EOF | sudo tee /etc/systemd/system/thanos-sidecar-A.service
[Unit]
Description=Thanos Sidecar for Prometheus A
After=prometheus-A.service
[Service]
ExecStart=/opt/prometheus-A/thanos sidecar \
--prometheus.url=http://localhost:9090 \
--tsdb.path=/opt/prometheus-A/data \
--objstore.config-file=/etc/thanos/bucket.yml
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now thanos-sidecar-A
journalctl -u thanos-sidecar-A -f
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
export MINIO_ACCESS_KEY="monitor"
export MINIO_SECRET_KEY="monitor123"
./minio server /mnt/data/minio --console-address ":9001" &
mc alias set myminio http://127.0.0.1:9000 monitor monitor123
mc mb myminio/thanos
mc ls myminio/thanos
# OUTPUT:
# NAME DATE SIZE
# 01GXYZ123ABC/ 2025-08-05 09:15 -
cat <<EOF | sudo tee /etc/systemd/system/thanos-query.service
[Unit]
Description=Thanos Query Frontend
After=thanos-sidecar-A.service thanos-sidecar-B.service
[Service]
ExecStart=/opt/thanos-0.35.1.linux-amd64/thanos query \
--http-address=0.0.0.0:10902 \
--query.replica-label=replica \
--store=127.0.0.1:10901 \
--frontend.http-address=0.0.0.0:10903
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now thanos-query
curl -s http://127.0.0.1:10903/api/v1/status/buildinfo | jq .
# OUTPUT:
# {
# "status": "success",
# "data": {"version":"0.35.1"}
# }
在 alertmanager.yml
中添加:
inhibit_rules:
- source_match:
severity: "critical"
target_match:
severity: "warning"
equal: ["alertname","instance"]
curl -s http://alertmanager.local/api/v2/alerts | jq '.[] | {alertname, labels}'
# OUTPUT:
# {"alertname":"HighCpuUsage","labels":{"instance":"app01","severity":"critical"}}
迁移过程中,我们也踩了不少坑:
After=prometheus-A.service
和 Restart=always
,解决了问题。组件 | 版本 |
---|---|
Prometheus | v2.47.2 |
Thanos | v0.35.1 |
MinIO | RELEASE.2024-07-10T18-00-00Z |
系统 | CentOS 7/8+, Ubuntu 18.04+ |
部署方式 | systemd / Kubernetes Helm |
这次迁移让我深刻体会到,高可用监控不是一蹴而就的,需要仔细规划和反复验证。Thanos 的加持让我们的 Prometheus 集群更健壮,数据存储和查询也更灵活。希望这篇分享能帮到有类似需求的你,记得帮老杨点赞、收藏、留言哦!
这里我先声明一下,日常生活中大家都叫我波哥,跟辈分没关系,主要是岁数大了.就一个代称而已. 我的00后小同事我喊都是带哥的.张哥,李哥的. 但是这个称呼呀,在线下参加一些活动时.金主爸爸也这么叫就显的不太合适. 比如上次某集团策划总监,公司开大会来一句:“今个咱高兴!有请IT运维技术圈的波哥讲两句“ 这个氛围配这个称呼在互联网这行来讲就有点对不齐! 每次遇到这个情况我就想这么接话: “遇到各位是缘分,承蒙厚爱,啥也别说了,都在酒里了.我干了,你们随意!” 所以以后咱们改叫老杨,即市井又低调.还挺亲切,我觉得挺好.
运维X档案系列文章:
老杨的关于AI的号