轉轉容器日誌採集的演進之路

帶你聊技術發表於2023-02-02


  • 1 裸金屬時代

  • 2 容器時代

    • 2.1 log-pilot + flume 二次開發方案

    • 2.2 ByteCompass

  • 3 雲原生時代

    • 3.1 轉轉方案(hostPath volume場景) fb-advisor

    • 3.2 通用方案(hostPath volume場景)

    • 3.3 對比

  • 4 總結


轉轉自 2018 年開始推進容器技術在公司業務服務上的落地。在容器生態中,日誌採集是非常重要且不可或缺的元件之一,它不僅僅涉及到業務方錯誤日誌的排查,還涉及到日誌資料統計系統,成為戰略決策的重要參考依據。

1 裸金屬時代

在裸金屬時代,轉轉業務日誌的採集端由大資料部門二次開發的scribe+flume組成。當一臺伺服器上部署了A服務後,如果需要對該服務進行日誌採集,需要經過以下幾個步驟。

  1. 由運維部門提交工單,申請在該伺服器上,對A服務日誌進行採集
  2. 工單稽核透過
  3. 在該伺服器上自動化部署日誌採集元件 scribe+flume
  4. 透過工單中該臺主機的日誌採集申請資料,渲染出scribe配置檔案,指定該服務的日誌輸出目錄為採集目錄
  5. scribe服務根據自身配置檔案,採集目錄下的日誌檔案資料,傳送到flume的對應埠,最後由flume將日誌分發至kafka,hdfs等元件

在裸金屬時代,服務的部署節點的變化並不大。新服務上線,給該服務分配裸金屬伺服器進行部署,一般情況下,很長一段時間,該服務的部署節點都不會發生任何變更。只有在活動大促期間對該服務的擴容,以及某臺裸金屬伺服器硬體的損壞,才會導致部署在該主機上的服務,產生部署節點上的變更。

也正是由於在裸金屬時代,服務部署節點的超強粘性,轉轉日誌採集的workflow運轉正常。

轉轉容器日誌採集的演進之路

2 容器時代

2016年,容器技術在中國開枝散葉,鋪天蓋地的技術文獻在網路上流轉。轉轉是在2018年開始邁入到容器時代。

裸金屬到容器時代的轉變並不容易,轉轉選擇了一條几乎是“最穩健”的路來完成這場技術革新。這條“最穩健”的路有幾點要求。

  • 服務部署形式變化對業務方“無感知”,延用裸金屬時代的釋出系統,相容容器服務的釋出與管理
  • 伺服器/容器終端登入對業務方“無感知”,延用裸金屬時代的堡壘機登入形式,相容容器環境登入
  • 延用裸金屬時代的整體日誌處理方式
  • and so on

本篇文章我著重討論這場變革中的日誌採集系統。由於日誌處理體系是一個龐大且複雜的體系,在容器時代對其進行雲原生革命,為了推進容器化,先要花大力氣打造日誌採集基礎設施, 從時間和成本上,對於轉轉來說都是無法接受的。

容器服務執行特點與條件制約

  • 服務容器跨節點排程頻繁
  • 微服務框架已標準化日誌輸出目錄
  • 容器內的服務僅有文字日誌輸出,沒有stdout
  • 原有的裸金屬時代日誌採集流程無法動搖
  • 容器執行後會將標準化的日誌輸出路徑掛載到宿主機目錄

2.1 log-pilot + flume 二次開發方案

當時的大資料團隊分析了容器服務執行的特點,針對該特點,打造了一套基於裸金屬時代的日誌採集相容方案。在原有日誌元件及功能都完全不變的前提下,基於log-pilot+flume二次開發了一套日誌轉儲引擎。

利用log-pilot的容器自動發現功能,提取出需要採集日誌的容器後設資料資訊,並渲染出一個 flume 的配置檔案,由 flume 將容器內的日誌,採集後轉儲到本地宿主機的一個目錄下,最後由二次開發後的 log-pilot 更新宿主機上的scribe配置檔案,並重啟 scribe 程式,這樣即對接上了之前裸金屬時代的後續日誌採集流程。

轉轉容器日誌採集的演進之路

為了相容裸金屬時代不可動搖的日誌採集地位,大資料部門貢獻了轉轉過渡到容器化的第一代日誌採集系統。

該系統初期運轉良好,但隨著轉轉服務容器化率的提升,日誌體量越來越大,這種日誌的轉儲模式直接導致了日質量接近翻番,不僅磁碟容量受到巨大考驗,日誌保留週期從30天逐漸縮短到了3天,而且 CPU iowait 也開始飆升,叢集節點每天的 iotuil 長期在 90% 以上,繁重的 IO 負擔已經成了阻礙業務進一步容器化不容忽視的阻礙。在保留裸金屬時代日誌採集流程不變的基礎上,運維針對容器場景做了進一步最佳化。

2.2 ByteCompass

運維自研的“日誌指南者”,主要目的為剔除掉 log-pilot + flume 這個日誌轉儲元件。少了一次日誌的讀取和寫入,磁碟空間和IO壓力會驟減。ByteCompass 為運維全自研元件,以 systemd 管理執行在宿主機。

轉轉容器日誌採集的演進之路

ByteCompass 借鑑了 log-pilot 感知容器變化的原理,watch 了 dockerd 的 api 介面,實時接收容器變化的事件資訊。當有容器新增時,判斷其是否帶有日誌採集標識,如果有,則進一步從容器配置的環境變數資訊中讀取日誌採集的後設資料資訊,最後將該容器資訊根據模板渲染成新的 scribe.conf 配置檔案,直接覆蓋宿主機中的該檔案,並對該宿主機的 scribe 程式執行重啟操作。

經過 ByteCompass 對日誌採集的最佳化,剔除掉了冗餘的日誌轉儲,無縫銜接了容器技術棧中的服務日誌特徵和裸金屬時代的日誌採集流程。與裸金屬時代日誌採集流程對比如下:

轉轉容器日誌採集的演進之路

ByteCompass 改造後的日誌採集,實現了叢集節點平均 iowait 從 10% 降到 1%,波峰從 25%+ 降低到 3%-;ioutil 全天平均值下降到 7%以下,降幅達到92%;本地日誌保留時間也從3天恢復到了7天以上。

3 雲原生時代

在解決了磁碟瓶頸後,轉轉的容器化程式加速進行。容器時代為了相容裸金屬時代遺留的使用者習慣,對容器環境做了很大程度上的妥協。隨著服務容器化的逐漸深入,轉轉開始從容器時代這個過渡階段,逐步開啟雲原生時代。

以上裸金屬時代和容器時代的日誌是按需採集,只有業務申請了日誌採集,才會將日誌採集走並做資料分析和處理。使用者查詢 info 及 error 日誌排錯,依然是很原始的登入到裸金屬伺服器上或登入到容器中,或透過日誌查詢平臺,直接檢索容器服務所在物理機掛載到 hostPath 中的日誌檔案。

雲原生時代給日誌採集提出了更高的要求,在保留現有日誌分析的基礎之上,還要實現全量日誌的集中儲存與檢索。以及考慮到未來 k8s 版本對 dockerd 依賴的剔除和更靈活的宿主機擴縮容,轉轉運維開始規劃全新的日誌採集系統以適應雲原生時代的需求。

由於轉轉容器預設會將日誌目錄掛載到宿主機,開源通用的文字檔案採集方案無法將 pod 後設資料資訊附加到日誌中,所以轉轉運維依託於 filebeat 自研了一個 filebeat 的 “助手” --- fb-advisor

3.1 轉轉方案(hostPath volume場景) fb-advisor

轉轉容器日誌採集的演進之路

受益於轉轉內部的容器規範,不管容器的日誌是否需要採集,容器的日誌目錄都是以 hostPath 機制掛載到宿主機目錄上的。fb-advisor 為轉轉自研元件,watch kube-apiserver 的 pod api,實時接收本節點的 pod 事件。如果為新增 pod 事件,則讀取 pod 後設資料資訊,識別 pod 中日誌目錄掛載的宿主機路徑,將其儲存在 filebeat 的配置檔案,放在 config.d 目錄下。filebeat 配置自動 reload 即可。

日誌採集後,集中生產到 kafka 中介軟體,再由自研的消費者將日誌處理後完成資料的分發,從而替換掉 scribe + flume “黃金組合”。

以下為與 ByteCompass 方案的對比

轉轉容器日誌採集的演進之路

3.2 通用方案(hostPath volume場景)

該通用方案同時適用於 hostPath volume 場景和容器內預設檔案系統場景的文字檔案日誌的採集,並同時附加 pod 後設資料資訊。

filebeat 中的 add_kubernetes_metadata processor,是專門用來給日誌附加 pod 後設資料資訊用的外掛。

processors:
  - add_kubernetes_metadata:
      in_cluster: false
      host: 10.140.24.108
      kube_config: /pathto/kubeconfig
      namespace: default
      default_indexers.enabled: false
      default_matchers.enabled: false
      sync_period: 60m
      indexers:
        - pod_uid:
      matchers:
        - logs_path:
            logs_path: '/var/lib/kubelet/pods/'
            resource_type: 'pod'
  • in_cluster: 是否執行在容器環境中
  • host: 主機名
  • kube_config: kubeconfig 檔案絕對路徑
  • namespace: 監聽的名稱空間,如果不寫,預設監聽所有名稱空間
  • default_indexers.enabled: 禁用預設的 indexers
  • default_matchers.enabled: 禁用預設的 matchers
  • sync_period: 指定列出歷史資源的超時時間
  • indexers: 使用 pod 後設資料為每個 pod 建立唯一識別符號
  • indexers.pod_uid: 使用 pod 的 UID 標識 pod 後設資料
  • matchers: 構造與索引建立的識別符號匹配的查詢鍵
  • matchers.logs_path: 使用從儲存在該欄位中的日誌路徑中提取的識別符號查詢 pod 後設資料
  • matchers.logs_path.logs_path: k8s 資料目錄絕對路徑
  • matchers.logs_path.resource_type: 根據 pod UID 為查詢鍵進行查詢

該通用方案中,add_kubernetes_metadata 負責連線 kube-apiserver 獲取後設資料資訊,並在日誌採集路徑中 /var/lib/kubelet/pods/<pod UID>/volumes/<volume name>/... 提取 pod UID 資訊,並以此為鍵,進行後設資料查詢,找到後設資料後,將其後設資料資訊附加到日誌條目中。

3.3 對比

對比轉轉方案和通用方案,主要區別在於轉轉方案的定製化程度更高,可以自由選擇需要附加的後設資料資訊,而通用方案預設會附加上容器所有的 label 資訊。

從日誌採集安全性來說,轉轉方案也略勝一籌,轉轉利用日誌目錄掛載到宿主機的特性,將 filebeat 的日誌採集路徑直接指向宿主機路徑。這樣的日誌採集,脫離了 pod 資料目錄跟隨 pod 生命週期的特點,避免由於某些問題導致日誌採集速率嚴重低於日誌產出速率,且 pod 被重新排程後,資料目錄被清理而導致的日誌資料丟失。

4 總結

雲原生時代的日誌採集方案百花齊放,沒有絕對通用的解決方案,沒有絕對完美的解決方案,只有依據自身實際特點,最合適的解決方案,希望本篇文章能帶給讀者關於日誌採集方案中的一些不同思路。

轉轉的日誌採集從裸金屬時代的 scribe + flume,到容器時代的 log-pilot + flume + scribe + flume,再到 ByteCompass + scribe + flume,最後到雲原生時代的 filebeat + fb-advisor,徹底擺脫了裸金屬時代日誌採集的影子,並且脫離了 dockerd 的依賴,開始朝著更加雲原生的方向繼續披荊斬棘。

本篇文章僅介紹了日誌採集的宏觀 workflow,內部細節有其內部特殊性,無法一一展現,歡迎留言進行深入的細節討論。


關於作者

呂瑞,轉轉運維,主要負責轉轉容器技術方向


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2933718/,如需轉載,請註明出處,否則將追究法律責任。

相關文章