天天看點

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

前言

上一期主要介紹Kubernetes日志輸出的一些注意事項,日志輸出最終的目的還是做統一的采集和分析。在Kubernetes中,日志采集和普通虛拟機的方式有很大不同,相對實作難度和部署代價也略大,但若使用恰當則比傳統方式自動化程度更高、運維代價更低。

Kubernetes日志采集難點

在Kubernetes中,日志采集相比傳統虛拟機、實體機方式要複雜很多,最根本的原因是Kubernetes把底層異常屏蔽,提供更加細粒度的資源排程,向上提供穩定、動态的環境。是以日志采集面對的是更加豐富、動态的環境,需要考慮的點也更加的多。

例如:

  1. 對于運作時間很短的Job類應用,從啟動到停止隻有幾秒的時間,如何保證日志采集的實時性能夠跟上而且資料不丢?
  2. K8s一般推薦使用大規格節點,每個節點可以運作10-100+的容器,如何在資源消耗盡可能低的情況下采集100+的容器?
  3. 在K8s中,應用都以yaml的方式部署,而日志采集還是以手工的配置檔案形式為主,如何能夠讓日志采集以K8s的方式進行部署?
Kubernetes 傳統方式
日志種類 檔案、stdout、主控端檔案、journal 檔案、journal
日志源 業務容器、系統元件、主控端 業務、主控端
采集方式 Agent(Sidecar、DaemonSet)、直寫(DockerEngine、業務) Agent、直寫
單機應用數 10-100 1-10
應用動态性
節點動态性
采集部署方式 手動、Yaml 手動、自定義

采集方式:主動 or 被動

日志的采集方式分為被動采集和主動推送兩種,在K8s中,被動采集一般分為Sidecar和DaemonSet兩種方式,主動推送有DockerEngine推送和業務直寫兩種方式。

  • DockerEngine本身具有LogDriver功能,可通過配置不同的LogDriver将容器的stdout通過DockerEngine寫入到遠端存儲,以此達到日志采集的目的。這種方式的可定制化、靈活性、資源隔離性都很低,一般不建議在生産環境中使用。
  • 業務直寫是在應用中內建日志采集的SDK,通過SDK直接将日志發送到服務端。這種方式省去了落盤采集的邏輯,也不需要額外部署Agent,對于系統的資源消耗最低,但由于業務和日志SDK強綁定,整體靈活性很低,一般隻有日志量極大的場景中使用。
  • DaemonSet方式在每個node節點上隻運作一個日志agent,采集這個節點上所有的日志。DaemonSet相對資源占用要小很多,但擴充性、租戶隔離性受限,比較适用于功能單一或業務不是很多的叢集。
  • Sidecar方式為每個POD單獨部署日志agent,這個agent隻負責一個業務應用的日志采集。Sidecar相對資源占用較多,但靈活性以及多租戶隔離性較強,建議大型的K8S叢集或作為PAAS平台為多個業務方服務的叢集使用該方式。
系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

總結下來:DockerEngine直寫一般不推薦;業務直寫推薦在日志量極大的場景中使用;DaemonSet一般在中小型叢集中使用;Sidecar推薦在超大型的叢集中使用。詳細的各種采集方式對比如下:

DockerEngine 業務直寫 DaemonSet方式 Sidecar方式
采集日志類型 标準輸出 業務日志 标準輸出+部分檔案 檔案
部署運維 低,原生支援 低,隻需維護好配置檔案即可 一般,需維護DaemonSet 較高,每個需要采集日志的POD都需要部署sidecar容器
日志分類存儲 無法實作 業務獨立配置 一般,可通過容器/路徑等映射 每個POD可單獨配置,靈活性高
多租戶隔離 弱,日志直寫會和業務邏輯競争資源 一般,隻能通過配置間隔離 強,通過容器進行隔離,可單獨配置設定資源
支援叢集規模 本地存儲無限制,若使用syslog、fluentd會有單點限制 無限制 取決于配置數
資源占用 低,docker
engine提供 整體最低,省去采集開銷 較低,每個節點運作一個容器 較高,每個POD運作一個容器
查詢便捷性 低,隻能grep原始日志 高,可根據業務特點進行定制 較高,可進行自定義的查詢、統計
可定制性 高,可自由擴充 高,每個POD單獨配置
耦合度 高,與DockerEngine強綁定,修改需要重新開機DockerEngine 高,采集子產品修改/更新需要重新釋出業務 低,Agent可獨立更新 一般,預設采集Agent更新對應Sidecar業務也會重新開機(有一些擴充包可以支援Sidecar熱更新)
适用場景 測試、POC等非生産場景 對性能要求極高的場景 日志分類明确、功能較單一的叢集 大型、混合型、PAAS型叢集

日志輸出:Stdout or 檔案

和虛拟機/實體機不同,K8s的容器提供标準輸出和檔案兩種方式。在容器中,标準輸出将日志直接輸出到stdout或stderr,而DockerEngine接管stdout和stderr檔案描述符,将日志接收後按照DockerEngine配置的LogDriver規則進行處理;日志列印到檔案的方式和虛拟機/實體機基本類似,隻是日志可以使用不同的存儲方式,例如預設存儲、EmptyDir、HostVolume、NFS等。

雖然使用Stdout列印日志是Docker官方推薦的方式,但大家需要注意這個推薦是基于容器隻作為簡單應用的場景,實際的業務場景中我們還是建議大家盡可能使用檔案的方式,主要的原因有以下幾點:

  1. Stdout性能問題,從應用輸出stdout到服務端,中間會經過好幾個流程(例如普遍使用的JSON LogDriver):應用stdout -> DockerEngine -> LogDriver -> 序列化成JSON -> 儲存到檔案 -> Agent采集檔案 -> 解析JSON -> 上傳服務端。整個流程相比檔案的額外開銷要多很多,在壓測時,每秒10萬行日志輸出就會額外占用DockerEngine 1個CPU核。
  2. Stdout不支援分類,即所有的輸出都混在一個流中,無法像檔案一樣分類輸出,通常一個應用中有AccessLog、ErrorLog、InterfaceLog(調用外部接口的日志)、TraceLog等,而這些日志的格式、用途不一,如果混在同一個流中将很難采集和分析。
  3. Stdout隻支援容器的主程式輸出,如果是daemon/fork方式運作的程式将無法使用stdout。
  4. 檔案的Dump方式支援各種政策,例如同步/異步寫入、緩存大小、檔案輪轉政策、壓縮政策、清除政策等,相對更加靈活。

是以我們建議線上應用使用檔案的方式輸出日志,Stdout隻在功能單一的應用或一些K8s系統/運維元件中使用。

CICD內建:Logging Operator

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

Kubernetes提供了标準化的業務部署方式,可以通過yaml(K8s API)來聲明路由規則、暴露服務、挂載存儲、運作業務、定義縮擴容規則等,是以Kubernetes很容易和CICD系統內建。而日志采集也是運維監控過程中的重要部分,業務上線後的所有日志都要進行實時的收集。

原始的方式是在釋出之後手動去部署日志采集的邏輯,這種方式需要手工幹預,違背CICD自動化的宗旨;為了實作自動化,有人開始基于日志采集的API/SDK包裝一個自動部署的服務,在釋出後通過CICD的webhook觸發調用,但這種方式的開發代價很高。

在Kubernetes中,日志最标準的內建方式是以一個新資源注冊到Kubernetes系統中,以Operator(CRD)的方式來進行管理和維護。在這種方式下,CICD系統不需要額外的開發,隻需在部署到Kubernetes系統時附加上日志相關的配置即可實作。

Kubernetes日志采集方案

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

早在Kubernetes出現之前,我們就開始為容器環境開發日志采集方案,随着K8s的逐漸穩定,我們開始将很多業務遷移到K8s平台上,是以也基于之前的基礎專門開發了一套K8s上的日志采集方案。主要具備的功能有:

  1. 支援各類資料的實時采集,包括容器檔案、容器Stdout、主控端檔案、Journal、Event等;
  2. 支援多種采集部署方式,包括DaemonSet、Sidecar、DockerEngine LogDriver等;
  3. 支援對日志資料進行富化,包括附加Namespace、Pod、Container、Image、Node等資訊;
  4. 穩定、高可靠,基于阿裡自研的Logtail采集Agent實作,目前全網已有幾百萬的部署執行個體;
  5. 基于CRD進行擴充,可使用Kubernetes部署釋出的方式來部署日志采集規則,與CICD完美內建。

安裝日志采集元件

目前這套采集方案已經對外開放,我們提供了一個Helm安裝包,其中包括Logtail的DaemonSet、AliyunlogConfig的CRD聲明以及CRD Controller,安裝之後就能直接使用DaemonSet采集以及CRD配置了。安裝方式如下:

  1. 阿裡雲Kubernetes叢集在開通的時候可以勾選安裝,這樣在叢集建立的時候會自動安裝上述元件。如果開通的時候沒有安裝,則可以 手動安裝
  2. 如果是自建的Kubernetes,無論是在阿裡雲上自建還是在其他雲或者是線下,也可以使用這樣采集方案,具體安裝方式參考[自建Kubernetes安裝]()。

安裝好上述元件之後,Logtail和對應的Controller就會運作在叢集中,但預設這些元件并不會采集任何日志,需要配置日志采集規則來采集指定Pod的各類日志。

采集規則配置:環境變量 or CRD

除了在日志服務控制台上手動配置之外,對于Kubernetes還額外支援兩種配置方式:環境變量和CRD。

環境變量是自swarm時代一直使用的配置方式,隻需要在想要采集的容器環境變量上聲明需要采集的資料位址即可,Logtail會自動将這些資料采集到服務端。這種方式部署簡單,學習成本低,很容易上手;但能夠支援的配置規則很少,很多進階配置(例如解析方式、過濾方式、黑白名單等)都不支援,而且這種聲明的方式不支援修改/删除,每次修改其實都是建立1個新的采集配置,曆史的采集配置需要手動清理,否則會造成資源浪費。

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集
CRD配置方式

是非常符合Kubernetes官方推薦的标準擴充方式,讓采集配置以K8s資源的方式進行管理,通過向Kubernetes部署AliyunLogConfig這個特殊的CRD資源來聲明需要采集的資料。例如下面的示例就是部署一個容器标準輸出的采集,其中定義需要Stdout和Stderr都采集,并且排除環境變量中包含COLLEXT_STDOUT_FLAG:false的容器。

基于CRD的配置方式以Kubernetes标準擴充資源的方式進行管理,支援配置的增删改查完整語義,而且支援各種進階配置,是我們極其推薦的采集配置方式。

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

采集規則推薦的配置方式

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

實際應用場景中,一般都是使用DaemonSet或DaemonSet與Sidecar混用方式,DaemonSet的優勢是資源使用率高,但有一個問題是DaemonSet的所有Logtail都共享全局配置,而單一的Logtail有配置支撐的上限,是以無法支撐應用數比較多的叢集。

上述是我們給出的推薦配置方式,核心的思想是:

  1. 一個配置盡可能多的采集同類資料,減少配置數,降低DaemonSet壓力;
  2. 核心的應用采集要給予充分的資源,可以使用Sidecar方式;
  3. 配置方式盡可能使用CRD方式;
  4. Sidecar由于每個Logtail是單獨的配置,是以沒有配置數的限制,這種比較适合于超大型的叢集使用。

實踐1-中小型叢集

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

絕大部分Kubernetes叢集都屬于中小型的,對于中小型沒有明确的定義,一般應用數在500以内,節點規模1000以内,沒有職能明确的Kubernetes平台運維。這種場景應用數不會特别多,DaemonSet可以支撐所有的采集配置:

  1. 絕大部分業務應用的資料使用DaemonSet采集方式
  2. 核心應用(對于采集可靠性要求比較高,例如訂單/交易系統)使用Sidecar方式單獨采集

實踐2-大型叢集

系列文章:Kubernetes日志采集最佳實踐前言Kubernetes日志采集難點采集方式:主動 or 被動日志輸出:Stdout or 檔案CICD內建:Logging OperatorKubernetes日志采集方案實踐1-中小型叢集實踐2-大型叢集

對于一些用作PAAS平台的大型/超大型叢集,一般業務在1000以上,節點規模也在1000以上,有專門的Kubernetes平台運維人員。這種場景下應用數沒有限制,DaemonSet無法支援,是以必須使用Sidecar方式,整體規劃如下:

  1. Kubernetes平台本身的系統元件日志、核心日志相對種類固定,這部分日志使用DaemonSet采集,主要為平台的運維人員提供服務;
  2. 各個業務的日志使用Sidecar方式采集,每個業務可以獨立設定Sidecar的采集目的位址,為業務的DevOps人員提供足夠的靈活性。                                                           

繼續閱讀