Kubernetes監控在小米的落地

來源:小米雲技術

ID:mi-cloud-tech

作者:郭如意

d30e6f87e65a4efa8e8423f4da97aaea


本文介紹了高可用、持久存儲、可動態調整的Kubernetes監控方案的實現過程。

小米的彈性調度平臺(Ocean)以及容器平臺主要基於開源容器自動化管理平臺kubernetes(簡稱k8s)來提供服務,完善的監控系統提高容器服務的質量的前提。不同於傳統物理主機,每個容器相當於一個主機,導致一臺物理主機上的系統指標數量成本增長,總的監控指標規模相當龐大(經線上統計,每node指標達到10000+)。此外,爲了避免重複造輪,需要最大限度的利用公司的監控報警系統,需要把k8s的監控和報警融入其中。在小米現有的基礎設施之上,落地該監控,是一個不小的挑戰。

1

當監控遇上K8S

爲了更方便的管理容器,k8s對container進行了封裝,擁有了Pod、Deployment、Namespace、Service等衆多概念。與傳統集羣相比,k8s集羣監控更加複雜:

(1)監控維度更多,除了傳統物理集羣的監控,還包括核心服務監控(apiserver, etcd等)、容器監控、Pod監控、Namespace監控等。

(2)監控對象動態可變,在集羣中容器的銷燬創建十分頻繁,無法提前預置。

(3)監控指標隨着容器規模爆炸式增長,如何處理及展示大量監控數據。

(4)隨着集羣動態增長,監控系統必須具備動態擴縮的能力。

除了k8s集羣監控本身的特性外,具體監控方案的實現要考慮公司內部的實際情況:

(1)目前彈性調度計算平臺提供的k8s集羣包括:融合雲容器集羣、部分Ocean集羣以及CloudML集羣,擁有十餘個集羣,1000+機器。不同k8s集羣的部署方式,網絡模式,存儲方式等不盡相同,監控方案需要兼顧各種差異。

(2)Open-Falcon是公司內通用的監控報警系統,有完善的數據收集,展示和報警機制,但是Open-Falcon並不支持k8s這種拉的採集方案。此外,k8s裏的各種資源,有天然的層次關係,這就決定了監控數據的整合需要強大而靈活的聚合能力,Falcon在這些方面不太能滿足需求。但我們並不想重複造輪子,需要最大限度利用公司既有基礎設施,從而節約開發和運維成本。

(3)對於監控的持久化存儲,如何結合公司內的數據庫,實現監控數據的長期存儲,都是需要考慮的問題。

現有業界針對k8s監控也有一些成熟的方案:

(1)Heapster/Metrics-Server+ InfluxDB + Grafana

Heapster是k8s原生的集羣監控方案(現已廢棄,轉向metrics-server),從節點上的 cadvisor獲取計算、存儲、網絡等監控數據,然後將這些數據輸出到外部存儲(backend),如InfluxDB,最後再通過相應的UI界面進行可視化展示,如grafana。此方案部署簡單,但採集數據單一,不合適k8s集羣整體監控,只適用於監控集羣中各容器的資源信息,如作爲k8s dashboard的數據展示源。

(2)Exporter+Prometheus+Adapter

Prometheus 是一套開源的系統監控報警框架,具有多維數據模型、靈活強大的查詢語句、性能良好等特點。Prometheus可以通過各種exporter,如node-exporter、kube-state-metrics、cadivsor等採集監控metrics監控數據,此外Prometheus可以動態發現k8s集羣中的pod,node等對象。通過Prometheus採集各個維度的數據,進行聚合並提供報警,然後利用adapter可以將數據寫到遠程儲存中(如OpenTSDB,InfluxDB )等實現持久化存儲。但由於數據採集可能會有丟失,所以 Prometheus 不適用於對採集數據要 100% 準確的情形,例如實時監控等。

2

監控方案及演進

初始方案

前期,爲了儘快實現k8s的落地,監控系統藉助Falcon還有內部開發的exporter,僅實現了對於核心監控數據的採集,如Pod的cpu,內存,網絡等資源使用情況,具體架構如下圖所示。


3a3bb2f622ae49d3b0456e0b842cff7f



通過實現cadvisor-exporter採集cadvisor的容器監控數據;kube-state-exporter採集k8s關鍵Pod指標;Falcon-agent採集物理節點數據。初始方案僅採集了核心監控數據,初步實現對核心資源使用情況的監控,缺乏更全面的數據監控,例如apiserver,etcd等。由於Falcon目前不支持對於容器的監控,所以需要手動實現各種exporter來滿足k8s的監控需求。而且監控數據沒有實現持久化存儲,不支持長期查詢。

基於Prometheus的監控系統

由於初始監控系統的不足,經過調研對比最終選用Prometheus作爲k8s的監控方案,主要考慮一下幾點原因:

(1)原生支持k8s監控,具有k8s對象服務發現能力,而且k8s的核心組件提供了Prometheus的採集接口

(2)強大的性能,單個Prometheus可以每秒抓取10萬的metrics,可以滿足一定規模下k8s集羣的監控需求

(3)良好的查詢能力:Prometheus 提供有數據查詢語言 PromQL。PromQL 提供了大量的數據計算函數,大部分情況下用戶都可以直接通過 PromQL 從 Prometheus 裏查詢到需要的聚合數據。

基於Prometheus的k8s監控系統的架構如下圖所示:


fc61753dcce34c4ea768a4d5c4f98796



數據源:node-exporter採集物理節點指標;kube-state-metrics採集k8s相關指標,包括資源使用情況,以及各種對象的狀態信息;cadvisor採集容器相關指標;apiserver, etcd, scheduler, k8s-lvm,gpu等核心組件的監控數據;其他自定義metrics,通過在pod yaml文件annotations添加 prometheus.io/scrape: "true" 可實現自動抓取提供的metrics。

Prometheus數據處理模塊:Prometheus以Pod方式部署在k8s上,Pod中含有Prometheus、Prom-Reloader。Prometheus負責採集聚合數據;prom-config爲監控的聚合規則與抓取配置,以ConfigMap存儲;Prom-Reloader實現監控配置的熱更新,實時監控配置文件,無需重啓應用即可動態加載最新配置。

存儲後端:Falcon與OpenTSDB。

Open-Falcon是公司統一的監控報警系統,提供了完善的數據採集、報警、展示、歷史數據存儲功能以及權限功能。由於Falcon設計較早,沒有對於容器相關指標提供監控,而prometheus原生支持了k8s,但是其報警功能只能靜態配置且需要實現與公司相關賬號打通以方便用戶配置監控,且有些k8s的指標,需要暴露給容器用戶。基於此考慮,我們使用Falcon作爲k8s監控的報警和對外展示平臺。通過實現Falcon-Adapter,將監控數據轉發到Falcon以實現報警與展示。根據k8s服務對象將監控目標分爲多個層次:cluster, node, namespace, deployment, pod,將關鍵報警指標通過Falcon-Agent打到Falcon,用戶可自行在配置報警查看指標。

原生Prometheus的監控數據放在本地(使用tsdb時區數據庫),默認保存15天數據。監控數據不止用於監控與報警,後續的運營分析和精細化運維都需要以這些運營數據作爲基礎,因此需要數據的持久化。在Prometheus社區中也提供了部分讀寫方案,如Influxdb、Graphite、OpenTSDB等。而小米正好有OpenTSDB團隊,OpenTSDB將時序數據存儲在HBase中,我們公司的HBase也有穩定的團隊支持。基於此通過OpenTSDB爲監控數據提供遠程存儲。實現了OpenTSDB-Adapter,將監控數據轉發到時序數據庫OpenTSDB以實現數據的持久存儲,滿足長期查詢以及後期數據分析的需要。

部署方式

系統監控的核心繫統全部通過Deployment/Daemonset形式部署在k8s集羣中,以保證監控服務的可靠性。全部配置文件使用ConfigMap存儲並實現了自動更新。

存儲方式

Prometheus的存儲包括本地存儲與遠程存儲,本地存儲只保存短期內的監控數據,按照兩個小時爲一個時間窗口,將兩小時內產生的數據存儲在一個塊(Block)中,每一個塊中包含該時間窗口內的所有樣本數據(chunks),元數據文件(meta.json)以及索引文件(index)。由於各集羣提供存儲類型的不行,目前已經實現多種存儲方式的部署包括pvc、lvm、本地磁盤等。

遠程存儲通過實現prometheus的遠程讀寫接口實現對OpenTSDB的操作,方便對於長期數據的查詢。

爲了保持Prometheus的簡單性,Prometheus並沒有嘗試在自身中解決以上問題,而是通過定義兩個標準接口(remote_write/remote_read),讓用戶可以基於這兩個接口對接將數據保存到任意第三方的存儲服務中,這種方式在Promthues中稱爲Remote Storage。


c2a53988256e4990a4cb3de02ca8150b



如上圖所示,可以在Prometheus配置文件中指定Remote Write(遠程寫)的URL地址,一旦設置了該配置項,Prometheus將採集到的樣本數據通過HTTP的形式發送給適配器(Adapter)。而用戶則可以在適配器中對接外部任意的服務。外部服務可以是真正的存儲系統,公有云的存儲服務,也可以是消息隊列等任意形式。同樣地,Promthues的Remote Read(遠程讀)也通過了一個適配器實現。在遠程讀的流程當中,當用戶發起查詢請求後,Promthues將向remote_read中配置的URL發起查詢請求(matchers,time ranges),Adapter根據請求條件從第三方存儲服務中獲取響應的數據。同時將數據轉換爲Promthues的原始樣本數據返回給Prometheus Server。當獲取到樣本數據後,Promthues在本地使用PromQL對樣本數據進行二次處理。啓用遠程讀設置後,只在數據查詢時有效,對於規則文件的處理,以及Metadata API的處理都只基於Prometheus本地存儲完成。

遠程存儲現已支持公司內部的Falcon與OpenTSDB,通過Falcon方便用戶查看監控數據以及配置報警。寫到OpenTSDB已實現持久化存儲,並且支持通過Prometheus對其進行遠程讀寫。

目前基於Prometheus的監控方案已在各集羣部署,但隨着集羣規模的增長逐漸暴露出一些問題。

其一,是隨着容器增長監控指標激增,對Falcon-agent與transfer造成一定壓力,致使經常造成Falcon-agent擁堵以及部分監控數據延遲、丟失等問題。在線上測試當通過單個Falcon-agent發送超過150000/m時,經常性出現數據丟失,現已關閉部分監控數據的發送。根本原因是prometheuse集中的數據聚合和推送,把分散在各集羣的指標匯聚到了一臺主機,從而帶來了超常的壓力。

其二,是在規模較大的集羣,Prometheus佔用CPU與內存資源都較多(下表中爲線上集羣Prometheus的運行情況),偶爾會出現某些metrics抓取不到的情況,隨着集羣規模的擴大單個Prometheus將會遇到性能瓶頸。


03deb72cc9b7471387633789b67a476c



分區監控方案

針對單個Prometheus監控方案的不足,需要對其進行擴展已滿足大規模k8s集羣監控,並適配Falcon系統agent的性能。通過調研,發現Prometheus支持集羣聯邦。這種分區的方式增加了Prometheus自身的可擴展性,同時,也可以分散對單個Falcon agent的壓力。

聯邦功能是一個特殊的查詢接口,允許一個prometheus抓取另一個prometheus的metrics,已實現分區的目的。如下所示:


0c4144a1b3d94fc8bc2eccd69f7f89ed



常見分區兩種方式:

其一是功能分區,聯邦集羣的特性可以幫助用戶根據不同的監控規模對Promthues部署架構進行調整,可以在各個數據中心中部署多個Prometheus Server實例。每一個Prometheus Server實例只負責採集當前數據中心中的一部分任務(Job),例如可以將不同的監控任務分配到不同的Prometheus實例當中,再由中心Prometheus實例進行聚合。

其二是水平擴展,極端情況下,單個採集任務的Target數也變得非常巨大。這時簡單通過聯邦集羣進行功能分區,Prometheus Server也無法有效處理時。這種情況只能考慮繼續在實例級別進行功能劃分。將同一任務的不同實例的監控數據採集任務劃分到不同的Prometheus實例。通過relabel設置,我們可以確保當前Prometheus Server只收集當前採集任務的一部分實例的監控指標。

針對k8s的實際情況,分區方案架構如下:


0966e4a72332423d94148ab781cc7abe



Prometheus分區包括master Prometheus 與 slave Prometheus以及 kube state Prometheus:由於大量指標的採集來源於node上的服務,如kubelet, node-exporter, cadvisor等是以node爲單位採集的,所以按照node節點來劃分不同job,slave Prometheus 按照node切片採集node,pod級別數據;

kube-state-metrics暫時無法切片,單獨作爲一個kube-state Prometheus,供master Prometheus採集;其他etcd, apiserver,自定義指標等可通過master Prometheus直接採集。

Prometheus master對於其他Prometheus slave的抓取可通過如下配置:


- job_name: federate-slave honor_labels: true metrics_path: '/federate' params:
 'match[]': - '{__name__=~"pod:.*|node:.*"}' kubernetes_sd_configs: - role: pod namespaces: names: - kube-system relabel_configs: - source_labels: - __meta_kubernetes_pod_label_app action: keep regex: prometheus-slave.*

Prometheus slave的對於抓取任務的分區通過Prometheus提供的hashmod方法來實現:


- job_name: kubelet scheme: https kubernetes_sd_configs: - role: node namespaces: names: [] tls_config: insecure_skip_verify: true relabel_configs: - source_labels: [] regex: __meta_kubernetes_node_label_(.+) replacement: "$1" action: labelmap - source_labels: [__meta_kubernetes_node_label_kubernetes_io_hostname] modulus: ${modulus} target_label: __tmp_hash action: hashmod - source_labels: [__tmp_hash] regex: ${slaveId} action: keep

部署方式

master Prometheus 與 kube-state Prometheus通過deployment部署。slave Prometheus可有多個pod,但由於每個pod的配置不同(配置中的${slaveId}不同),每個slave prometheus需要在配置中體現分區編號,而原生的deployment/statefulset/daemonset都不支持同一Pod模板掛載不同的ConfigMap配置。爲了方便管理Slave Prometheus通過statefulset來部署slave,由於statefulset會將每個pod按順利編號如slave-0,slave-1等。通過Prom-Reloader獲得到Pod名稱,持續監聽Prometheus配置變化,然後生成帶有編號的配置以區分不同的分區模塊。

測試驗證

測試包括兩方面,一是針對分區後的監控方案進行功能測試是否符合預期,二是對於其性能進行測試

在功能測試中,驗證分區方案的聚合規則正常,特別對於分區前後的數據進行校驗,通過對一週內的數據進行對比,取一小時內平均的差值比率,如下圖:


ac12204df4824c6988b3ffde762bccf0



經統計,超過95%的時間序列對比誤差在1%以內,個別指標瞬時波動較大(如網絡使用率),但隨着時間增加會抵消差異。

在性能測試中,針對不同分區監控不同負載下進行測試,驗證其性能狀況。

在測試集羣上創建1000個虛擬node,創建不同數量pod測試Prometheus分區性能:


7ce36eaad3244ad68f8914f51d4ebb3e



對於Prometheus master與Prometheus kube-state在1分鐘抓取時間內最多可支持8w pod,主要瓶頸在於kube-state-metrics隨着pod增加,數據量激增,一次抓取耗時不斷增長。

對於Prometheus slave由於採集部分數據,壓力較小,單個Prometheus可抓取超過400個節點(60 pod/node)。如下圖所示在開啓remote write後抓取時間不斷增加,後續將不斷增加Remote-Storage-Adapter的性能。


104796c03a2347db8ebe22f119c2a1f0



經過在k8s測試集羣驗證,Prometheus分區監控架構最多支持8w的pod,可以滿足預期集羣增長需求。

3

展望

目前分區監控方案已在部分集羣部署,具有高可用、持久存儲、可動態調整等特點。另外,我們未來將持續改進:實現監控的自動擴容,針對kube-state-metrics的性能優化(目前不支持分區);在部署方式上,藉助prometheus-operator與helm等實現更簡潔的配置管理與部署;在監控數據的利用上,可以應用特定算法對數據進行深度挖掘以提供有價值的信息,如利用監控數據提供擴容預測,尋找合適的擴容時機。通過不斷優化,以確保更好地爲k8s提供穩定可靠智能的監控服務。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章