Logging Operator - 優(yōu)雅的云原生日志管理方案 (三)

前文:
Logging Operator 的文章去年拖更很久了蔑担,原以為不會再有進度心墅,不過最近在自己的KubeGems項目中遇到處理日志可觀察性部分的需求時枷遂,又重新研究了下它漆枚,于是有了本系列的第三篇湿蛔。

Logging Operator是BanzaiCloud下開源的一個云原生場景下的日志采集方案榆骚。它在 2020 年 3 月的時候經(jīng)過重構(gòu)后的 v3 版本,底層憑借高效的 fluentbit 和插件豐富的 flunetd煌集,Logging Operator幾乎已經(jīng)完美的適配了 kubernetes 模式下的日志采集場景妓肢,未來可期。去年偶然間發(fā)現(xiàn)Rancher 在 2.5 版本之后也采用了 Logging Operator 作為統(tǒng)一的日志解決方案碉钠,足以說明它正在被一些以 Kubernetes 為核心的管理平臺接受,并集成至內(nèi)部(也包括小白的 KubeGems)栗弟。

本文作為前面兩篇的續(xù)篇污筷,主要跟大家談?wù)勛罱“子?Logging Operator 來解決用戶需求時的案例以及感受,所以我不打算花篇幅對其架構(gòu)和使用再做描述乍赫,感興趣的同學(xué)可以往前翻翻小白的文章瓣蛀。

關(guān)于指標(biāo)

應(yīng)用在容器化的過程中,由于容器文件系統(tǒng)的臨時性雷厂,開發(fā)者始終面臨自己的日志文件落盤和輸出 stdout 的兩難選擇惋增,當(dāng)研發(fā)將應(yīng)用日志管理的權(quán)利交給平臺時诈皿,意味著平臺要做的東西遠(yuǎn)比應(yīng)用一對一采集要復(fù)雜。在眾多需求中像棘,某天有SRE同學(xué)提問:“我們在阿里云中可以看到日志采集的實時速率稽亏,我們需要為此定制質(zhì)量監(jiān)控指標(biāo)”。這個問題也點醒了我避除,對于我們在做私有云時怎披,站在平臺外面對日志采集的管道內(nèi)部的觀察一直是處于信息缺失的盲區(qū)。好在 fluentbit 和 fluentd 都有獨立的prometheus 插件來暴露內(nèi)部的指標(biāo)瓶摆,不過在用 Logging Operator 后凉逛,它的指標(biāo)采集依托 prometheus operator, 且架構(gòu)足夠清晰群井,因此我們也可以有更多的選擇來滿足研發(fā)的需求状飞。

img

首先,我們在定義 logging 時可以讓 fluent bit(d)開啟 prometheus的采集

spec:
  fluentdSpec:
    metrics:
      serviceMonitor: true
      serviceMonitorConfig:
        honorLabels: true    // 打開honorLabels主要是為了保持組件原有的label书斜,避免標(biāo)簽被覆蓋诬辈。
  fluentbitSpec:
    metrics:
      serviceMonitor: true

這里可以看到 Logging Operator 主要依靠ServiceMonitor來做采集端的服務(wù)發(fā)現(xiàn),這里需要集群內(nèi)部運行 Prometheus Operator 以支持該 CRD荐吉。如果集群內(nèi)部沒有改資源類型焙糟,也可以借助 Prometheus 自身的服務(wù)發(fā)現(xiàn)機制來完成指標(biāo)的發(fā)現(xiàn)和采集。

不過這里僅僅只聲明了采集端的指標(biāo)入口样屠,這里面默認(rèn)只包含了 Fluent bit(d)內(nèi)部基本的運行狀態(tài)穿撮,如果要進一步實現(xiàn)對日志速率的監(jiān)控,就得需要 Flunetd 出馬了痪欲。早些年谷歌的GKE上還在用 Fluentd 作為日志采集器時悦穿,偶然間胡亂看(有目的的抄襲)的一條 Prometheus 插件配置引起了我的興趣

<filter **>
  @type prometheus
  <metric>
    type counter
    name logging_entry_count
    desc Total number of log entries generated by either application containers or system components
  </metric>
  <labels>
    container: $.kubernetes.container_name
    pod: $.kubernetes.pod_name
  </labels>
</filter>

這條規(guī)則將匹配所有進入Fluentd的日志, 并進入到 Prometheus 這個 filter 進行計數(shù)處理业踢。并將統(tǒng)計后的指標(biāo)以logging_entry_count命名栗柒,按照日志中的一些元數(shù)據(jù)信息作為指標(biāo)的 label,用于區(qū)分來至不同的容器知举。

由于需要解析日志的 kubernetes 元數(shù)據(jù)瞬沦,這里又需要 Fluentd 的 kubernetes-metadata-filter插件來做容器元數(shù)據(jù)的提取。在 Logging Operator中 Kubernetes 的元數(shù)據(jù)在 Fluent Bit 中解析雇锡,無需再在 Fluentd 額外添加該插件

雖然現(xiàn)在谷歌 GKE 現(xiàn)在也將日志采集器換成 Fluent Bit蛙埂,但上面這條配置在 Logging Operator 中并不“過時”。有了前車之鑒遮糖,我們可以在租戶的日志采集器(Flow / ClusterFlow)中將 Prometheus 插件引入進來用于分析日志速率绣的。當(dāng)中最簡單的實踐如下:

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
  name: default
  namespace: demo
spec:
  - prometheus:
      labels:
        container: $.kubernetes.container_name
        namespace: $.kubernetes.namespace_name
        node: $.kubernetes.host
        pod: $.kubernetes.pod_name
      metrics:
      - desc: Total number of log entries generated by either application containers
          or system components
        name: logging_entry_count
        type: counter
  globalOutputRefs:
  - containers-console
  match:
  - select:
      labels:
        what.you.want: collect

當(dāng)上述指標(biāo)入庫 Prometheus 之后,我們便可以通過這條語句查出當(dāng)前集群下日志采集器的應(yīng)用速率

sum by (pod) (rate(logging_entry_count[1m]))

此時欲账,如果云平臺是基于多租戶多環(huán)境架構(gòu)屡江,那么你甚至可以按照租戶環(huán)境、租戶級別分別來聚合日志的速率赛不。

file

上述僅僅是對日志總體速率的采集監(jiān)控惩嘉,如果我們需要對日志內(nèi)出現(xiàn)的特定的內(nèi)容或者對日志的byte 進行統(tǒng)計時,就需要結(jié)合其它的插件進行組合踢故。當(dāng)前 Logging Operator 支持的插件還遠(yuǎn)不如 Fluentd 豐富文黎,不過我們可以參照官方文檔惹苗,編寫需要的plugin集成至 Operator。Logging Operator Developers手冊

對于日志組件內(nèi)部的監(jiān)控和告警耸峭,Logging Operator 有一套自己的規(guī)則桩蓉,可以在 logging 這個 CR 中啟用這個功能

spec:
  fluentbitSpec:
    metrics:
      prometheusRules: true
  fluentdSpec:
    metrics:
      prometheusRules: true

這里的prometheusRules同樣是 Prometheus Operator 管理的資源,如果集群內(nèi)沒有此資源類型劳闹,可手動為 Prometheus 配置 Rules

回到最初的問題院究,如果需要將日志的采集速率作為應(yīng)用的量化指標(biāo)時,利用logging_entry_count即可本涕。

關(guān)于采樣

大多數(shù)情況下业汰,日志架構(gòu)不應(yīng)該對業(yè)務(wù)日志采取一些不可控的策略,造成應(yīng)用日志的不完整菩颖,例如采樣样漆。在這里顯然我也不推薦你在現(xiàn)有的架構(gòu)中啟用此功能。不過有時候晦闰,或者是部分魔法師無法有效控制程序的“洪荒之力”而瘋狂輸出時氛濒,平臺對于這類俏皮的應(yīng)用時就可以采樣的方案,畢竟保證整個日志通道的可用性是平臺第一優(yōu)先要考慮因素鹅髓。

Logging Operator 在日志采樣方面舞竿,采用了Throttle這個插件限速器,用一句話總結(jié)這個插件就是為每個進入到 filter 日志的管道引入了漏桶算法窿冯,讓其丟棄到超過速率限制的日志骗奖。

apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
  name: default
  namespace: demo
spec:
  - throttle:
      group_bucket_limit: 3000
      group_bucket_period_s: 10
      group_key: kubernetes.pod_name
  globalOutputRefs:
  - containers-console
  match:
  - select:
      labels:
        what.you.want: collect
  • group_key: 日志采樣的聚合 key,通常我們按照pod 名稱來做聚合醒串,亦或直接填寫kubenretes.metadata 的其它值聚合也行
  • group_bucket_period_s: 采樣的時間范圍执桌,默認(rèn) 60s
  • group_bucket_limit: 采樣期間的日志桶最大容量

日志的采樣速率由公式group_bucket_limit / group_bucket_period_s計算,當(dāng)group_key中的日志速率超過值時則會丟到后續(xù)日志芜赌。

由于 Throttle 并沒有采用令牌桶的算法仰挣,所以它不會有 burst 來應(yīng)對突發(fā)日志量的采集。

關(guān)于日志落盤

前面說到缠沈,所有基于容器的應(yīng)用程序膘壶,日志的最佳實踐是將日志定向到stdoutstderr中洲愤,但并不是所有“魔法師”都會遵循此約定颓芭,日志文件落盤仍然是當(dāng)下多數(shù)研發(fā)的選擇。雖然理論上來說容器的標(biāo)準(zhǔn) (錯誤)輸出也是將日志流集中重定到/var/log/containers下的日志文件上柬赐,但仍然受限于運行時配置或者其他硬盤原因帶來不可控的因素亡问。

對于日志落盤的場景,當(dāng)前業(yè)界也無統(tǒng)一的解決方案肛宋,但歸總起來其實也就2個實現(xiàn)方式:

  • sidecar 方案

    此方案是將日志采集器跟隨應(yīng)用容器一同運行在pod 當(dāng)中州藕,通過 volume 共享日志路徑的方式采集束世。常見的是方式是為 kubernetes 開發(fā)一套單獨的控制器,并采用MutatingWebhook在pod 啟動階段將 sidecar 的信息注入床玻。

    sidecar 的方案優(yōu)勢在于為每個應(yīng)用的 sidecar 配置相對獨立毁涉,但劣勢除占用過多資源外,采集器的更新迭代需跟隨應(yīng)用的生命周期笨枯,對于持續(xù)維護不太優(yōu)雅薪丁。

  • node agent 方案

    此方案將日志采集器以 DaemonSet 的方式運行在每個 Node 當(dāng)中遇西,然后在操作系統(tǒng)層面進行集中采集馅精。通常此方案需要平臺的研發(fā)需要做一定路徑策略,將固定 hostpath的 vulume 掛載給容器用于應(yīng)用日志落盤時使用粱檀。除此之外洲敢,我們知道所有 Kubernetes 默認(rèn)的存儲類型或者第三方的遵循 CSI 標(biāo)準(zhǔn)的存儲,都會將Volume掛載到/var/lib/kubelet/pods/<pod_id>/volumes/kubernetes.io~<type>/<pvc_id>/mount目錄下茄蚯,所以對于 node agent 更加優(yōu)雅一點的方案是在 node agent 中賦予調(diào)用 Kubernetes API 的權(quán)限压彭,讓其知曉被采集容器日志映射在主機下的路徑。

    node agent的方案的優(yōu)勢在于配置集中管理渗常,采集器跟應(yīng)用容器解耦壮不,互不影響。缺點在于采集器存在吞吐不足的風(fēng)險皱碘。

可以看到上述兩個方案中询一,不管哪一個都與 Logging Operator 沾不上關(guān)系。確實癌椿,當(dāng)下社區(qū)對此場景下還沒有一個行之有效的方案健蕊,不過按照其思路,我們可以將日志文件轉(zhuǎn)成標(biāo)準(zhǔn)(錯誤)輸出流來變相處理這個問題踢俄。

tail 來舉個直觀的例子來說明上述的方案缩功。

...
containers:
- args:
  - -F
  - /path/to/your/log/file.log
  command:
  - tail
  image: busybox
  name: stream-log-file-[name]
  volumeMounts:
  - mountPath: /path/to/your/log
    name: mounted-log
...

雖然tail是一個極其簡單粗暴的方式,且無法解決日志輪轉(zhuǎn)等問題都办,但它的確為Logging Operator提供了一個新的日志落盤場景下的方案嫡锌。雖然看上去與 sidecar 如出一轍,不過最大的區(qū)別在于琳钉,此方案能與 Logging Operator 現(xiàn)有的日志管道無縫兼容世舰,日志被采集后仍然能在 flow 階段進行處理。

總結(jié)

Logging Operator 站在自動化運維的角度確實有效解決了 Kubernetes 場景下日志架構(gòu)復(fù)雜和應(yīng)用日志采集難的問題槽卫,雖然當(dāng)下對落盤日志的支持還不夠全面跟压。但隨著接入的用戶逐漸成長,現(xiàn)在的問題在將來或許還有更好的解決方案歼培。不過震蒋,當(dāng)下它的確不失為最好的云原生日志架構(gòu)之一茸塞。


關(guān)注公眾號【云原生小白】,回復(fù)「入群」加入Loki學(xué)習(xí)群

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末查剖,一起剝皮案震驚了整個濱河市钾虐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笋庄,老刑警劉巖效扫,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異直砂,居然都是意外死亡菌仁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門静暂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來济丘,“玉大人,你說我怎么就攤上這事洽蛀∧∶裕” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵郊供,是天一觀的道長峡碉。 經(jīng)常有香客問我,道長驮审,這世上最難降的妖魔是什么鲫寄? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮头岔,結(jié)果婚禮上塔拳,老公的妹妹穿的比我還像新娘。我一直安慰自己峡竣,他們只是感情好靠抑,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著适掰,像睡著了一般颂碧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上类浪,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天载城,我揣著相機與錄音,去河邊找鬼费就。 笑死诉瓦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播睬澡,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼固额,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了煞聪?” 一聲冷哼從身側(cè)響起斗躏,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昔脯,沒想到半個月后啄糙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡云稚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年隧饼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碱鳞。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡桑李,死狀恐怖踱蛀,靈堂內(nèi)的尸體忽然破棺而出窿给,到底是詐尸還是另有隱情,我是刑警寧澤率拒,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布崩泡,位于F島的核電站,受9級特大地震影響猬膨,放射性物質(zhì)發(fā)生泄漏角撞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一勃痴、第九天 我趴在偏房一處隱蔽的房頂上張望谒所。 院中可真熱鬧,春花似錦沛申、人聲如沸劣领。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尖淘。三九已至,卻和暖如春著觉,著一層夾襖步出監(jiān)牢的瞬間村生,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工饼丘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留趁桃,地道東北人。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像卫病,于是被迫代替她去往敵國和親屡穗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容