2023-08-17 10:28:30來源:官方架構圖
隨著vivo業(yè)務遷移到容器平臺,vivo云原生監(jiān)控體系面臨著指標量快速上漲帶來的一系列挑戰(zhàn),本文將分享vivo 容器化項目中容器監(jiān)控遇到的問題以及我們的解決和優(yōu)化方法。
二、監(jiān)控架構首先對vivo容器監(jiān)控架構進行一個簡單的介紹。
【資料圖】
原生Prometheus沒有提供高可用的標準方案,我們通過自研 Adapter “分組選舉”方式實現(xiàn)去重,即每個 Prometheus 副本對應一組 Adapter,兩組 Adapter 之間會進行選主,只有Leader組的 Adapter才會轉發(fā)數(shù)據(jù)。通過這種方式既實現(xiàn)了去重,也實現(xiàn)了Prometheus雙副本高可用。
三、問題現(xiàn)象過去幾年來,vivo容器化服務快速增長,監(jiān)控流量上漲數(shù)倍,我們主要遇到如下三個問題:監(jiān)控組件負載快速升高、容器監(jiān)控數(shù)據(jù)斷點和數(shù)據(jù)存儲組件負載陡增。
3.1 監(jiān)控組件負載快速升高容器化每次部署IP都會變化的特性,導致容器監(jiān)控指標量相比物理機和虛擬機要高出好幾個數(shù)量級。同時由于集群規(guī)模的不斷增加以及業(yè)務的快速增長,導致監(jiān)控 Prometheus、VictoriaMetrics 負載快速增高,給我們?nèi)萜鞅O(jiān)控帶來極大的挑戰(zhàn)。監(jiān)控總時間序列可以精簡為以下的表達式,即與 Pod數(shù)量、Pod指標量、指標Label維度數(shù)量呈線性關系:
TotalSeries = PodNum * PerPodMetrics * PerLabelCount
而隨著集群規(guī)模的不斷增加以及容器數(shù)量的不斷增多,監(jiān)控序列就會快速增長,同時監(jiān)控組件負載快速升高,會對容器監(jiān)控系統(tǒng)的穩(wěn)定性產(chǎn)生影響。
3.2 監(jiān)控丟點現(xiàn)象vivo容器層面(業(yè)務)的監(jiān)控數(shù)據(jù)則通過自研Adapter轉發(fā)給Kafka,進而存儲到公司基礎監(jiān)控做業(yè)務監(jiān)控展示和告警配置,同時也存儲一份到Druid做更多維度的統(tǒng)計報表。我們在推送監(jiān)控數(shù)據(jù)的時候發(fā)現(xiàn),Pod維度的指標難以保證發(fā)送頻率,即配置指標采集頻率為 10s,但是在推送的數(shù)據(jù)中頻率無法做到10s,且會有波動。下圖為 采集頻率設置 10s,查詢1分鐘的指標數(shù)據(jù)。
一分鐘內(nèi)某一容器的
container_cpu_user_seconds_total 指標的值:
可以看到只取到了4個值,與期望的 6個值不相符,即發(fā)生了“掉點”的情況,監(jiān)控面板按指定頻率展示數(shù)據(jù)會有頻繁掉0現(xiàn)象。
3.3 數(shù)據(jù)存儲組件負載陡增vivo容器監(jiān)控使用 VictoriaMetrics的v1.59.1-cluster版本做為后端時序數(shù)據(jù)庫來持久化存儲監(jiān)控數(shù)據(jù)。在使用過程中發(fā)現(xiàn) VictoriaMetrics的負載有不定期增高的情況,而后端數(shù)據(jù)庫的延遲會導致監(jiān)控查詢告警功能的異常影響用戶體驗。
四、解法4.1 監(jiān)控組件負載快速升高我們使用 Prometheus-Operator 管理 Prometheus,因為優(yōu)化方案中有 Prometheus-Operator 相關的名詞,故為了下面的理解,先對 Prometheus-Operator 做一個介紹:
(圖片來源:官方架構圖)
上圖是Prometheus-Operator官方提供的架構圖,下面來介紹下圖中各組件:
Operator: Operator是最核心的部分,作為一個控制器,他會去創(chuàng)建Prometheus、ServiceMonitor資源對象,然后會一直監(jiān)控并維持這些資源對象的狀態(tài)。Prometheus:這種資源對象就是作為Prometheus Server存在, Operator 根據(jù)自定義資源 Prometheus 類型中定義的內(nèi)容而部署的 Prometheus Server。Prometheus 也可以通過 labelSelector 去匹配多個ServiceMonitor。ServiceMonitor:ServiceMonitor就是exporter的各種抽象,exporter是用來提供專門提供metrics數(shù)據(jù)接口的服務。Prometheus就是通過ServiceMonitor提供的metrics數(shù)據(jù)接口去 pull 數(shù)據(jù)的。該資源通過 Labels 來選取對應的 Service Endpoint,讓 Prometheus Server 通過選取的 Service 來獲取 Metrics 信息。一個 ServiceMonitor 可以通過 labelSelector 的方式去匹配一類 Service。Service:Service是Kubernetes內(nèi)建資源用于把一組擁有相同功能的Pod封裝起來,并提供一個統(tǒng)一的入口來暴露這組Pod的服務,從而為客戶端訪問提供了一個穩(wěn)定的訪問地址,屏蔽了底層Pod的變化和故障。Service可以結合Kubernetes中的其他組件實現(xiàn)負載均衡、服務發(fā)現(xiàn)、集群內(nèi)部通信等功能。我們重點關注 ServiceMonitor,因為ServiceMonitor為我們提供了指定 target 采集的配置,例如采集頻率,target內(nèi)指標過濾,指標中l(wèi)abel重命名等等操作。
對于監(jiān)控組件負載快速升高問題的解決,我們主要從兩個方面著手,分別是指標治理以及性能優(yōu)化。
圖片
4.1.1 指標治理
1、過濾未使用指標
第一個工作是過濾無用指標,Prometheus 會去從 Target 中去獲取指標數(shù)據(jù)。每個 Target 下會有多個 endponit。每一個endpoint 又會提供幾十上百個指標,而每個指標下的數(shù)據(jù)量也很大。但在生產(chǎn)環(huán)境中我們實際上用到的指標可能只有幾十個,Prometheus采集過來我們又沒有用到的指標就會浪費資源并降低監(jiān)控系統(tǒng)的穩(wěn)定性。因此我們需要對Prometheus 采集到的指標進行一定程度的過濾,從而減少資源的占用。
通過Prometheus提供的
scrape_samples_scraped指標對采集的 target進行分析找到采集樣本量大的Target。
我們進行指標過濾主要就是關注這些數(shù)據(jù)量大的 target,在進行指標過濾之前需要收集 Prometheus所采集的所有指標數(shù)據(jù)以及當前監(jiān)控告警面板以及相關依賴服務所使用到的指標。再根據(jù)采集的指標和正在使用的指標進行正則表達式的書寫。最終在對應 target的 ServiceMonitor將正則表達式寫入。Prometheus則會過濾掉我們不需要的指標。下面就是過濾 cAdvisor這個 target 的 container_threads 開頭的指標的示例。
# 過濾 container_threads 開頭的指標 - action: drop regex: container_threads(.*) sourceLabels: - __name__
完成指標精簡后,監(jiān)控單次采集樣本量從 1000萬降低到 250萬。Prometheus 的CPU 使用量降低 70% ,內(nèi)存 使用量降低 55%。
2、過濾低優(yōu)先級 pod 相關指標
對精簡后的指標進行分析,發(fā)現(xiàn) Pod維度的監(jiān)控指標占比為70%,且有相當比例的 Pod 是集群組件的 Daemonset的Pod。而Daemonset的Pod是隨著集群規(guī)模的增加而增加的。
而對于大部分的集群組件Daemonset,因為設置了資源上限,我們不需要關注其資源消耗情況,只需要關注是否存活和正常提供服務即可。故可以對這部分 Pod 的指標進行一個精簡,不收集這些 Pod的 memory、cpu 等容器監(jiān)控指標。
一個 Daemonset 提供的 Pod 的 Namespace 是相同的,且Pod名稱前綴相同。
# 名稱為cadvisor的 daemonset 提供的 podcadvisor-xxxx1 1/1 Running cadvisor-xxxx2 1/1 Running
且 cAdvisor 提供的指標中包含了 namespace 和 pod 的 label。
container_memory_cache{cnotallow="POD", namespace="monitoring", pod="kube-state-metrics-xxxx-xxxx", service="cadvisor"}
所以我們通過在 ServiceMonitor 上面組合指標的 pod 和 namespace,并與指定的規(guī)則進行匹配丟棄掉我們不需要的 daemonset pod 的序列。
# 過濾掉 monitoring namespace 下面 telegraf 這個daemosnet提供的 pod 的相關指標 - action: drop regex: monitoring@telegraf(.*) separator: "@" sourceLabels: - namespace - pod
在對集群中部分ds Pod 的指標進行過濾后。
對 cAdvisor 的單次采集數(shù)據(jù)量下降 70%。效果十分明顯。
4.1.2 性能優(yōu)化
1、均衡 Prometheus 負載
vivo 容器監(jiān)控架構中最核心的組件就是 Prometheus了,而 Prometheus 也是日常出現(xiàn)問題最多的一個組件,因為 Prometheus 不僅是需要采集數(shù)據(jù),還需要將數(shù)據(jù)通過remote_write的方式推送的VictoriaMetrics 和 Kafka中。
圖片
將監(jiān)控 target 進行分類交由不同的組 Prometheus 采集,且每類 Prometheus 為雙副本模式。隨著集群規(guī)模的增加,發(fā)現(xiàn)當前模式的不合理之處,即因為Pod維度監(jiān)控數(shù)據(jù)量級十分高,導致container 類型 Prometheus 負載遠遠高于其他類型的 Prometheus。在高負載的情況下面會發(fā)生重啟,remote_write 異常等情況。
我們 Prometheus組件架構為按類型采集監(jiān)控指標。其中 Container類型的 Prometheus采集的指標數(shù)量遠遠大于 Component、Host、Resource類型。故需要手動平衡 集群中 Prometheus的負載 將集群的 container類型 Prometheus上面kubelet 和 kube-state-metrics 轉移到 resource-Prometheus 上面 降低 container-Prometheus負載。(與此同時resource-Prometheus也會發(fā)送到 kafka-adapter)。且在負載低的Prometheus上 監(jiān)控跳轉面板用到的監(jiān)控指標(核心指標)進行重復采集,盡可能防止數(shù)據(jù)丟失。降低了container-Prometheus 40%的負,極大的減少了Prometheus異常情況的發(fā)生。
2、減少Prometheus存儲數(shù)據(jù)時間
我們的第2個修改點在 Prometheus的數(shù)據(jù)存儲時間上,Prometheus的默認存儲時間為2周,后續(xù)測試發(fā)現(xiàn) Prometheus的存儲數(shù)據(jù)時間對內(nèi)存的影響很大,且現(xiàn)在監(jiān)控數(shù)據(jù)的持久化存儲都放在 VictoriaMetrics 上面,Prometheus存儲的數(shù)據(jù)主要用于排查問題,不需要承擔持久化存儲的任務。故我們修改Prometheus采集的數(shù)據(jù)本地存儲時間從7天改為2天。Prometheus 內(nèi)存消耗降低 40%。
4.2 監(jiān)控丟點現(xiàn)象4.2.1 問題定位
最初我們認為是 Prometheus 在remote_write 的過程中發(fā)生了丟點的情況,但是通過在社區(qū)查詢和配置問題Prometheus 遠程寫相關的監(jiān)控指標發(fā)現(xiàn)Prometheus并沒有在遠程寫的時候丟棄數(shù)據(jù),且發(fā)現(xiàn)在推送數(shù)據(jù)的過程中只有kubelet 內(nèi)置的 cAdvisor提供的數(shù)據(jù)有"丟點"的情況。故我們開始研究指標提供端組件 cAdvisor,發(fā)現(xiàn)cAdvisor”丟點”問題的原因在于 cAdvisor組件有自己的刷新頻率 和 時間戳。cAdvisor 會去 cgroup 中讀取數(shù)據(jù)并存儲到內(nèi)存中供外部使用。Kubelet的cAdvisor 的刷新數(shù)據(jù)頻率達不到 10s,并且會根據(jù)刷新時間放到指標中。而 Prometheus 按 10s 采集頻率去采集數(shù)據(jù)時,底層的 cAdvisor 如果還沒有去刷新數(shù)據(jù),內(nèi)存中則還是上次的數(shù)據(jù)。而cAdvisor 在0.31版本及之后的版本中添加了時間戳支持,即 cadvisor 提供的數(shù)據(jù)會帶上自己的時間戳。當 Prometheus 去采集 cadviosr數(shù)據(jù)時會以 cAdvisor提供的時間戳為準。故當 Prometheus 按照ServiceMonitor 設置的采集頻率10s去采集cAdvisor 提供的數(shù)據(jù)時,如果在此期間 cAdvisor 沒有進行數(shù)據(jù)更新,則Prometheus會采集到與上次采集時間戳和值相同的情況,Prometheus 就只會記錄一條數(shù)據(jù)。這就是cAdvisor “丟點”的本質(zhì)。cAdvisor的刷新頻率由 housekeeping相關參數(shù) 和 抖動 機制確定。
kubelet 內(nèi)置 cAdvisor設置的參數(shù):
// Kubelet 內(nèi)置 cadvisor 默認參數(shù)// cadvisor housekeeping 的間隔,刷新數(shù)據(jù)的間隔const defaultHousekeepingInterval = 10 * time.Second // cadvisor 是否開啟動態(tài) housekeepingconst allowDynamicHousekeeping = true /*cadvisor housekeeping 的最大間隔,allow_dynamic_housekeeping=true的時候, 會判斷容器活躍程度動態(tài)的調(diào)整 HousekeepingInterval, 當發(fā)現(xiàn)一段時間為容器狀態(tài)為發(fā)生改變會將 housekeeping 的間隔 設置為maxHousekeepingInterval 。*/const maxHousekeepingInterval = 15 * time.Second
4.2.2 解決方案
根據(jù)上面的分析,定位到無法保證指標頻率的根本原因在于 cAdvisor 的默認啟動參數(shù),而目前我們采集的cAdvisor是內(nèi)置于 kubelet 中的,如果要修改參數(shù)的話需要改動 kubelet。故綜合考慮集群穩(wěn)定性和維護成本等因素,我們決定以 daemonset 的方式部署一套cAdvisor,并根據(jù)需求設置 housekeeping 相關的參數(shù)來保證 cAdvisor 刷新數(shù)據(jù)的頻率,并設置 Prometheus 采集 cAdvisor 數(shù)據(jù)的時候忽略 cAdvisor 自帶的時間戳,即通過單獨部署的 cAdvisor 提供Pod的監(jiān)控數(shù)據(jù)并保證監(jiān)控數(shù)據(jù)的頻率。
我們的工作主要在部署 cAdvisor 和 修改對應的 ServiceMonitor。
1、部署 cAdvisor:主要是確定cAdvisor啟動參數(shù), 主要操作為禁用dynamic_housekeeping 和 設置 housekeeping_interval 為 1s,來保證 cAdvisor 獲取數(shù)據(jù)的頻率。
containers:// 參數(shù)設置 - -allow_dynamic_housekeeping=false - -housekeeping_interval=1s
2、創(chuàng)建對應的ServiceMonitor讓 cAdvisor 讓Prometheus 忽略cadviosr自帶的時間戳。(因為 cadviosr自身的抖動機制,頻率無法固定)
cAdvisor的抖動機制:
// return jitter(cd.housekeepingInterval, 1.0)func jitter(duration time.Duration, maxFactor float64) time.Duration {if maxFactor <= 0.0 {maxFactor = 1.0}wait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration))return wait}
cAdvisor的 ServiceMonitor上配置忽略指標自帶時間戳
通過單獨部署的 cAdvisor和 Prometheus 的忽略 cAdvisor 自帶的時間戳,我們成功的解決了容器監(jiān)控斷點的問題,保證了監(jiān)控的頻率。
spec: endpoints: - honorLabels: true // 忽略時間戳 honorTimestamps: false interval: 10s
可以看到再去采集 1分鐘內(nèi)的容器相關監(jiān)控數(shù)據(jù),是很標準的 6 個數(shù)據(jù)點。至此監(jiān)控“掉點”問題解決。
監(jiān)控面板展示數(shù)據(jù)連續(xù),無中斷現(xiàn)象發(fā)生。
4.3 后端數(shù)據(jù)庫負載突增4.3.1 問題定位
從監(jiān)控架構圖可以看到,我們使用社區(qū) v1.59.1-cluster版本的VictoriaMetrics 作為監(jiān)控后端的時序數(shù)據(jù)庫,并在Prometheus 采集的數(shù)據(jù)后通過remote_write寫入到時序數(shù)據(jù)庫VictoriaMetrics中進行持久化存儲,Grafana會從VictoriaMetrics 讀取數(shù)據(jù)展示在對應的 Dashboard上面。而在我們的實際使用中發(fā)現(xiàn),Prometheus 遠程寫入VictoriaMetrics有不定期延遲飆升的現(xiàn)象。
Prometheus寫入VictoriaMetrics延遲
寫入數(shù)據(jù)庫延遲的飆升會導致,監(jiān)控面板展示延時、監(jiān)控誤告警等一系列問題。
我們對 VictoriaMetrics的詳細指標進行分析。發(fā)現(xiàn) vmstorage 組件在底層執(zhí)行 indexdb merge 操作的時候,其 CPU、內(nèi)存等資源使用量會有一個突增, 即indexdb 的 Merge 操作非常消耗資源。
4.3.2 解決方案
正是由于VictoriaMetrics 這些的資源突增,導致自己負載過高,無法正常響應 Prometheus的 remote_write的數(shù)據(jù)。我們所期望的是在 indexdb merge 的時候,資源使用量的增長不會影響到正常的數(shù)據(jù)插入和查詢。經(jīng)過查詢相關資源得到VictoriaMetrics在1.73.0版本中對indexdb的 merge進行優(yōu)化,提升了整體性能。故我們對VictoriaMetrics 進行了版本升級以優(yōu)化這個問題。在版本升級后,未發(fā)現(xiàn) VictoriaMetrics 在indexdb merge時有資源突增的情況發(fā)生。
五、總結在Kubernetes大規(guī)模使用的今天,以 Prometheus 為核心的監(jiān)控系統(tǒng)已成為云原生監(jiān)控領域的事實標準。原生Prometheus沒有提供高可用和持久化存儲的標準方案,vivo通過自研adapter實現(xiàn)了Prometheus雙副本高可用,并將數(shù)據(jù)寫入到VictoriaMetrics中實現(xiàn)了數(shù)據(jù)的持久化存儲。而在業(yè)務規(guī)模的增長的過程中,監(jiān)控數(shù)據(jù)量也在快速增長,對監(jiān)控采集和存儲組件都帶來了不小的壓力,當前我們通過降低數(shù)據(jù)提供端指標數(shù)量、優(yōu)化采集組件參數(shù)、升級開源存儲組件版本的方式,提升了監(jiān)控系統(tǒng)的性能。
而架構的演變是隨著業(yè)務規(guī)模的增長而不斷的演變改進的,未來我們將結合業(yè)務實際規(guī)模優(yōu)化監(jiān)控架構提升容器監(jiān)控整體性能。后續(xù)我們規(guī)劃在監(jiān)控采集、監(jiān)控查詢、監(jiān)控數(shù)據(jù)提供三個方向繼續(xù)提升提供系統(tǒng)性能:
【監(jiān)控采集】:改進數(shù)據(jù)采集端架構,應用自動分片從而降低采集端壓力?!颈O(jiān)控查詢】:應用 PrometheusRule以降低常用查詢耗時,提升監(jiān)控查詢體驗。【監(jiān)控數(shù)據(jù)提供】:在exporter端降低數(shù)量從而更穩(wěn)定提供的數(shù)據(jù)。關鍵詞:
一、背景介紹隨著vivo業(yè)務遷移到容器平臺,vivo云原生監(jiān)控體系面臨著指
今年年初,ChatGPT猶如一顆火種,激發(fā)了AI應用的發(fā)展動力,AI產(chǎn)業(yè)進入
RabbitMQ是一個功能強大的消息隊列系統(tǒng),它提供了靈活的插件機制,使用
8月17日消息,最近哈佛大學科學家利用谷歌云平臺克隆出一臺用于研究心
證券時報網(wǎng)訊,據(jù)四川日報,近日,《四川天府新區(qū)營商環(huán)境創(chuàng)新改革行動
App8月17日消息,截至8月16日,上交所融資余額報7806 84億元,較前一交
易車訊在蔚來手機即將上市之際,蔚來近日向車友會成員征集手機購買意向
快科技8月16日消息,vivo上架了一款新機——Y78+(t1),售價為1599元起。
智通財經(jīng)APP訊,聯(lián)邦制藥(03933)發(fā)布公告,預期集團截至2023年6月30日
我認為學做蛋糕比較容易,我來告訴大家我的蛋糕制作方法,首先準備好材
直播吧8月16日訊今天,國安外援德索薩的兒子,在其參加的北京百隊杯組
大約十年前,《第二次機器時代》(TheSecondMachineAge)一書的作者寫道
證券時報網(wǎng)訊,據(jù)中央結算公司8月16日消息,截至2023年7月末,境外機構
今日凌晨,蘋果推送了iOS17beta6測試版更新,同時還推送了watchOS10bet
生成式人工智能正在快速發(fā)展,許多人正在嘗試使用這項技術來解決他們的