最近在用 Docker 容器跑壓力測試,我想知道每個容器的 CPU、記憶體使用狀況,有無超出 Host 主機承載上限。

爬文查到 docker stats 能顯示當下各容器 CPU、記憶體、網路跟磁碟 IO,既然能拿到這些資料,定期輪詢寫成 Log,後續要出什麼分析報表都不成問題。

不過,查資料時找到更有趣的東西 - cAdvisor

cAdvisor 是 Google 開發的開源監控工具,專門用來收集容器資源使用狀況及效能數據。它能自動發現並監控運行中的 Docker 容器,提供 CPU、記憶體、網路和磁碟使用等即時統計。最酷的是你只需用 Docker 跑現成的 cAdvisor 容器,即可用網頁介面查看容器的即時狀況,還能資料導出給 Prometheus 等監控系統進行統一監控及長期分析。

都講到 Prometheus,不意外 Grafana 馬上跟著登場,你攔都攔不住。

用 Grafana + Prometheus 建構監控預警系統,這些年已成管理大型雲端服務的主流解決方案, 在 SRE / DevOps 領域成為顯學。Prometheus 負責蒐集及儲存營運數據(CPU、Memory、IO)、並發展出自己的查詢語言(PromQL)可以分析數據及設置告警;而 Grafana 可將 Prometheus 的數據可視化,做成美美的監控儀表板,還提供高度的客制化彈性,二者相輔相成。網路上專業介紹文很多,這裡就不班門弄斧了。
(延伸參考:使用 Prometheus 和 Grafana 打造監控預警系統)


圖片來源

cAdvisor 雖有網頁介面但功能陽春,只能看最近十分鐘的資料,且缺乏客製圖表、告警通知等功能。於是有社群朋友用 Docker Composer 把 cAdvisor、Prometheus、Grafana 容器串起來寫好設定檔,做到下一行指令,不用三分鐘,一套雲端機房等級的高彈性監控系統就架好了,是容器化技術又一次經典的火力展示。

實驗性質的小網站,理論上不需要如此奢華的專案效能監控系統,但容器化把事情變簡單了,裝整套大系統比自己組裝寫程式還快,git clone 完下一行指令就好,耗用資源也不高,管它是不是牛刀,免費又好用為什麼不要?

再說,不拿小需求練兵增廣見聞累積經驗,將來真遇上大場面,豈不又像劉佬佬進大觀園。

我找到這個 Github 專案 - - Docker Container Monitoring with cAdvisor, Prometheus, and Grafana using Docker Compose。(相關說明)

裡面有一個 docker-compose.yml 會同時啟用 cAdvisor、Prometheus、Grafana 三個容器,分別傾聽 8080、9090、3000 Port;另外有個 prometheus.yml 設定檔指定每 15 秒抓一次資料,除了從 cAdvisor 取得容器效能數據,也抓自己的資料 (預設抓取網址為 http://localhost:xxxx/metrics):

global:
  scrape_interval: 15s # 每15秒抓取一次數據。
  evaluation_interval: 15s # 每15秒評估一次規則。
  
scrape_configs:
  - job_name: "prometheus"
    # metrics_path 預設為 '/metrics'
    static_configs:
      - targets: ["localhost:9090"] # 抓取 Prometheus 自身的數據。

  - job_name: "cadvisor"
    static_configs:
      - targets: ["localhost:8080"] # 抓取 cAdvisor 的數據。

Grafana 則需要三個相關設定檔,datasources.yml 指定 Prometheus 位於 http://localhost:9090、default.yml 指定載入 dashboard.json 做為預設儀表板、dashboard.json 則是基本儀表板組合,預設抓取各容器的 CPU、記憶體、網路傳輸縮製即時線圖,呈現效果如下:

我故意開 Python 容器在裡面跑一分鐘無窮迴圈後中斷,成功在 CPU 圖表畫出一個梯形。這裡的 CPU 線圖有用 PromQL rate() 函數取固定時間間隔(Time Window)內耗用 CPU 秒數的平均值,線形比較平滑,不像傳統效能監視器 CPU 負載圖一堆尖銳轉折。

記錄實測過程我做的小調整:

  1. 原 docker-compose.yml 中 network_model: hostports 映對設定並存,二者只需留一種。由於相關設定檔是用 localhost 互相溝通,故保留 network_model: host 較簡單,不然要改走容器內部網路並將設定檔 URL 的 localhost 改為容器名稱,工程較大。
  2. 原本 dashboard.json 設定抓 CPU 等數字時 PromQL "rate(container_cpu_user_seconds_total{image!=\"\"}[5m]) * 100" 抓最近五分鐘指標值平均(換言之,短暫的尖峰會被攤平,有興趣測入推薦這篇:Prometheus 指标值不准:是 feature,还是 bug?),讓曲線平滑化以觀察長期趨勢。我的壓力測試期間長度較短,故調成 30s 平均讓它更明顯反映變化。

【延伸閱讀】

This post explores monitoring Docker container resource usage using docker stats and cAdvisor for real-time stats. It further discusses integrating cAdvisor with Prometheus and Grafana for a comprehensive and scalable monitoring system. A recommended GitHub project simplifies setup using Docker Compose.


Comments

# by yangmh66

Almost perfect, 但好像沒看到 GPU 資源的monitoring...

# by yoyo

GPU可參考 https://github.com/NVIDIA/dcgm-exporter

Post a comment