一、Kubernetes 容器監控的標配—Prometheus
1、簡介
Prometheus 是由 SoundCloud 開發的開源監控告警系統並且帶時序數據庫,基於 Go 語言,是 Google BorgMon 監控系統的開源版本。2016 年,由 Google 發起的 Linux 基金會旗下的原生雲基金會(Cloud Native Computing Foundation,CNCF)將 Prometheus 納入其第二大開源項目。Prometheus 在開源社區也十分活躍,在 GitHub 上擁有兩萬多 Star,並且系統每隔一兩周就會有一個小版本的更新。
隨着 Kubernetes 在容器調度和管理上確定領頭羊的地位,Prometheus 也成為 Kubernetes 容器監控的標配。
2、優點
Prometheus 的優點有很多,如下所述。
(1)提供多維度數據模型和靈活的查詢方式,通過將監控指標關聯多個 tag,來將監控數據進行任意維度的組合,並且提供簡單的 PromQL 查詢方式,還提供 HTTP 查詢接口,可以很方便地結合 Grafana 等 GUI 組件展示數據。
(2)在不依賴外部存儲的情況下,支持服務器節點的本地存儲,通過 Prometheus 自帶的時序數據庫,可以完成每秒千萬級的數據存儲;不僅如此,在保存大量歷史數據的場景中,Prometheus 可以對接第三方時序數據庫如 OpenTSDB 等。
(3)定義了開放指標數據標准,以基於 HTTP 的 Pull 方式采集時序數據,只有實現了 Prometheus 監控數據格式的監控數據才可以被 Prometheus 采集、匯總,並支持以 Push 方式向中間網關推送時序列數據,能更加靈活地應對多種監控場景。
(4)支持通過靜態文件配置和動態發現機制發現監控對象,自動完成數據采集。Prometheus 目前已經支持 Kubernetes、etcd、Consul 等多種服務發現機制,可以減少運維人員的手動配置環節,在容器運行環境中尤為重要。
(5)易於維護,可以通過二進制文件直接啟動,並且提供了容器化部署鏡像。
(6)支持數據的分區采樣和聯邦部署,支持大規模集群監控。
3、架構
下面簡單介紹 Prometheus 的架構。
Prometheus 的基本原理是通過 HTTP 周期性抓取被監控組件的狀態,任意組件只要提供對應的 HTTP 接口並且符合 Prometheus 定義的數據格式,就可以接入 Prometheus 監控。
如圖1-9 所示為 Prometheus 的整體架構圖(來自 Prometheus 官網),展現了 Prometheus 內部模塊及相關的外圍組件之間的關系。
圖1-9
PrometheusServer 負責定時在目標上抓取 metrics(指標)數據,每個抓取目標都需要暴露一個 HTTP 服務接口用於 Prometheus 定時抓取。這種調用被監控對象獲取監控數據的方式被稱為 Pull(拉)。Pull 方式體現了 Prometheus 獨特的設計哲學與大多數采用了 Push(推)方式的監控系統不同。
Pull 方式的優勢是能夠自動進行上游監控和水平監控,配置更少,更容易擴展,更靈活,更容易實現高可用。展開來說就是 Pull 方式可以降低耦合。由於在推送系統中很容易出現因為向監控系統推送數據失敗而導致被監控系統癱瘓的問題,所以通過 Pull 方式,被采集端無須感知監控系統的存在,完全獨立於監控系統之外,這樣數據的采集完全由監控系統控制,增強了整個系統的可控性。
Prometheus 通過 Pull 方式采集數據,那么它如何獲取監控對象呢?Prometheus 支持兩種方式:第 1 種是通過配置文件、文本文件等進行靜態配置;第 2 種是支持 ZooKeeper、Consul、Kubernetes 等方式進行動態發現,例如對於 Kubernetes 的動態發現,Prometheus 使用 Kubernetes 的 API 查詢和監控容器信息的變化,動態更新監控對象,這樣容器的創建和刪除就都可以被 Prometheus 感知。
Storage 通過一定的規則清理和整理數據,並把得到的結果存儲到新的時間序列中,這里有兩種存儲方式。
一種是本地存儲。通過 Prometheus 自帶的時序數據庫將數據保存到本地磁盤,為了性能考慮,建議使用 SSD。但本地存儲的容量畢竟有限,建議不要保存超過一個月的數據。
另一種是遠端存儲,適用於存儲大量監控數據。通過中間層的適配器的轉化,目前 Prometheus 支持 OpenTSDB、InfluxDB、Elasticsearch 等后端存儲,通過適配器實現 Prometheus 存儲的 remote write 和 remote read 接口,便可以接入 Prometheus 作為遠端存儲使用。如圖1-10 所示展現了 Prometheus 當前支持的遠端數據庫。
圖1-10
Prometheus 通過 PromQL 和其他 API 可視化地展示收集的數據。Prometheus 支持多種方式的圖表可視化,例如 Grafana、自帶的 PromDash 及自身提供的模版引擎等。Prometheus 還提供 HTTP API 查詢方式,自定義所需要的輸出。
Prometheus 通過 Pull 方式拉取數據,但某些現有系統是通過 Push 方式實現的,為了接入這些系統,Prometheus 提供了對 PushGateway 的支持,這些系統主動推送 metrics 到 PushGateway,而 Prometheus 只是定時去 Gateway 上抓取數據。
AlertManager 是獨立於 Prometheus 的一個組件,在觸發了預先設置在 Prometheus 中的高級規則后,Prometheus 便會推送告警信息到 AlertManager。AlertManager 提供了十分靈活的告警方式,可以通過郵件、slack 或者釘釘等途徑推送。並且 AlertManager 支持高可用部署,為了解決多個 AlertManager 重復告警的問題,引入了 Gossip,在多個 AlertManager 之間通過 Gossip 同步告警信息。
AlertManager 的整體工作流程如圖1-11 所示。
二、其他開源監控工具
除了市場上提供的很多 SaaS 商業工具如監控寶、監控易、聽雲等,還有一些開源監控工具如 Zabbix、Open-Falcon 等。
1、Zabbix
Zabbix 是由 AlexeiVladishev 開源的分布式監控系統,支持多種采集方式和采集客戶端,同時支持 SNMP、IPMI、JMX、Telnet、SSH 等多種協議,它將采集到的數據存放到數據庫中,然后對其進行分析整理,如果符合告警規則,則觸發相應的告警。
Zabbix 主要有以下幾個核心概念。
主機(Host):是 Zabbix 監控的對象抽象,每個監控對象都有一個 IP 地址,這里的主機不僅限於物理服務器,可能是虛擬機容器或者某個網絡設備。
主機組(Host Group):是一組主機的集合,主要用於多用戶之間的資源隔離,將主機組和用戶關聯,這樣 Zabbix 的不同用戶便只對自己管理的資源可見。
條目(Item):是一個指標的相關監控數據,每個條目都有一個 key 去標識,以區分不同的指標。
應用(Application):是一組條目的集合,一個條目可以屬於一個或多個應用。
模板(Template):是 Zabbix 里快速配置的利器,用於快速定義被監控主機的預設條目集合,通常包含條目、觸發器、視圖、應用及服務發現規則,通過將主機關聯模板來避免重復配置主機。
觸發器(Trigger):是 Zabbix 的告警規則,用於評估某監控對象在某特定條目內接收到的數據是否匹配閾值,如果匹配,則觸發器狀態將從 OK 轉變為 Problem,當數據量再次回到合理范圍時,觸發器狀態又將從 Problem 轉變為 OK。
動作(Action):是 Zabbix 在某個事件發生后執行的動作。事件主要指告警事件、網絡發現新主機加入事件、自動注冊(代理)事件和內部事件(監控項不支持);行為主要包括發送郵件通知、執行遠程命令或者執行 Zabbix 的附加動作。
Zabbix 的組件圖如圖1-12 所示。
圖1-12
如圖1-12 所示,Zabbix 由以下幾個組件構成。
1)ZabbixServer
Zabbix 的核心組件,由C語言編寫而成,主要負責接收 Agent 發送的監控信息,並進行匯總存儲。Zabbix Server 需要完成以下三個主要工作。
設備注冊。有兩種方式可以將監控對象注冊到設備中:一種是手動配置 Agent 地址,但如果需要將機房中的幾百台機器一次性加入,則將是很大的工作量;另一種是采用自動發現機制,可以配置整個網段,Server 會檢測整個網段的主機,並且可以自動配置模板、觸發器等一系列相關配置。
數據收集。這里既包括主動采集,也包括被動接收,采集到的數據首先會被放置在內存中,然后被批量保存在數據庫中。
定期的數據清理及告警觸發。通過配置的觸發器匹配采集數據,如果滿足條件,則發出告警。
2)Zabbix Database
用於存儲所有配置信息,以及由 Zabbix 收集的監控數據。后端數據庫支持 MySQL、PostgreSQL、Oracle 等,通常用到的是 MySQL,並提供 ZabbixWeb 頁面的數據查詢方式。由於采用了關系型數據庫存儲時序數據,所以 Zabbix 在監控大規模集群時常常在數據存儲方面捉襟見肘。
3)Zabbix Web
Zabbix 的 GUI 組件,由 PHP 編寫而成,通常與 Server 運行在同一台主機上,提供監控數據的展現和系統配置,主要配置包括監控模板、告警等。
4)Proxy
可選組件,常用於分布式監控環境中,代理 Server 收集部分被監控端的監控數據並按照一定的頻率統一發往 Server 端。
Proxy 有自己的數據庫,引入 Proxy 主要是為了解決以下兩個問題。
Server 和 Agent 之間網絡不連通,這種情況在跨網絡、跨機房的場景中經常出現。
在大規模部署時減輕 Server 的壓力,畢竟在同時連接這么多 Agent 時,Server 需要維護更多的連接。以 Proxy 模式進行部署時,Agent 配置的上游地址是 Proxy,而 Proxy 配置的是 Server。
5)Agent
部署在被監控主機上,負責收集本地數據並發往 Server 端或 Proxy 端,Agent 會啟動一個名為 Agentd 的守護進程。
Agent 分為兩種模式:主動和被動。主動是指 Agent 主動采集數據並將數據發送到 Server/Proxy;被動是指 Server 每次都主動調用 Agent 獲取數據。Agent 還能執行用戶的自定義腳本,從而完成一些原生 Agent 不具備的功能。
這里補充講解 Zabbix 的一個工具,即 Zabbix_sender。Zabbix_sender 是一個命令行工具,可用於主動向 Zabbix 服務端發送監控數據,這樣可避免 Agent 一直等待監控任務完成。有意思的是,Zabbix 本身由一個商業團隊維護,該團隊免費提供 Zabbix 軟件,但收取支持和維護費用。這和 Red Hat 的思路如出一轍,在系統軟件日趨成熟的未來,軟件的商業模式將逐步從出售許可證轉變為收取服務費用,這也是大勢所趨。
2、Nagios
Nagios 原名為 NetSaint,由 Ethan Galstad 開發並維護。Nagios 是一個老牌監控工具,由C語言編寫而成,主要針對主機監控(CPU、內存、磁盤等)和網絡監控(SMTP、POP3、HTTP 和 NNTP 等),當然也支持用戶自定義的監控腳本,如圖1-13 所示。
圖1-13
Nagios 的整體架構非常清晰,它通過 Plugin 采集各種監控數據,例如針對 SNMP 監控時,通過 SNMP plugin 和在監控對象上運行的 snmpd 通信獲取網絡信息;它還支持一種更加通用和安全的采集方式 NRPE(Nagios RemotePluginExecutor),它首先在遠端啟動一個 NRPE 守護進程,用於在遠端主機上面運行檢測命令,在 Nagios 服務端用 check nrep 的 plugin 插件通過 SSL 對接到 NRPE 守護進程,執行相應的監控行為。相比 SSH 遠程執行命令的方式,這種方式更加安全。當然,Nagios 也支持 SSH 的 Plugin。
Nagios 數據被保存在 RDD(Round Robin Database,環形數據庫)中,RDD 適用於存儲時序數據,支持以下 4 種監控數據。
gauge:儀表盤數據。
counter:計數器。
absolute:不同時間段的變化率,為正數。
driver:變化率,指當前值和前一個監控數值的比值,有正有負。
RDD 的存儲原理比較簡單,它把整個數據存儲空間構建成圓環,指針指向最新的數據位置並且會隨着數據讀寫移動,如果此時沒有獲取監控數據,RDD 就會使用默認的 unknown 填充,保證數據對齊。每個數據庫文件都以 .rdd 結尾,大小是固定的,如圖1-14 所示。
圖1-14
3、Open-Falcon
Open-Falcon 是小米開源的企業級監控工具,由 Go 語言開發而成,包括小米、滴滴、美團等在內的互聯網公司都在使用它,是一款靈活、可擴展並且高性能的監控方案,整體架構如圖1-15 所示。
圖1-15
下面對如圖1-15 所示的組件進行簡單介紹。
Falcon-agent:用 Go 語言開發的 Daemon 程序,運行在每台 Linux 服務器上,用於采集主機上的各種指標數據,主要包括 CPU、內存、磁盤、文件系統、內核參數、Socket 連接等,目前已經支持 200 多項監控指標。並且,Agent 支持用戶自定義的監控腳本,腳本必須返回 Agent 指定的數組格式。Agent 采集的數據會通過 RPC 方式上報到 Transfer。為了避免單個 Transfer 發生故障,Agent 支持配置多個 Transfer 地址,還可以忽略多余的監控指標。Agent 本身也可以成為一個 Proxy-gateway 代理網關,接收第三方 HTTP 請求並將其轉發到 Transfer 中。
Hearthbeat server:簡稱 HBS(心跳服務),每個 Agent 都會周期性地通過 RPC 方式將自己的狀態上報給 HBS,主要包括主機名、主機 IP、Agent 版本和插件版本,Agent 還會從 HBS 獲取自己需要執行的采集任務和自定義插件。
Transfer:負責接收 Agent 發送的監控數據,並對數據進行整理,在過濾后通過一致性 Hash 算法將數據發送到 Judge 或者 Graph。為了支持存儲大量的歷史數據,Transfer 還支持 OpenTSDB。Transfer 本身沒有狀態,可以隨意擴展。
Judge:告警模塊,Transfer 轉發到 Judge 的數據會觸發用戶設定的告警規則,如果滿足,則會觸發郵件、微信或者回調接口。這里為了避免重復告警,引入了 Redis 暫存告警,從而完成告警合並和抑制。
Graph:RRD 數據上報、歸檔、存儲的組件。Graph 在收到數據以后,會以 RRDtool 的數據歸檔方式存儲數據,同時提供 RPC 方式的監控查詢接口。
API:主要提供查詢接口,不但可以從 Graph 里讀取監控數據,還可以對接 MySQL,用於保存告警、用戶等信息。
Dashboard:由 Python 開發而成,提供 Open-Falcon 的數據和告警展現,監控數據來自 Graph,Dashboard 允許用戶自定義監控面板。
Aggregator:聚合組件,聚合某集群下所有機器的某個指標的值,提供一種集群視角的監控體驗。通過定時從 Graph 獲取數據,按照集群聚合產生新的監控數據並將監控數據發送到 Transfer。
監控系統的對比
下面針對 Prometheus、Zabbix、Nagios 和 Open-Falcon 這幾種監控系統進行橫向對比,如表1-1 所示。
表1-1
監控系統 |
開發語言 |
成熟度 |
擴展性1 |
高性能 |
社區活躍度 |
對容器的支持 |
企業使用情況 |
Zabbix |
C +PHP |
高 |
高 |
低 |
中 |
低 |
高 |
Nagios |
C |
高 |
中 |
中 |
低 |
低 |
低 |
Open-Falcon |
Go |
中 |
高 |
高 |
中 |
中 |
中 |
Prometheus |
Go |
中 |
高 |
高 |
高 |
高 |
高 |
從開發語言上看,為了應對高並發和快速迭代的需求,監控系統的開發語言已經慢慢從C轉移到 Go。
不得不說,Go 憑借簡潔的語法和優雅的並發,在 Java 占據業務開發領域、C占領底層開發領域的情況下,准確定位中間件開發需求,在當前的開源中間件產品中被廣泛應用。
從系統成熟度方面來看,Zabbix 和 Nagios 都是老牌的監控系統:Zabbix 是在 1998 年出現的,Nagios 是在 1999 年出現的,系統功能比較穩定,成熟度較高。而 Prometheus 和 Open-Falcon 都是最近幾年才誕生的,雖然功能還在不斷迭代、更新,但它們站在巨人的肩膀之上,在架構設計上借鑒了很多老牌監控系統的經驗。
從系統擴展性方面來看,Zabbix 和 Open-Falcon 都可以自定義各種監控腳本。Zabbix 不僅可以做到主動推送,還可以做到被動拉取;Prometheus 則定義了一套監控數據規范,並通過各種 exporter 擴展系統采集能力。
從數據存儲方面來看,Zabbix 采用關系數據庫存儲數據,這極大限制了 Zabbix 的數據采集性能。Nagios 和 Open-Falcon 都采用了 RDD 數據存儲方式。Open-Falcon 還加入了一致性 Hash 算法進行數據分片,並且可以對接到 OpenTSDB,而且 Prometheus 自研的一套高性能時序數據庫,在 V3 版本時可以達到每秒千萬級別的數據存儲,可通過對接第三方時序數據庫擴展對歷史數據的存儲性能。
從社區活躍度方面來看,目前 Zabbix 和 Nagios 的社區活躍度比較低,尤其是 Nagios,Open-Falcon 的社區雖然也比較活躍,但基本都是國內的公司在參與。Prometheus 的社區活躍度很高,並且得到 CNCF 的支持,后期的發展值得期待。
從容器支持方面來看,由於 Zabbix 和 Nagios 出現得比較早,當時容器還沒有誕生,所以它們對容器的支持自然也比較差。Open-Falcon 雖然提供了容器監控功能,但支持力度有限。Prometheus 的動態發現機制,不僅支持 Swarm 原生集群,還支持 Kubernetes 容器集群監控,是目前容器監控的最佳解決方案。Zabbix 在傳統監控系統中,尤其是在服務器相關監控方面,占據絕對優勢。Nagios 則在網絡監控方面有廣泛應用。伴隨着容器的發展,Prometheus 開始成為容器監控方面的標配,並將被廣泛應用。總體來說,Prometheus 可以說是目前監控領域最鋒利的“瑞士軍刀”了。
本文節選自《深入淺出 Prometheus:原理、應用、源碼與拓展詳解》一書。陳曉宇,楊川胡,陳嘯編著,由電子工業出版社博文視點出版。