有道 Kubernetes 容器API監控系統設計和實踐

本期文章,咱們將給你們分享有道容器服務API監控方案,這個方案同時具備輕量級和靈活性的特色,很好地體現了k8s集羣化管理的優點,解決了靜態配置的監控不知足容器服務監控的需求。並作了易用性和誤報消減、可視化面板等一系列優化,目前已經超過80%的容器服務已經接入了該監控系統。

來源/ 有道技術團隊微信公衆號
做者/ 郭超容 王偉靜
編輯/ hjyjava

1.背景

Kubernetes 已經成爲事實上的編排平臺的領導者、下一代分佈式架構的表明,其在自動化部署、監控、擴展性、以及管理容器化的應用中已經體現出獨特的優點。node

在k8s容器相關的監控上, 咱們主要作了幾塊工做,分別是基於prometheus的node、pod、k8s資源對象監控,容器服務API監控以及基於grafana的業務流量等指標監控。git

在物理機時代,咱們作了分級的接口功能監控——域名級別接口監控和機器級別監控,以便在某個機器出現問題時,咱們就能快速發現問題。docker

上圖中,左邊是物理機時代對應的功能監控,包括域名級別接口監控和3臺物理機器監控。右邊是對應的k8s環境,一個service的流量會由k8s負載均衡到pod1,pod2,pod3中,咱們分別須要添加的是service和各個pod的監控。數據庫

因爲K8s中的一切資源都是動態的,隨着服務版本升級,生成的都是全新的pod,而且pod的ip和原來是不同的。api

綜上所述,傳統的物理機API不能知足容器服務的監控需求,而且物理機功能監控須要手動運維管理,爲此咱們指望設計一套適配容器的接口功能監控系統,而且可以高度自動化管理監控信息,實現pod API自動監控。微信

2.技術選型

爲了知足以上需求,咱們初期考慮瞭如下幾個方案。架構

1. 手動維護各個service 和pod 監控到目前物理機使用的podmonitor開源監控系統。

2. 從新制定一個包含k8s目錄樹結構的系統,在這個系統裏面看到的全部信息都是最新的, 在這個系統裏面,能夠作咱們的目錄樹中指定服務的發佈、功能監控、測試演練等。負載均衡

3. 沿用podmonitor框架,支持動態獲取k8s集羣中最新的服務和pod信息,並更新到監控系統中。框架

+方案分析+

針對方案一,考慮咱們服務上線的頻率比較高,而且k8s設計思想即是可隨時自動用新生成的pod(環境)頂替原來很差用的pod,手動維護pod監控效率過低,該方案不可行。

第二個方案應該是比較系統的解決辦法,但須要的工做量會比較大,這種思路基本全本身開發,不能很好的利用已有的功能監控系統,遷移成本大。

因而咱們選擇了方案三,既能兼容咱們物理機的接口功能監控方案,又能動態生成和維護pod監控。

3.總體設計思路

k8s監控包括如下幾個部分:

其中API功能監控,是咱們保證業務功能正確性的重要監控手段。

一般業務監控系統都會包含監控配置、數據存儲、信息展現,告警這幾個模塊,咱們的API功能監控系統也不例外。

咱們沿用apimonitor框架功能,並結合了容器服務功能監控特色,和已有的告警體系,造成了咱們容器API功能監控系統結構:

首先介紹下目前咱們物理機使用的apimonitor監控:一個開源的框架
https://gitee.com/ecar_team/a...

能夠模擬探測http接口、http頁面,經過請求耗時和響應結果來判斷系統接口的可用性和正確性。支持單個API和多個API調用鏈的探測。

以下圖所示,第一行監控裏面監控的是圖片翻譯服務域名的地址,後邊的是各臺物理機的ip:端口。

點開每條監控

咱們沿用apimonitor框架的大部分功能,其中主要的適配和優化包括:

1. 監控配置和存儲部分:一是制定容器服務service級別監控命名規則:集羣.項目.命名空間.服務;(和k8s集羣目錄樹保持一致,方便根據service生成pod監控),二是根據service監控和k8s集羣信息動態生成pod級別監控,

2. 監控執行調度器部分不用改動

3. 信息展現部分,增長了趨勢圖和錯誤彙總圖表

4. 告警部分,和其它告警使用統一告警組。

4.具體實踐操做

4.1 添加service 級別API監控告警

須要爲待監控服務,配置一個固定的容service級別監控。

service級別監控命名規則:集羣.項目.命名空間.服務

以詞典查詞服務爲例,咱們配置一條service級別的多API監控(也能夠是單API監控)

· 單API:一個服務只須要加一條case用

· 多API:若是一個服務須要加多條功能case

其中「所屬系統」 是服務所屬的告警組,支持電話、短信、popo羣、郵件等告警方式(和其它監控告警通用)

任務名稱:取名規則,rancher中k8s集羣名字.項目名字.命名空間名字.service名字(一共四段)

告警消息的字段含義:

docker-dict:告警組,訂閱後會收到告警消息

k8s-prod-th:集羣

dict: 項目

dict:命名空間

data-server:workload名字

data-server-5b7d996f94-sfjwn:pod名字

{} :接口返回內容, 即:response.content

http://dockermonitor.xxx.youdao.com/monitorLog?guid=61bbe71eadf849558344ad57d843409c&name=k8s-prod-th.dict.dict.data-server.data-server-5b7d996f94-sfjwn : 告警詳細連接

4.2 自動生成pod API監控

自動生成下面三行監控任務:(第一行監控是按上面方法配置的容器service ip監控,後邊三行是自動生成pod監控任務 )

監控service級別是單API,則自動生成的是單API,service級別是多API,則自動生成的是多API監控。

自動生成的pod級別監控,除了最後兩行標紅處(ip: port)和service級別不同,其餘都同樣。

實現pod自動生成的方法

1.給podmonitor(改框架是java語言編寫的),增長一個java模塊,用來同步k8s信息到podmonitor中。考慮到修改podmonitor中數據這個行爲,自己是能夠獨立於框架的,能夠不修改框架任何一行代碼就能實現數據動態更新。

2.對比podmonitor數據庫和k8s集羣中的信息,不一致的數據,經過增刪改查db,增長pod的監控。因爲數據之間存在關聯性,有些任務添加完沒有例行運行,故採用了方法三。

3.對比podmonitor數據庫和k8s集羣中的信息,不一致的數據,經過調用podmonitor內部接口添加/刪除一項監控,而後調接口enable /disable job等。按照可操做性難易, 咱們選擇了方法三

針對於k8s集羣中查到的一條pod信息:總共有三種狀況:

1.對於表中存在要插入pod的監控信息記錄,而且enable狀態爲1。則認爲該pod的監控不須要改變

2.對於表中存在要插入pod的監控信息記錄(刪除操做並不會刪除源數據信息),而且enable狀態爲0。則認爲該pod的監控已被刪除或者被中止。調用刪除操做, 清空QRTZ (例行任務插件)表中的響應內容, 調用delete db操做清出監控信息相關表中的內容(使得監控記錄不至於一直在增加)

3.對於表中不存在pod相關信息記錄, 則須要新增長的一個pod。調用post 建立監控任務接口(根據service 監控配置), 並調用get請求設置接口爲監控enabled狀態。

另外對於已經在物理機podmonitor中添加了監控的服務,提供了一個小腳本,用於導出物理機podmonitor域名級別監控到docker monitor監控中。

5.難點和重點問題解決

5.1 誤報消減

5.1.1上線告警抑制

因爲服務重啓期間,會有removing狀態和未ready狀態的pod,在dockermonitor系統中存在記錄,會引發誤報。
咱們的解決方法是提供一個通用腳本,根據k8s服務的存活檢查時間,計算容器服務的發佈更新時間,肯定再自動開啓服務監控的時機。實如今服務重啓時間段,中止該服務的接口功能告警;存活檢查時間過了以後,自動開啓監控。
以下如所示,即Health Check中的Liveness Check檢查時間。

在咱們上線發佈平臺上銜接了該告警抑制功能。

5.1.2彈性擴縮容告警抑制

原來咱們經過查詢rancher的 API接口獲得集羣中全量信息,在咱們服務愈來愈多以後, 查詢一次全量信息須要的時間愈來愈長,基本須要5min左右。在這個過程當中,存在docker-monitor和k8s集羣中的信息不一致的狀況。一開始試圖經過按照業務分組,並行調用rancher接口獲得業務k8s集羣信息。時間從5min縮短到1min多鍾。誤報有必定的減小, 但從高峯期到低谷期時間段, 仍然會有若干pod在k8s集羣中縮掉了, 但docker-monitor中仍有相應的告警。

在調研了一些方案以後,咱們經過k8s增量事件(如pod增長、刪除)的機制,拿到集羣中最新的信息,pod的任何變動,3s鍾以內就能拿到。

經過es的查詢接口,使用 filebeat-system索引的日誌, 把pod帶有關鍵字Releasing address using workloadID (更及時),或kube-system索引的日誌: Deleted pod: xx delete 。

經過這個方案,已經基本沒有誤報。

5.2策略優化

爲了適配一些API容許必定的容錯率,咱們在apimonitor框架中增長了重試策略(單API和多API方式均增長該功能)

爲了適配各種不一樣業務,容許設置自定義超時時間

5.3易用性

增長複製等功能,打開一個已有的告警配置,修改後點擊複製, 則可建立一個新的告警項
使用場景: 在多套環境(預發、灰度和全量)監控,以及從一個類似API接口微調獲得新API監控

5.4業務適配

精品課對服務的容器化部署中使用了接口映射機制,使用自定義的監聽端口來映射源端口,將service的監聽端口做爲服務的入口port供外部訪問,以下圖所示。當service的監聽端口收到請求時,會將請求報文分發到pod的源端口,所以對pod級別的監控,須要找到pod的源端口。

咱們分析了rancher提供的服務API文件後發現,在端口的配置信息中,port.containerPort爲服務的監聽端口,port.sourcePort爲pod的監聽端口,port.name包含port.containerPo
-rt和port.sourcePort的信息,由此找到了pod的源端口與service監聽端口的關鍵聯繫,從而實現了對精品課服務接入本平臺的支持。

6.上線效果

1.容器服務API監控統一,造成必定的規範,幫助快速發現和定位問題。
經過該容器API監控系統,攔截的典型線上問題有:

· xx上線誤操做
· 依賴服務xxxlib版本庫問題
· dns server解析問題
· xxx服務OOM問題
· xxx服務堆內存分配不足問題
· xx線上壓測問題
· 多個業務服務日誌寫滿磁盤問題
· 各種功能不可用問題
·

2.同時增長了API延時趨勢圖標方便評估服務性能:

錯誤統計表方便排查問題:

結合咱們k8s資源對象監控,和grafana的業務流量等指標監控,線上故障率顯著減小,幾個業務的容器服務0故障。

7.總結與展望

7.1總結

本期文章中咱們介紹了基於靜態API監控和K8s集羣化管理方案,設計了實時的自動容器API監控系統。

經過上述方案,咱們可以在業務遷移容器後,很快地從物理機監控遷移到容器監控。統一的監控系統,使得咱們線上服務問題暴露更及時、故障率也明顯減小

7.2展望

1.自動同步k8s服務健康檢查到docker-monitor系統,保證每個服務都有監控。

2.集成到容器監控大盤中,能夠利用大盤中k8s資源目錄樹,更快查找指定服務,以及關聯服務的grafana指標等監控。

3.自動恢復服務,好比在上線指定時間內,發生API監控告警,則自動回滾到上一版本,咱們但願監控不只能發現問題,還能解決問題。

監只是手段,控纔是目標。

8.結語

Docker技術將部署過程代碼化和持續集成,能保持跨環境的一致性,在應用開發運維的世界中具備極大的吸引力。

而k8s作了docker的集羣化管理技術,它從誕生時就自帶的平臺屬性,以及良好的架構設計,使得基於K8s容器能夠構建起一整套能夠解決上述問題的「雲原生」技術體系,也下降了咱們作持續集成測試、發佈、監控、故障演練等統一規劃和平臺的難度。目前有道業務服務基本都上線到容器,後續咱們將陸續遷移基礎服務,實現總體的容器化。

咱們也會不斷積極擁抱開源,借鑑業界成功案例,尋找適合咱們當前業務發展須要的理想選型。

-END-

相關文章
相關標籤/搜索