在Rockset,咱們使用Kubernetes(k8s)進行集羣編排。它運行咱們全部的生產微服務-從咱們的提取工人到咱們的查詢服務層。除了託管全部生產基礎架構以外,每位工程師還擁有本身的Kubernetes命名空間和專用資源,咱們可使用它們在本地部署和測試新版本的代碼和配置。這種沙盒開發環境使咱們每週能夠放心地屢次發佈軟件。在此博客文章中,咱們將探索內部構建的工具,該工具可以讓咱們查看Kubernetes事件,這是有關係統狀態的極好信息源,咱們發現該工具備助於對系統進行故障排除和了解其長期運行情況。前端
只要它管理的任何資源發生任何更改,Kubernetes都會發出事件。這些事件一般包含有關觸發它的實體的重要元數據,事件的類型(正常,警告,錯誤等)以及緣由。此數據一般存儲在etcd中,並在您運行某些kubectl命令時可用。sql
$ kubectl describe pods jobworker-c5dc75db8-7m5ln ... ... ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 7m default-scheduler Successfully assigned master/jobworker-c5dc75db8-7m5ln to ip-10-202-41-139.us-west-2.compute.internal Normal Pulling 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal pulling image "..." Normal Pulled 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Successfully pulled image "..." Normal Created 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Created container Normal Started 6m kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Started container Warning Unhealthy 2m (x2 over 2m) kubelet, ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal Readiness probe failed: Get http://XXX.XXX.XXX.XXX:YYY/healthz: dial tcp connect: connection refused
這些事件有助於瞭解特定實體進入特定狀態時幕後發生的狀況。查看全部事件的彙總列表的另外一個地方是經過kubectl get事件訪問全部事件。數據庫
$ kubectl get events LAST SEEN TYPE REASON KIND MESSAGE 5m Normal Scheduled Pod Successfully assigned master/jobworker-c5dc75db8-7m5ln to ip-XXX-XXX-XXX-XXX.us-west-2.compute.internal 5m Normal Pulling Pod pulling image "..." 4m Normal Pulled Pod Successfully pulled image "..." ... ...
從上面能夠看出,這爲咱們提供了詳細信息-發出事件的實體,事件的類型/嚴重性以及觸發事件的緣由。當但願瞭解系統中正在發生的更改時,此信息很是有用。這些事件的另外一種用途是瞭解長期系統性能和可靠性。例如,致使Pod從新啓動的某些節點和網絡錯誤可能不會在高可用性設置中引發服務中斷,但一般可能掩蓋了使系統面臨更大風險的潛在條件。json
在默認的Kubernetes設置中,事件被持久保存到鍵值存儲etcd中。 etcd已針對快速快速一致的查詢進行了優化,但不足以提供對數據的分析能力。隨着大小的增加,etcd也難以跟上,所以,事件會按期壓縮和清理。默認狀況下,etcd僅保留過去一小時的事件。api
歷史背景可用於瞭解集羣的長期健康情況,過去發生的事件以及在Kubernetes中採起的緩解它們的措施,並創建準確的過後統計。儘管咱們研究了事件的其餘監視工具,但咱們意識到咱們有機會使用本身的產品來分析這些事件,而其餘監視產品則沒法使用這種方法,並使用它來構建咱們全部狀態的可視化Kubernetes資源。服務器
爲了提取Kubernetes事件,咱們使用了Heptio的開源工具eventrouter。它從Kubernetes API服務器讀取事件,並將其轉發到指定的接收器。接收器能夠是從Amazon S3到任意HTTP端點的任何內容。爲了鏈接到Rockset集合,咱們決定爲eventrouter構建一個Rockset鏈接器,以控制上傳到咱們的集合的數據的格式。咱們將此Rockset接收器貢獻到了上游eventrouter項目中。這個鏈接器很是簡單-它接收全部接收到的事件並將它們發送到Rockset中。真正很酷的部分是,對於攝取這些事件(它們是隨不一樣類型的實體而變化的JSON有效負載),咱們不須要構建任何架構或進行結構轉換。咱們能夠按原樣將JSON事件發送到Rockset集合中,並對其進行查詢,就好像它是完整的SQL表同樣。 Rockset首先經過使用聚合索引爲全部json字段創建索引,而後經過Smart Schema自動對其進行模式化,從而將JSON事件自動轉換爲SQL表。網絡
前端應用程序是SQL層上的薄層,它容許按名稱空間和實體類型(Pod,Deployment等)過濾事件,而後在這些實體類型內按正常/錯誤過濾事件。目的是使這些事件具備直方圖,以便在較長的時間內直觀地檢查和了解羣集的狀態。固然,咱們展現的內容只是能夠構建的內容的一個子集-人們能夠想象更復雜的分析-例如分析網絡穩定性,部署過程,發佈軟件版本,甚至使用事件存儲做爲關鍵診斷工具來發現之間的相互關係集羣級別的警報和Kubernetes級別的更改。架構
在開始從eventrouter接收事件到Rockset以前,咱們必須在Rockset中建立一個集合。這是全部eventrouter事件都存儲在的集合。您可使用免費賬戶https://console.rockset.com/c...。app
Rockset中的集合能夠從指定來源獲取數據,也能夠經過REST API發送事件。 API」做爲數據源來建立這樣的集合。less
建立集合時,咱們能夠選擇一個保留期(例如120天)或任何合理的時間,以使咱們對集羣的運行情況有所瞭解。此保留時間是根據Rockset _event_time中的特殊字段應用的。咱們會將這個字段映射到JSON事件有效負載中的特定字段,該事件將從事件路由器收到,稱爲event.lastTimestamp。轉換函數以下所示:
UNIX_MILLIS(PARSE_TIMESTAMP_ISO8601(event.lastTimestamp))
建立集合後,咱們如今能夠設置並使用eventrouter來開始接收Kubernetes事件。
如今,從eventrouter接收事件還須要作一件事-Rockset API密鑰。咱們能夠在Rockset中使用API密鑰將JSON寫入集合並進行查詢。在這種狀況下,咱們從「管理」>「 API密鑰」建立一個名爲eventrouter_write的API密鑰。
複製API密鑰,由於在下一步設置eventrouter時將須要它,以將事件發送到咱們剛剛設置的Rockset集合中。您能夠經過克隆eventrouter存儲庫來設置eventrouter,而後將YAML文件 yaml/deployment。
# eventrouter/yaml/deployment.yaml config.json: |- { "sink": "rockset" "rocksetServer": "https://api.rs2.usw2.rockset.com", "rocksetAPIKey": "<API_KEY>", "rocksetCollectionName": "eventrouter_events", "rocksetWorkspaceName": "commons", }
您能夠將<API_KEY>替換爲咱們在上一步中剛剛建立的Rockset API密鑰。如今,咱們準備好了!運行kubectl apply -f yaml / deployment.yaml,eventrouter能夠當即開始監視和轉發事件。查看Rockset中的集合,您應該開始看到流入的事件並能夠做爲SQL表使用。咱們能夠從Rockset控制檯中查詢它,以下所示,並瞭解一些流入的事件。咱們能夠在它上面運行完整的SQL,包括全部類型的過濾器,聯接等。
如今,咱們能夠開始從集羣中提出一些有趣的問題,並瞭解集羣的運行情況。咱們要問的一個問題是-咱們多久將一次新映像部署到生產中。咱們按照嚴格的發佈時間表進行操做,可是有時會退出和回滾鏡像。
上面的查詢處理了咱們的部署,部署又建立了副本集並找到了部署特定鏡像的最後日期。
這張帶有時間戳的鏡像和Pod摘錄,向咱們介紹了最後幾回部署及其發生的時間。將其繪製在圖表上將告訴咱們有關部署的一致性以及部署實踐的健康程度。
如今,繼續提升羣集自己的性能,運行咱們本身的手動Kubernetes羣集意味着咱們能夠對升級和系統設置進行大量控制,可是值得一看的是什麼時候節點可能丟失/網絡分區致使節點丟失標記爲未就緒。這些事件的聚類能夠告訴咱們不少有關基礎結構的穩定性。
該查詢爲咱們提供了節點狀態變爲「未就緒」的時間,咱們能夠嘗試使用SQL時間函數對數據進行聚類,以瞭解在特定時間段內發生問題的頻率。
咱們還能夠查找pod和容器級事件,例如它們什麼時候發生OOMKilled並將其與系統中發生的其餘事件相關聯。與諸如Prometheus之類的時間序列數據庫相比,SQL的強大功能使咱們能夠編寫和加入不一樣類型的事件,以嘗試將在特定時間間隔內發生的不一樣事情組合在一塊兒,這多是因果關係。
爲了可視化事件,咱們構建了一個使用React的簡單工具,咱們在內部使用它來瀏覽並進行Kubernetes事件及其中發生的錯誤的一些基本聚類。咱們正在將此儀表板發佈爲開源,並但願瞭解社區可能將其用做什麼。 Kubernetes事件的可視化有兩個主要方面。首先是對每一個資源的粒度的羣集的高級概述。這使咱們可以查看來自部署和Pod的實時事件流,並查看Kubernetes系統中每一個資源的狀態。還有一個按名稱空間過濾的選項-由於某些服務集在它們本身的名稱空間中運行,這使咱們可以深刻到特定的名稱空間來查看事件。
若是咱們對任何特定資源的運行情況和狀態感興趣,則能夠單擊每一個每一個資源的摘要,並打開一個頁面,其中包含該資源的事件日誌的詳細概述,並帶有一個圖表,該圖表顯示了隨時間推移的事件和錯誤,以提供有關如何管理資源的總體圖。
此可視化中的圖形具備可調的粒度,而且時間範圍的更改容許在任何指定的時間間隔內查看給定資源的事件。將鼠標懸停在堆疊條形圖上的特定條形上,使咱們能夠查看在該時間段內發生的錯誤類型,以幫助您對特定資源正在發生的狀況進行超時分析。該圖下方列出的事件表按事件時間排序,還告訴您包含與該圖相同的信息-也就是說,按時間順序概述了此特定k8s資源發生的全部事件。圖形和表格是瞭解Kubernetes資源過去爲什麼失敗以及該失敗可能伴隨時間的任何趨勢(例如,若是它與新的微服務的發佈同時發生)的有用的方式。
當前,咱們正在使用事件的實時可視化來研究咱們本身在開發和生產中的Kubernetes部署。該工具和數據源使咱們可以查看正在進行的部署,而無需糾纏kubectl界面來查看損壞的緣由。此外,此工具備助於回顧過去的事件。例如-若是咱們發現了瞬態問題,那麼咱們如今能夠及時回顧過去,回顧一下瞬態生產問題,找到可能發生的緣由的模式,以及咱們能夠採起的措施來防止再次發生該事件。在未來。
可以以精細的粒度訪問歷史Kubernetes事件日誌的功能是一種強大的抽象,它使Rockset可以比單獨使用kubectl更好地瞭解咱們的Kubernetes系統狀態。這種獨特的數據源和可視化功能使咱們可以監視咱們的部署和資源,並從歷史角度查看問題。若是您發現它在您本身的環境中有用,咱們很樂意嘗試並作出貢獻!