概述
下面幾個(gè)問(wèn)題,相信廣大K8s用戶在日常集群運(yùn)維中都曾經(jīng)遇到過(guò):
·集群中的某個(gè)應(yīng)用被刪除了,誰(shuí)干的?
·Apiserver的負(fù)載突然變高,大量訪問(wèn)失敗,集群中到底發(fā)生了什么?
·集群節(jié)點(diǎn)NotReady,是什么原因?qū)е碌模?/span>
·集群的節(jié)點(diǎn)發(fā)生了自動(dòng)擴(kuò)容,是什么觸發(fā)的?什么時(shí)間觸發(fā)的?
以前,排查這些問(wèn)題,對(duì)客戶來(lái)說(shuō)并不容易。生產(chǎn)環(huán)境中的Kubernetes集群通常是一個(gè)相當(dāng)復(fù)雜的系統(tǒng):
·底層是各種異構(gòu)的主機(jī)、網(wǎng)絡(luò)、存儲(chǔ)等云基礎(chǔ)設(shè)施;
·上層承載著大量的應(yīng)用負(fù)載;
·中間運(yùn)行著各種原生(例如:Scheduler、Kubelet)和第三方的組件(例如:各種Operator),負(fù)責(zé)對(duì)基礎(chǔ)設(shè)施和應(yīng)用進(jìn)行管理和調(diào)度;
·此外不同角色的人員頻繁地在集群上進(jìn)行部署應(yīng)用、添加節(jié)點(diǎn)等各種操作。
在集群運(yùn)行的過(guò)程中,為了對(duì)集群中發(fā)生的狀況能夠盡可能的了如指掌,我們通常會(huì)從多個(gè)維度對(duì)集群進(jìn)行觀測(cè)。
日志,作為實(shí)現(xiàn)軟件可觀測(cè)性的三大支柱之一,為了解系統(tǒng)運(yùn)行狀況,排查系統(tǒng)故障提供了關(guān)鍵的線索,在運(yùn)維管理中起著至關(guān)重要的作用。
Kubernetes提供了兩種原生的日志形式——審計(jì)(Audit)和事件(Event),它們分別記錄了對(duì)于集群資源的訪問(wèn)以及集群中發(fā)生的事件信息。從騰訊云容器團(tuán)隊(duì)長(zhǎng)期運(yùn)維K8s集群的經(jīng)驗(yàn)來(lái)看,審計(jì)和事件并不是可有可無(wú)的東西,善用它們可以極大的提高集群的可觀測(cè)性,為運(yùn)維帶來(lái)巨大的便利。
下面讓我們來(lái)詳細(xì)認(rèn)識(shí)一下它們。
什么是Kubernetes審計(jì)?
Kubernetes審計(jì)日志是Kube-apiserver產(chǎn)生的可配置策略的結(jié)構(gòu)化日志,記錄了對(duì)Apiserver的訪問(wèn)事件。審計(jì)日志提供Metrics之外的另一種集群觀測(cè)維度,通過(guò)查看、分析審計(jì)日志,可以追溯對(duì)集群狀態(tài)的變更;了解集群的運(yùn)行狀況;排查異常;發(fā)現(xiàn)集群潛在的安全、性能風(fēng)險(xiǎn)等等。
審計(jì)來(lái)源
在Kubernetes中,所有對(duì)集群狀態(tài)的查詢和修改都是通過(guò)向Apiserver發(fā)送請(qǐng)求,對(duì)Apiserver的請(qǐng)求來(lái)源可以分為4類:
·控制面組件,例如Scheduler,各種Controller,Apiserver自身
·節(jié)點(diǎn)上的各種Agent,例如Kubelet、Kube-proxy等
·集群的其它服務(wù),例如Coredns、Ingress-controller、各種第三方的Operator等
·外部用戶,例如運(yùn)維人員通過(guò)Kubectl
審計(jì)中都記錄了些什么?
每一條審計(jì)日志都是一個(gè)JSON格式的結(jié)構(gòu)化記錄,包括元數(shù)據(jù)(metadata)、請(qǐng)求內(nèi)容(requestObject)和響應(yīng)內(nèi)容(responseObject)3個(gè)部分。其中元數(shù)據(jù)一定會(huì)存在,請(qǐng)求和響應(yīng)內(nèi)容是否存在取決于審計(jì)級(jí)別。元數(shù)據(jù)包含了請(qǐng)求的上下文信息,例如誰(shuí)發(fā)起的請(qǐng)求,從哪里發(fā)起的,訪問(wèn)的URI等等;
審計(jì)有什么用?
Apiserver做為Kubernetes集群唯一的資源查詢、變更入口,審計(jì)日志可以說(shuō)記錄了所有對(duì)于集群訪問(wèn)的流水,通過(guò)它可以從宏觀和微觀了解整個(gè)集群的運(yùn)行狀況,比如:
·資源被刪掉了,什么時(shí)候刪掉的,被“誰(shuí)”刪掉的?
·服務(wù)出現(xiàn)問(wèn)題,什么時(shí)候做過(guò)版本變更?
·Apiserver的響應(yīng)延時(shí)變長(zhǎng),或者出現(xiàn)大量5XX響應(yīng)Status Code,Apiserver負(fù)載變高,是什么導(dǎo)致的?
·Apiserver返回401/403請(qǐng)求,究竟是證書(shū)過(guò)期,非法訪問(wèn),還是RBAC配置錯(cuò)誤等。
·Apiserver收到大量來(lái)自外網(wǎng)IP對(duì)敏感資源的訪問(wèn)請(qǐng)求,這種請(qǐng)求是否合理,是否存在安全風(fēng)險(xiǎn);
什么是Kubernetes事件?
事件(Event)是Kubernetes中眾多資源對(duì)象中的一員,通常用來(lái)記錄集群內(nèi)發(fā)生的狀態(tài)變更,大到集群節(jié)點(diǎn)異常,小到Pod啟動(dòng)、調(diào)度成功等等。我們常用的kubectl describe命令就可以查看相關(guān)資源的事件信息。
事件中記錄了什么?
·級(jí)別(Type):目前僅有“Normal”和“Warning”,但是如果需要,可以使用自定義類型。
·資源類型/對(duì)象(Involved Object):事件所涉及的對(duì)象,例如Pod,Deployment,Node等。
·事件源(Source):報(bào)告此事件的組件;如Scheduler、Kubelet等。
·內(nèi)容(Reason):當(dāng)前發(fā)生事件的簡(jiǎn)短描述,一般為枚舉值,主要在程序內(nèi)部使用。
·詳細(xì)描述(Message):當(dāng)前發(fā)生事件的詳細(xì)描述信息。
·出現(xiàn)次數(shù)(Count):事件發(fā)生的次數(shù)。
事件有什么用?
集群內(nèi)已經(jīng)翻江倒海,集群外卻風(fēng)平浪靜,這可能是我們?nèi)粘<哼\(yùn)維中常常遇到的情況,集群內(nèi)的狀況如果無(wú)法透過(guò)事件來(lái)感知,很可能會(huì)錯(cuò)過(guò)最佳的問(wèn)題處理時(shí)間,待問(wèn)題擴(kuò)大,影響到業(yè)務(wù)時(shí)才發(fā)現(xiàn)往往已經(jīng)為時(shí)已晚。
除了早早發(fā)現(xiàn)問(wèn)題,Event也是排查問(wèn)題的最佳幫手,由于Event記錄了全面的集群狀態(tài)變更信息,所以大部分的集群?jiǎn)栴}都可通過(guò)Event來(lái)排查。
總結(jié)一下Event在集群中扮演兩大重要角色:
·“吹哨人”:當(dāng)集群發(fā)生異常情況時(shí),用戶可通過(guò)事件第一時(shí)間感知;
·“目擊者”:集群中的大小事件都會(huì)通過(guò)Event記錄,如果集群中發(fā)生意外情況,如:節(jié)點(diǎn)狀態(tài)異常,Pod重啟,都可以通過(guò)事件查找發(fā)生的時(shí)間點(diǎn)及原因;
TKE如何發(fā)掘?qū)徲?jì)/事件的價(jià)值
傳統(tǒng)的通過(guò)輸入查詢語(yǔ)句檢索日志的方式來(lái)使用審計(jì)和事件,固然可以提供很高的靈活性,但也有著較高的使用門(mén)檻,不僅要求使用者對(duì)于日志的數(shù)據(jù)結(jié)構(gòu)非常了解,還要熟悉Lucene、SQL語(yǔ)法。這往往導(dǎo)致使用效率偏低,也無(wú)法充分發(fā)掘數(shù)據(jù)的價(jià)值。
騰訊云容器服務(wù)TKE聯(lián)合騰訊云日志服務(wù)CLS[1],打造出針對(duì)Kubernetes審計(jì)/事件采集、存儲(chǔ)、檢索、分析的一站式產(chǎn)品級(jí)服務(wù),不僅提供了一鍵開(kāi)啟/關(guān)閉功能,免去一切繁瑣的配置;還根據(jù)容器團(tuán)隊(duì)長(zhǎng)期運(yùn)維海量集群的經(jīng)驗(yàn)中總結(jié)出對(duì)于Kubernetes審計(jì)/事件的最佳使用實(shí)踐。
TKE支持通過(guò)可視化的圖表,以多個(gè)維度對(duì)審計(jì)日志[2]和集群事件[3]進(jìn)行呈現(xiàn),使用者只需了解K8s的基本概念,就能很“直覺(jué)”地在TKE控制臺(tái)上進(jìn)行各種檢索和分析操作,足以支撐絕大多數(shù)常見(jiàn)集群運(yùn)維場(chǎng)景,使得無(wú)論是發(fā)現(xiàn)問(wèn)題還是定位問(wèn)題都能做到事半功倍,從而提升運(yùn)維效率,真正地將審計(jì)和事件數(shù)據(jù)的價(jià)值最大化。
如何使用TKE審計(jì)/事件服務(wù)去排查問(wèn)題?
關(guān)于TKE的集群審計(jì)/事件簡(jiǎn)介與基礎(chǔ)操作,請(qǐng)參考集群審計(jì)[4]、事件存儲(chǔ)[5]的官方文檔。
場(chǎng)景示例:
下面我們看幾個(gè)現(xiàn)實(shí)中的典型場(chǎng)景:
示例1:排查一個(gè)工作負(fù)載消失的問(wèn)題
在審計(jì)檢索頁(yè)面中,單擊【K8s對(duì)象操作概覽】標(biāo)簽,指定操作類型和資源對(duì)象:
查詢結(jié)果如下圖所示:
由圖可見(jiàn),是10001****7138這個(gè)帳號(hào),對(duì)應(yīng)用「nginx」進(jìn)行了刪除。可根據(jù)帳號(hào)ID在【訪問(wèn)管理】>【用戶列表】中找到關(guān)于此賬號(hào)的詳細(xì)信息。
示例2:排查一個(gè)節(jié)點(diǎn)被封鎖的問(wèn)題
在審計(jì)檢索頁(yè)面中,單擊【節(jié)點(diǎn)操作概覽】標(biāo)簽,填寫(xiě)被封鎖的節(jié)點(diǎn)名:
查詢結(jié)果如下圖所示:
由圖可見(jiàn),是10001****7138這個(gè)帳號(hào)在2020-1-30T06:22:18時(shí)對(duì)172.16.18.13這臺(tái)節(jié)點(diǎn)進(jìn)行了封鎖操作。
示例3:排查Apiserver響應(yīng)變慢的問(wèn)題
在審計(jì)檢索的【聚合檢索】標(biāo)簽頁(yè)中,提供了從用戶、操作類型、返回狀態(tài)碼等多個(gè)維度對(duì)于Apiserver訪問(wèn)聚合趨勢(shì)圖。
由圖可見(jiàn),用戶tke-kube-state-metrics的訪問(wèn)量遠(yuǎn)高于其他用戶,并且在“操作類型分布趨勢(shì)”圖中可以看出大多數(shù)都是list操作,在“狀態(tài)碼分布趨勢(shì)”圖中可以看出,狀態(tài)
碼大多數(shù)為403,結(jié)合業(yè)務(wù)日志可知,由于RBAC鑒權(quán)問(wèn)題導(dǎo)致tke-kube-state-metrics組件不停的請(qǐng)求Apiserver重試,導(dǎo)致Apiserver訪問(wèn)劇增。日志如下所示:
E1130 06:19:37.368981 1 reflector.go:156]pkg/mod/k8s.io/client-go v0.0.0-20191109102209-3c0d1af94be5/tools/cache/reflector.go:108:Failed to list*v1.VolumeAttachment:volumeattachments.storage.k8s.io is forbidden:User"system:serviceaccount:kube-system:tke-kube-state-metrics"cannot list resource"volumeattachments"in API group"storage.k8s.io"at the cluster scope
示例4:排查節(jié)點(diǎn)異常的問(wèn)題
一臺(tái)Node節(jié)點(diǎn)出現(xiàn)異常,在事件檢索頁(yè)面,點(diǎn)擊【事件總覽】,在過(guò)濾項(xiàng)中輸入異常節(jié)點(diǎn)名稱:
查詢結(jié)果顯示,有一條節(jié)點(diǎn)磁盤(pán)空間不足的事件記錄查詢結(jié)果如下圖:
進(jìn)一步查看異常事件趨勢(shì):
可以發(fā)現(xiàn),2020-11-25號(hào)開(kāi)始,節(jié)點(diǎn)172.16.18.13由于磁盤(pán)空間不足導(dǎo)致節(jié)點(diǎn)異常,此后kubelet開(kāi)始嘗試驅(qū)逐節(jié)點(diǎn)上的pod以回收節(jié)點(diǎn)磁盤(pán)空間;
示例5:查找觸發(fā)節(jié)點(diǎn)擴(kuò)容的原因
開(kāi)啟了節(jié)點(diǎn)池[6]「彈性伸縮」的集群,CA(cluster-autoscler)組件會(huì)根據(jù)負(fù)載狀況自動(dòng)對(duì)集群中節(jié)點(diǎn)數(shù)量進(jìn)行增減。如果集群中的節(jié)點(diǎn)發(fā)生了自動(dòng)擴(kuò)(縮)容,用戶可通過(guò)事件檢索對(duì)整個(gè)擴(kuò)(縮)容過(guò)程進(jìn)行回溯。
在事件檢索頁(yè)面,點(diǎn)擊【全局檢索】,輸入以下檢索命令:
event.source.component:"cluster-autoscaler"
在左側(cè)隱藏字段中選擇event.reason、event.message、event.involvedObject.name、event.involvedObject.name進(jìn)行顯示,將查詢結(jié)果按照日志時(shí)間倒序排列,結(jié)果如下圖所示:
通過(guò)上圖的事件流水,可以看到節(jié)點(diǎn)擴(kuò)容操作在2020-11-25 20:35:45左右,分別由三個(gè)nginx Pod(nginx-5dbf784b68-tq8rd、nginx-5dbf784b68-fpvbx、nginx-5dbf784b68-v9jv5)觸發(fā),最終擴(kuò)增了3個(gè)節(jié)點(diǎn),后續(xù)的擴(kuò)容由于達(dá)到節(jié)點(diǎn)池的最大節(jié)點(diǎn)數(shù)沒(méi)有再次觸發(fā)。
總結(jié)
本文介紹了在Kubernetes中兩個(gè)經(jīng)常被忽略的元素--「審計(jì)日志」和「集群事件」,并討論了它們?cè)谫x能集群運(yùn)維和提升系統(tǒng)可觀測(cè)性方面的價(jià)值。
騰訊云容器團(tuán)隊(duì)在長(zhǎng)期運(yùn)維海量Kubernetes集群經(jīng)驗(yàn)總結(jié)的基礎(chǔ)上,在TKE中發(fā)布了基于審計(jì)和事件的產(chǎn)品服務(wù),幫助用戶能夠快速高效解決日常集群運(yùn)維中遇到的問(wèn)題,將用戶從繁雜的集群?jiǎn)栴}中解放出來(lái)。
最后我們從實(shí)戰(zhàn)角度出發(fā),通過(guò)幾個(gè)經(jīng)典問(wèn)題來(lái)演示通過(guò)TKE審計(jì)/事件服務(wù)來(lái)定位排查問(wèn)題。由于篇幅有限,我們的演示只是產(chǎn)品功能的冰山一角,更多的功能需要用戶去探索使用,最后歡迎用戶體驗(yàn)。
(騰訊云日志服務(wù)CLS對(duì)于TKE產(chǎn)生的所有審計(jì)/事件數(shù)據(jù)提供免費(fèi)服務(wù)至2021年6月1日。)
參考資料
[1]日志服務(wù)CLS:https://cloud.tencent.com/product/cls
[2]審計(jì)日志:https://cloud.tencent.com/document/product/457/50510
[3]集群事件:https://cloud.tencent.com/document/product/457/50512
[4]集群審計(jì):https://cloud.tencent.com/document/product/457/48346
[5]事件存儲(chǔ):https://cloud.tencent.com/document/product/457/32091
[6]節(jié)點(diǎn)池:https://cloud.tencent.com/document/product/457/43719