云計算

Kubernetes監控在小米的落地

廣告
廣告

本文介紹了高可用、持久存儲、可動態調整的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,內存,網絡等資源使用情況,具體架構如下圖所示。

通過實現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監控系統的架構如下圖所示:

數據源: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。

如上圖所示,可以在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將會遇到性能瓶頸。

分區監控方案

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

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

常見分區兩種方式:

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

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

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

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配置變化,然后生成帶有編號的配置以區分不同的分區模塊。

測試驗證

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

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

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

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

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

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

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

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

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

小米云平臺部,主要分享云存儲、云計算、系統、網絡、運維、私有云、安全、數據庫、內核等內容,歡迎感興趣的朋友們關注!

“小應用”背后的“大改變” 愛奇藝賦能流媒體播放服務

上一篇

施密特:谷歌的五大原則

下一篇

你也可能喜歡

Kubernetes監控在小米的落地

長按儲存圖像,分享給朋友

ITPUB 每周精要將以郵件的形式發放至您的郵箱


微信掃一掃

微信掃一掃
大丰收注册
东福彩电子投注单 江苏11选5走势图 公寓租赁赚钱吗 广东快乐十分现场开奖 wnba比分结果山猫对天空 人人赚钱app真的能提现吗 捕鱼达人图片素材 重庆快乐十分 重庆时时开奖直播网址 11选五稳赚不赔的方法 黑马全人工计划软件 浙江快乐12推荐号码推荐 麻将里的百搭 福建快三 重庆时时彩开奖直播 老快3开奖查询