概述
有時(shí)候,集群資源莫名被刪除或修改,有可能是人為誤操作,也有可能是某個(gè)應(yīng)用的bug或惡意程序調(diào)用apiserver接口導(dǎo)致,需要找出"真兇"。這時(shí)候,我們需要為集群開啟審計(jì),記錄apiserver的接口調(diào)用,然后根據(jù)條件檢索和分析審計(jì)日志來找到原因。
關(guān)于TKE的集群審計(jì)簡(jiǎn)介與基礎(chǔ)操作,請(qǐng)參考官方文檔集群審計(jì)[1]。因?yàn)榧簩徲?jì)的數(shù)據(jù)存儲(chǔ)在日志服務(wù),所以我們需要在日志服務(wù)控制臺(tái)去對(duì)審計(jì)結(jié)果進(jìn)行檢索和分析,檢索語(yǔ)法請(qǐng)參考日志檢索語(yǔ)法與規(guī)則[2],要進(jìn)行分析就還需要寫日志服務(wù)所支持的SQL語(yǔ)句,請(qǐng)參考日志服務(wù)分析簡(jiǎn)介[3]。
注:本文僅適用于TKE集群
場(chǎng)景示例
下面給出一些集群審計(jì)使用場(chǎng)景和查詢的示例。
找出是誰(shuí)做的操作
如果節(jié)點(diǎn)被封鎖了,不知道是哪個(gè)應(yīng)用或人為操作的,需要查出來,可以在開啟集群審計(jì)后,使用下面的語(yǔ)句來檢索:
objectRef.resource:nodes AND requestObject:unschedulable
版面設(shè)置可以設(shè)置顯示user.username,requestObject和objectRef.name三個(gè)字段,分別表示做操作的用戶、請(qǐng)求內(nèi)容以及節(jié)點(diǎn)名稱:
從上圖可以看出,是10001****958這個(gè)子賬號(hào)在2020-10-09 16:13:22的時(shí)候?qū)ain.63u5qua9.0這臺(tái)節(jié)點(diǎn)進(jìn)行了封鎖操作,我們?cè)谠L問管理-用戶-用戶列表[4]里可以根據(jù)賬號(hào)ID找到關(guān)于這個(gè)子賬號(hào)的詳細(xì)信息。
如果某個(gè)工作負(fù)載被刪除,想知道是誰(shuí)刪除的,這里以deployments/nginx為例來查詢:
objectRef.resource:deployments AND objectRef.name:"nginx"AND verb:"delete"
查詢結(jié)果:
揪出導(dǎo)致apiserver限頻的真兇
apiserver會(huì)有默認(rèn)的請(qǐng)求頻率限制保護(hù),避免惡意程序或bug導(dǎo)致對(duì)apiserver請(qǐng)求頻率過高,使得apiserver/etcd負(fù)載過高,影響正常請(qǐng)求。如果發(fā)生了限頻,我們可以通過審計(jì)來找出到底是誰(shuí)在發(fā)大量請(qǐng)求。
如果我們通過userAgent來分析統(tǒng)計(jì)請(qǐng)求的客戶端,首先需要修改下日志主題的鍵值索引,為userAgent字段開啟統(tǒng)計(jì):
通過以下SQL語(yǔ)句進(jìn)行統(tǒng)計(jì)每種客戶端請(qǐng)求apiserver的QPS大小:
*|SELECT CAST((__TIMESTAMP_US__/1000-__TIMESTAMP_US__/1000%1000)as TIMESTAMP)AS time,COUNT(1)AS qps,userAgent GROUP BY time,userAgent ORDER BY time
切換到圖標(biāo)分析,選擇折線圖,X軸用time,Y軸用qps,聚合列使用userAgent:
可以看到查到數(shù)據(jù)了,但可能結(jié)果太多,小面板顯示不下,點(diǎn)擊添加到儀表盤,放大顯示:
此例中可以看到kube-state-metrics這個(gè)客戶端對(duì)apiserver請(qǐng)求頻率遠(yuǎn)遠(yuǎn)高于其它客戶端,這就找到了"真兇"是kube-state-metrics,查看日志可以發(fā)現(xiàn)是因?yàn)镽BAC權(quán)問題導(dǎo)致kube-state-metrics不停的請(qǐng)求apiserver重試,觸發(fā)了apiserver的限頻:
I1009 13:13:09.760767 1 request.go:538]Throttling request took 1.393921018s,request:GET:https://172.16.252.1:443/api/v1/endpoints?limit=500&resourceVersion=1029843735
E1009 13:13:09.766106 1 reflector.go:156]pkg/mod/k8s.io/client-go v0.0.0-20191109102209-3c0d1af94be5/tools/cache/reflector.go:108:Failed to list*v1.Endpoints:endpoints is forbidden:User"system:serviceaccount:monitoring:kube-state-metrics"cannot list resource"endpoints"in API group""at the cluster scope
同理,如果要使用其它字段來區(qū)分要統(tǒng)計(jì)的客戶端,可以根據(jù)需求靈活修改SQL,比如使用user.username來區(qū)分,SQL這樣寫:
*|SELECT CAST((__TIMESTAMP_US__/1000-__TIMESTAMP_US__/1000%1000)as TIMESTAMP)AS time,COUNT(1)AS qps,user.username GROUP BY time,user.username ORDER BY time
顯示效果:
小結(jié)
本文介紹了如何利用TKE的集群審計(jì)功能來輔助我們排查問題,給出了一些實(shí)踐的例子。
參考資料
[1]集群審計(jì):https://cloud.tencent.com/document/product/457/48346
[2]日志檢索語(yǔ)法與規(guī)則:https://cloud.tencent.com/document/product/614/47044
[3]日志服務(wù)分析簡(jiǎn)介:https://cloud.tencent.com/document/product/614/44061
[4]訪問管理-用戶-用戶列表:https://console.cloud.tencent.com/cam