Monitoring(Grafana + Prometheus + Loki 監控系統)¶
Overview¶
Monitoring 係 benhoweb.com 嘅自托管(self-hosted)基礎監控服務,部署喺 Oracle Cloud Infrastructure(OCI)嘅 ARM64 實例上。佢嘅作用係統一收集、儲存、可視化同警示成個平台所有服務嘅運行狀態,令管理員可以喺單一 Dashboard 入面掌握一切。
成個 Stack 由七個核心組件組成:Grafana、Prometheus、Loki、cAdvisor、Promtail、Alertmanager 同 Node Exporter,構成一套完整嘅「指標(Metrics)+ 日誌(Logs)」雙軌監控方案。指標方面,Prometheus 負責拉取同儲存各服務嘅 /metrics 數據;日誌方面,Promtail 收集 Docker Log 並推送至 Loki;最後全部集中喺 Grafana 做可視化查詢同 Alertmanager 做警示通知。
Monitoring 服務奉行「一件新服務一個 Container」嘅原則,所有組件都以 Docker Compose 管理,並透過 Cloudflare Tunnel 安全接入,唔會喺 Host 上面開放任何 Port。呢個設計令監控系統本身亦成為妥善管理嘅一部分,符合整體基建嘅零信任網絡策略。另外,Grafana 嘅後端資料庫直接共用 pg-main,體現「新服務一律共用 pg-main」嘅平台政策。
Architecture¶
Monitoring Stack 喺單一 Oracle Cloud ARM64 實例上運行,所有服務透過 Docker Compose 綑綁喺同一個名為 cf_network 嘅外部 Docker 網絡。架構可以分為以下幾個層次:
核心組件¶
- Grafana(13.1.1):監控 Dashboard 前端,提供統一嘅可視化介面。佢嘅設定資料庫唔係本地 SQLite,而係 PostgreSQL——使用
pg-main提供嘅grafanadatabase。 - Prometheus:指標收集同儲存引擎,定期拉取各 exporter 嘅
/metrics端點,並根據 rule 產生警示。 - Loki:日誌聚合系統,以標籤方式索引日誌,配合 Grafana Explore 做日誌查詢。
- cAdvisor:收集容器層面嘅資源使用數據(CPU、記憶體、網絡、磁碟 IO),俾 Prometheus scrape。
- Promtail:日誌收集 agent,會自動發現 Docker Container 嘅 stdout/stderr 日誌並推送至 Loki。
- Alertmanager:處理 Prometheus 產生嘅警示,經過去重、分組、抑制後,轉發至郵件、Telegram 等通知渠道。
- Node Exporter:收集 Host(即 Oracle Cloud VM)層級嘅系統指標,例如 CPU load、記憶體使用量、磁碟空間、網絡流量。
網絡設計¶
所有 Web 服務(包括 Grafana)一律經由 Cloudflare Tunnel 對外提供,唔會直接暴露 Host Port。用戶透過 https://grafana.benhoweb.com 存取 Grafana,流量由 Cloudflare 邊緣進入 Tunnel,再轉發至 Stack 內部嘅 Grafana container。呢個設計有兩個好處:
- 完全隱藏實際 VM IP,大幅減少被掃描同攻擊嘅機會;
- TLS 終止由 Cloudflare 處理,內部唔使再管理證書。
數據流向¶
Node Exporter ──► Prometheus ──► Grafana
cAdvisor ──────► Prometheus ──► Alertmanager ──► 通知渠道
Promtail ──────► Loki ────────► Grafana
Deployment¶
前置要求¶
- Oracle Cloud(OCI)ARM64 VM,建議至少 4 OCPU / 24 GB RAM,行 Ubuntu 或 Oracle Linux。
- 已初始化
cf_networkDocker external network:
docker network create cf_network
- 已有運行中嘅
pg-mainPostgreSQL 服務,並建立好grafana用戶同 database。 - 準備
.env檔案,包含GF_SECURITY_ADMIN_PASSWORD同GF_DATABASE_PASSWORD。
部署步驟¶
- 建立目錄並放入
docker-compose.yml:
mkdir -p ~/monitoring && cd ~/monitoring
- 確保
.env檔案內容正確:
GF_SECURITY_ADMIN_PASSWORD=your_strong_password
GF_DATABASE_PASSWORD=your_grafana_db_password
- 啟動整個 Stack:
docker compose up -d
-
喺 Cloudflare Zero Trust Dashboard 建立 Tunnel,加入 Public Hostname:
-
Subdomain:
grafana - Domain:
benhoweb.com - Service:
http://grafana:3000
Cloudflare Tunnel 用戶端可以以 sidecar container 形式部署喺同一 cf_network 網絡,或者直接裝喺 Host 度。
Configuration¶
Grafana¶
Grafana 嘅關鍵設定全部透過環境變數注入:
- 管理員帳號:
GF_SECURITY_ADMIN_USER=admin,密碼由.env提供,避免使用預設值。 - PostgreSQL Backend:
GF_DATABASE_TYPE: postgres
GF_DATABASE_HOST: pg-main:5432
GF_DATABASE_NAME: grafana
GF_DATABASE_USER: grafana
GF_DATABASE_PASSWORD: ${GF_DATABASE_PASSWORD}
GF_DATABASE_SSL_MODE: disable
- Root URL:
GF_SERVER_ROOT_URL=https://grafana.benhoweb.com,確保經 Cloudflare Tunnel 存取時,Grafana 可以正確產生 URL。 - 關閉更新檢查:
GF_ANALYTICS_REPORTING_ENABLED=false、GF_ANALYTICS_CHECK_FOR_UPDATES=false、GF_NEWS_NEWS_FEED_ENABLED=false,減少無謂嘅對外連線。
Prometheus¶
需要準備 prometheus.yml 定義 scrape targets:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
另外,Prometheus 需要掛載 alert rule 檔案,並將 alertmanager:9093 設為 Alertmanager 地址。
時間時區¶
所有容器統一設定 TZ: Asia/Hong_Kong,令 Log 時間戳同 Dashboard 時間顯示都符合香港用家習慣。
Operations¶
日常管理¶
- 查閱日誌:Promtail 會自動收集所有 Container 嘅 stdout 日誌並送入 Loki,操作員可以喺 Grafana Explore 入面用 LogQL 查詢,完全唔使 SSH 入 VM。
- 重啟服務:修改設定之後:
docker compose restart grafana prometheus
- 更新映像:由於版本已經係固定(例如
grafana/grafana:13.1.1),升級時只需改 tag 再執行docker compose up -d。
備份策略¶
- Grafana 嘅 database 由
pg-main統一備份,啱啱符合平台嘅「共用 PostgreSQL」政策。 - Prometheus 數據屬短期熱數據,預設 retention 為 15 日;如需更長保留期,可以加
--storage.tsdb.retention.time=30d,並考慮用額外 Block Volume 儲存。 - Loki 嘅日誌數據同樣係短期,建議設定 retention 為 7 至 30 日。
監控自身¶
為咗避免「監控系統死咗但冇人知」,Stack 本身會被 Node Exporter 同 cAdvisor 監控;亦可以設定 Cron Job 定期檢查 https://grafana.benhoweb.com 嘅 HTTP 狀態,或用外部 Uptime Kuma 做健康檢查。
FAQ¶
點解 Grafana 要共用 pg-main?¶
根據 benhoweb.com 嘅平台政策,「新服務一律共用 pg-main」。好處係只需備份一個 PostgreSQL 實例、唔使每個服務各自起 Database Container、並可以透過 PostgreSQL role 統一管理權限。代價係 pg-main 成為單點,所以 pg-main 本身需要做定期 PITR 備份或 HA。
點解唔開 Host Port?¶
所有 Web 服務都用 Cloudflare Tunnel,原因係:
- 安全:VM 冇任何對外 Port,攻擊者根本無從入手;
- 穩定:Tunnel 出站連線唔需要 Dynamic DNS,亦唔怕 ISP 轉 IP;
- 一致:所有服務統一接入 cf_network,網絡設定簡單清晰。
Prometheus 會唔會好食空間?¶
Prometheus 嘅 TSDB 會按 retention policy 自動清理,預設 15 日。喺 ARM64 VM 上建議將 /prometheus 放喺 SSD Block Volume,同時可以調低 scrape interval 或者只收集必要嘅指標,控制儲存用量。
點解 Stack 入面冇 Grafana Agent / Alloy?¶
呢個 Stack 已經有 Promtail 做日誌收集,指標收集亦由 Prometheus 直接 pull 各 exporter 完成,所以唔需要額外嘅 Agent。若日後要收集 Kubernetes 或遠端機嘅數據,就可以考慮引入 Alloy。
點解要指定 Grafana 版本?¶
用固定版本(例如 13.1.1)可以確保部署可重現,避免「尋日仲得、今日爆咗」嘅情況。升級時經過測試先至改 tag,符合 Dockhand GitHub Stack 嘅管理哲學。
Related Links¶
本頁面由 benhoweb.com 基建團隊維護,最後更新於 2026 年。
Source¶
Coverage auto (container scan)