Kubernetes 稳定性保障手册 -- 日志专题
作者 | 悟鵬、沉醉
來源 | 阿里巴巴云原生公眾號
《Kubernetes 穩定性保障手冊》系列文章:
-
Kubernetes 穩定性保障手冊 – 極簡版
-
Kubernetes 穩定性保障手冊 – 日志專題(本文)
不論對于軟件的用戶還是開發者,日志都是很重要的信息源。日志可以用來表征軟件的運行狀態,在軟件運行不符合預期時提供豐富的信息,也可以用在開發階段調試軟件,方便定位問題。
軟件的生命周期涉及到 開發 和 運行 兩個階段,日志的生成是在軟件的開發階段,日志的使用集中在軟件的運行階段。
在開發階段規范化日志,有助于運行階段通過標準化方法分析日志、配置日志監控和告警。
在運行階段通過標準化方法使用日志,有助于低成本把握程序的運行態行為,及時感知異常,促進開發階段的迭代效率。
在軟件的生命周期中,運行階段時長占比會遠大于開發階段,即對日志的使用時長會遠大于開發階段寫日志邏輯的時長。在開發階段應用良好的日志規范,會對軟件生命周期的正常運行和快速迭代帶來很大幫助:
復雜度分析
程序中的元素可以抽象為兩部分:自身邏輯,依賴。兩類元素之間的交互為:自身邏輯閉環,自身邏輯與依賴交互。
從長期角度來看,交互環節出問題的概率會比自身邏輯出問題的概率高,因此要重點關注交互環節的日志邏輯。
同時,對日志的管理需要意識到 _誰會使用這些日志,_通常有 4 類角色:
- 用戶
- 維護者
- 安全人員
- 審計人員
用戶從黑盒角度使用軟件,通過日志了解軟件當前的運行狀態,關注重點是軟件正常的狀態。
維護者從白盒角度使用軟件,開發角色通過日志調試軟件,SRE 角色通過日志及時感知軟件的異常狀態,并通過日志上下文分析異常原因。
安全人員通過分析日志,了解惡意登錄、異常刪除等風險。
審計人員通過審計日志、應用日志,確認業務、架構的合規性。
根據上述不同的使用場景,我們可以梳理出幾類日志類別,進一步增強開發和運行階段對日志的理解:
開發階段
最佳實踐
理解了日志使用者關注的重點后,開發階段寫日志時,推薦使用如下最佳實踐:
- 使用 structured logs
- 不使用 format strings
- 使用 info 和 error 表征日志級別
- info 又可細化為多個級別,0~10,信息的重要性依次降低 (也可以參考《Kubernetes: sig-instrumentation/logging.md》
- 0:用戶想要看到的信息
- 1:維護者關注的白盒行為信息
- 10: 維護者調試用的信息
- info 又可細化為多個級別,0~10,信息的重要性依次降低 (也可以參考《Kubernetes: sig-instrumentation/logging.md》
- 使用具有過濾器能力的 log lib,通過 logger 自動過濾敏感信息
- 參見 《KEP: Kubernetes system components logs sanitization》
- 日志通過 stdout/stderr 輸出,關閉不必要的文本日志
- 避免額外的磁盤占用、IO 消耗、日志清理任務的維護等
對于 golang,可以考慮使用 klog 作為 logger 實現。
FAQ
為什么使用 structured logs?
structured logs 是一種結構化的日志格式,結構如下,其中 msg 表征通用的事件,多對的 k=v 用來具化事件:
msg k=v k=v … k=v
示例:
“Pod status updated” pod=“kube-system/kubedns” status=“ready”
對于開發階段,structured logs 通過固化的結構和字段語義,協助開發者思考程序邏輯狀態,有助于進一步控制程序復雜度和理解程序邏輯。
對于運行階段,structured logs 中的 k 天然具備索引的屬性,便于進行查詢和分析。也可以考慮將 msg 規范化,增加 事件 語義,通過限制 msg 語義來增強 msg 的作用。
為什么不使用 debug/warning/critical/fatal?
通過減少日志類型,降低使用和維護負擔。
debug 可以融入到 info 級別。
warning/critical 對于用戶和維護者都是模糊的詞,對于要采取的行動通常不具備指導意義。warning/critical 和 error 類似,表征程序運行過程中出現了預期外的現象,此時程序要么自動處理,要么交由外部人工介入判斷。若由程序自動處理,那么用戶和維護者感知到這類現象即可,info 可以滿足。若需要交由外部人工介入,那么 error 就可以滿足。對于問題的嚴重性,可放在運行階段,通過異常具體的信息來表征,如 ServiceUnavailable、Unauthorized 等。
fatal 是將 error 和 panic 兩類邏輯封裝了起來,在開發過程中可能會帶來執行邏輯上的不清晰,如決定是否 panic 的邏輯需要放在最頂層邏輯中,若在頂層邏輯之下調用 fatal,可能會帶來資源泄露、程序運行復雜度增加等問題。
為什么不使用 format strings?
format strings 是形如如下的結構:
klog.V(4).Infof(“Got a Retry-After %ds response for attempt %d to %v”, seconds, retries, url)
這種結構將 通用事件 和 具體內容 耦合在一起,不利于開發階段降低理解程序邏輯的成本,也不便于使用階段通過標準化的方式進行查詢、分析,增加日志的使用成本。
一種改善方式:
klog.V(4).InfoS(“got a retry-after response when requesting url”, “attempt”, retries, “after seconds”, seconds, “url”, url)
為什么要使用具有過濾器能力的 log lib?
開發過程中,可能會由于疏忽而將敏感信息輸出到日志中,如密碼、token 等信息。為了避免敏感信息泄露,需要加強 code review,同時也可以考慮在 logger 中配置過濾器,自動進行敏感信息的過濾,參見 《KEP: Kubernetes system components logs sanitization》 。
對于 golang,可以考慮使用 klog 作為 logger 實現,并配合 Kubernetes/component-base: sanitization 進行使用。
運行階段
最佳實踐
運行階段是對日志的使用,包括如下 4 個階段:
由于日志服務對程序的運行以及后續的運營極為重要,建議采用托管型的日志產品來滿足運行階段對日志的使用需求,如阿里云的 SLS 產品。
若在多個 region 部署集群,且集群的組件相同,在使用日志產品時,需要確保每個 region 中日志項目名稱規則的一致性。以阿里云 SLS 產品為例,若需要分別收集多個 region 的日志,則 project、logstore 的名稱需要在多個 region 中保持相同的規則,目的是便于通過統一的方法對不同集群的日志做查詢和分析。
通常情況下,日志產品會提供上述 4 個階段的服務,具體的使用方法可以參見對應日志產品的文檔,下述針對告警做重點分析。
告警
告警要滿足如下目標:
- 覆蓋面全
- 關鍵告警及時感知
基于開發階段的日志規范,可對 error 級別的告警做統一告警,將告警信息統一到低優先級的通知渠道,如表征普通告警的釘釘群。
若要及時感知到關鍵告警,需要從如下 2 個方面入手:
- 定義「關鍵告警」特征
- 分級告警,與相應的通知渠道結合
定義「關鍵告警」的特征是個 長期、持續完善 的過程,有 通用關鍵告警 和 業務關鍵告警。
通用關鍵告警 與業務耦合度小,如機器級別的關鍵告警 (宕機、內存壓力大、load 過高等)、托管服務的關鍵告警 (master 組件 panic/OOM、master 組件內存壓力大等),這部分告警配置可以作為基礎服務,作為集群交付的一部分。
業務關鍵告警 與業務耦合度大,需要與業務長期維護,重點關注「業務交互環節」的告警。
通知渠道通常會有如下幾類:
- IM 群 (如釘釘群等)
- 短信
- 電話
- webhook
這些通知渠道對人觸達的及時性不同,電話觸達性最好,短信其次,然后是 IM 群。webhook 本質上是條通道,可以對接不同的 IM 群或短信、電話渠道。
推薦如下三種告警級別:
配置告警是個長期、不斷迭代的過程,為了有助于告警有效性的迭代,配置每條告警時,可以考慮使用如下表格,規范化每條告警的配置,并深入思考告警配置的有效性:
FAQ
如何預先配置未模擬出的異常?
業務依賴的 OpenAPI/SDK/Lib 等通常都會有錯誤碼列表,如 阿里云:API 錯誤中心、Lib 中的 errors 文件等。可以基于該已知信息,枚舉依賴的 OpenAPI/SDK 中對業務有明顯負面影響的狀態碼做分級告警,如 ServiceUnavailable/Forbbiden/Unauthorized 等。
歡迎大家留言交流使用 Kubernetes 過程中的穩定性保障問題,以及對穩定性保障的期待工具或服務。大家也可通過郵箱聯系作者,進一步深入交流:flyer.zyf@alibaba-inc.com
總結
以上是生活随笔為你收集整理的Kubernetes 稳定性保障手册 -- 日志专题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Serverless 如何在阿里巴巴实现
- 下一篇: 基于 KubeVela 与 Kubern