系列文章:Kubernetes日志采集最佳实践
前言
上一期主要介紹Kubernetes日志輸出的一些注意事項(xiàng),日志輸出最終的目的還是做統(tǒng)一的采集和分析。在Kubernetes中,日志采集和普通虛擬機(jī)的方式有很大不同,相對(duì)實(shí)現(xiàn)難度和部署代價(jià)也略大,但若使用恰當(dāng)則比傳統(tǒng)方式自動(dòng)化程度更高、運(yùn)維代價(jià)更低。
Kubernetes日志采集難點(diǎn)
在Kubernetes中,日志采集相比傳統(tǒng)虛擬機(jī)、物理機(jī)方式要復(fù)雜很多,最根本的原因是Kubernetes把底層異常屏蔽,提供更加細(xì)粒度的資源調(diào)度,向上提供穩(wěn)定、動(dòng)態(tài)的環(huán)境。因此日志采集面對(duì)的是更加豐富、動(dòng)態(tài)的環(huán)境,需要考慮的點(diǎn)也更加的多。
例如:
| 日志種類 | 文件、stdout、宿主機(jī)文件、journal | 文件、journal |
| 日志源 | 業(yè)務(wù)容器、系統(tǒng)組件、宿主機(jī) | 業(yè)務(wù)、宿主機(jī) |
| 采集方式 | Agent(Sidecar、DaemonSet)、直寫(DockerEngine、業(yè)務(wù)) | Agent、直寫 |
| 單機(jī)應(yīng)用數(shù) | 10-100 | 1-10 |
| 應(yīng)用動(dòng)態(tài)性 | 高 | 低 |
| 節(jié)點(diǎn)動(dòng)態(tài)性 | 高 | 低 |
| 采集部署方式 | 手動(dòng)、Yaml | 手動(dòng)、自定義 |
采集方式:主動(dòng) or 被動(dòng)
日志的采集方式分為被動(dòng)采集和主動(dòng)推送兩種,在K8s中,被動(dòng)采集一般分為Sidecar和DaemonSet兩種方式,主動(dòng)推送有DockerEngine推送和業(yè)務(wù)直寫兩種方式。
- DockerEngine本身具有LogDriver功能,可通過配置不同的LogDriver將容器的stdout通過DockerEngine寫入到遠(yuǎn)端存儲(chǔ),以此達(dá)到日志采集的目的。這種方式的可定制化、靈活性、資源隔離性都很低,一般不建議在生產(chǎn)環(huán)境中使用。
- 業(yè)務(wù)直寫是在應(yīng)用中集成日志采集的SDK,通過SDK直接將日志發(fā)送到服務(wù)端。這種方式省去了落盤采集的邏輯,也不需要額外部署Agent,對(duì)于系統(tǒng)的資源消耗最低,但由于業(yè)務(wù)和日志SDK強(qiáng)綁定,整體靈活性很低,一般只有日志量極大的場(chǎng)景中使用。
- DaemonSet方式在每個(gè)node節(jié)點(diǎn)上只運(yùn)行一個(gè)日志agent,采集這個(gè)節(jié)點(diǎn)上所有的日志。DaemonSet相對(duì)資源占用要小很多,但擴(kuò)展性、租戶隔離性受限,比較適用于功能單一或業(yè)務(wù)不是很多的集群。
- Sidecar方式為每個(gè)POD單獨(dú)部署日志agent,這個(gè)agent只負(fù)責(zé)一個(gè)業(yè)務(wù)應(yīng)用的日志采集。Sidecar相對(duì)資源占用較多,但靈活性以及多租戶隔離性較強(qiáng),建議大型的K8S集群或作為PAAS平臺(tái)為多個(gè)業(yè)務(wù)方服務(wù)的集群使用該方式。
總結(jié)下來:DockerEngine直寫一般不推薦;業(yè)務(wù)直寫推薦在日志量極大的場(chǎng)景中使用;DaemonSet一般在中小型集群中使用;Sidecar推薦在超大型的集群中使用。詳細(xì)的各種采集方式對(duì)比如下:
| 采集日志類型 | 標(biāo)準(zhǔn)輸出 | 業(yè)務(wù)日志 | 標(biāo)準(zhǔn)輸出+部分文件 | 文件 |
| 部署運(yùn)維 | 低,原生支持 | 低,只需維護(hù)好配置文件即可 | 一般,需維護(hù)DaemonSet | 較高,每個(gè)需要采集日志的POD都需要部署sidecar容器 |
| 日志分類存儲(chǔ) | 無法實(shí)現(xiàn) | 業(yè)務(wù)獨(dú)立配置 | 一般,可通過容器/路徑等映射 | 每個(gè)POD可單獨(dú)配置,靈活性高 |
| 多租戶隔離 | 弱 | 弱,日志直寫會(huì)和業(yè)務(wù)邏輯競(jìng)爭(zhēng)資源 | 一般,只能通過配置間隔離 | 強(qiáng),通過容器進(jìn)行隔離,可單獨(dú)分配資源 |
| 支持集群規(guī)模 | 本地存儲(chǔ)無限制,若使用syslog、fluentd會(huì)有單點(diǎn)限制 | 無限制 | 取決于配置數(shù) | 無限制 |
| 資源占用 | 低,docker | |||
| engine提供 | 整體最低,省去采集開銷 | 較低,每個(gè)節(jié)點(diǎn)運(yùn)行一個(gè)容器 | 較高,每個(gè)POD運(yùn)行一個(gè)容器 | |
| 查詢便捷性 | 低,只能grep原始日志 | 高,可根據(jù)業(yè)務(wù)特點(diǎn)進(jìn)行定制 | 較高,可進(jìn)行自定義的查詢、統(tǒng)計(jì) | 高,可根據(jù)業(yè)務(wù)特點(diǎn)進(jìn)行定制 |
| 可定制性 | 低 | 高,可自由擴(kuò)展 | 低 | 高,每個(gè)POD單獨(dú)配置 |
| 耦合度 | 高,與DockerEngine強(qiáng)綁定,修改需要重啟DockerEngine | 高,采集模塊修改/升級(jí)需要重新發(fā)布業(yè)務(wù) | 低,Agent可獨(dú)立升級(jí) | 一般,默認(rèn)采集Agent升級(jí)對(duì)應(yīng)Sidecar業(yè)務(wù)也會(huì)重啟(有一些擴(kuò)展包可以支持Sidecar熱升級(jí)) |
| 適用場(chǎng)景 | 測(cè)試、POC等非生產(chǎn)場(chǎng)景 | 對(duì)性能要求極高的場(chǎng)景 | 日志分類明確、功能較單一的集群 | 大型、混合型、PAAS型集群 |
?
日志輸出:Stdout or 文件
和虛擬機(jī)/物理機(jī)不同,K8s的容器提供標(biāo)準(zhǔn)輸出和文件兩種方式。在容器中,標(biāo)準(zhǔn)輸出將日志直接輸出到stdout或stderr,而DockerEngine接管stdout和stderr文件描述符,將日志接收后按照DockerEngine配置的LogDriver規(guī)則進(jìn)行處理;日志打印到文件的方式和虛擬機(jī)/物理機(jī)基本類似,只是日志可以使用不同的存儲(chǔ)方式,例如默認(rèn)存儲(chǔ)、EmptyDir、HostVolume、NFS等。
雖然使用Stdout打印日志是Docker官方推薦的方式,但大家需要注意這個(gè)推薦是基于容器只作為簡(jiǎn)單應(yīng)用的場(chǎng)景,實(shí)際的業(yè)務(wù)場(chǎng)景中我們還是建議大家盡可能使用文件的方式,主要的原因有以下幾點(diǎn):
因此我們建議線上應(yīng)用使用文件的方式輸出日志,Stdout只在功能單一的應(yīng)用或一些K8s系統(tǒng)/運(yùn)維組件中使用。
CICD集成:Logging Operator
Kubernetes提供了標(biāo)準(zhǔn)化的業(yè)務(wù)部署方式,可以通過yaml(K8s API)來聲明路由規(guī)則、暴露服務(wù)、掛載存儲(chǔ)、運(yùn)行業(yè)務(wù)、定義縮擴(kuò)容規(guī)則等,所以Kubernetes很容易和CICD系統(tǒng)集成。而日志采集也是運(yùn)維監(jiān)控過程中的重要部分,業(yè)務(wù)上線后的所有日志都要進(jìn)行實(shí)時(shí)的收集。
原始的方式是在發(fā)布之后手動(dòng)去部署日志采集的邏輯,這種方式需要手工干預(yù),違背CICD自動(dòng)化的宗旨;為了實(shí)現(xiàn)自動(dòng)化,有人開始基于日志采集的API/SDK包裝一個(gè)自動(dòng)部署的服務(wù),在發(fā)布后通過CICD的webhook觸發(fā)調(diào)用,但這種方式的開發(fā)代價(jià)很高。
在Kubernetes中,日志最標(biāo)準(zhǔn)的集成方式是以一個(gè)新資源注冊(cè)到Kubernetes系統(tǒng)中,以O(shè)perator(CRD)的方式來進(jìn)行管理和維護(hù)。在這種方式下,CICD系統(tǒng)不需要額外的開發(fā),只需在部署到Kubernetes系統(tǒng)時(shí)附加上日志相關(guān)的配置即可實(shí)現(xiàn)。
Kubernetes日志采集方案
早在Kubernetes出現(xiàn)之前,我們就開始為容器環(huán)境開發(fā)日志采集方案,隨著K8s的逐漸穩(wěn)定,我們開始將很多業(yè)務(wù)遷移到K8s平臺(tái)上,因此也基于之前的基礎(chǔ)專門開發(fā)了一套K8s上的日志采集方案。主要具備的功能有:
安裝日志采集組件
目前這套采集方案已經(jīng)對(duì)外開放,我們提供了一個(gè)Helm安裝包,其中包括Logtail的DaemonSet、AliyunlogConfig的CRD聲明以及CRD Controller,安裝之后就能直接使用DaemonSet采集以及CRD配置了。安裝方式如下:
安裝好上述組件之后,Logtail和對(duì)應(yīng)的Controller就會(huì)運(yùn)行在集群中,但默認(rèn)這些組件并不會(huì)采集任何日志,需要配置日志采集規(guī)則來采集指定Pod的各類日志。
采集規(guī)則配置:環(huán)境變量 or CRD
除了在日志服務(wù)控制臺(tái)上手動(dòng)配置之外,對(duì)于Kubernetes還額外支持兩種配置方式:環(huán)境變量和CRD。
環(huán)境變量是自swarm時(shí)代一直使用的配置方式,只需要在想要采集的容器環(huán)境變量上聲明需要采集的數(shù)據(jù)地址即可,Logtail會(huì)自動(dòng)將這些數(shù)據(jù)采集到服務(wù)端。這種方式部署簡(jiǎn)單,學(xué)習(xí)成本低,很容易上手;但能夠支持的配置規(guī)則很少,很多高級(jí)配置(例如解析方式、過濾方式、黑白名單等)都不支持,而且這種聲明的方式不支持修改/刪除,每次修改其實(shí)都是創(chuàng)建1個(gè)新的采集配置,歷史的采集配置需要手動(dòng)清理,否則會(huì)造成資源浪費(fèi)。
CRD配置方式是非常符合Kubernetes官方推薦的標(biāo)準(zhǔn)擴(kuò)展方式,讓采集配置以K8s資源的方式進(jìn)行管理,通過向Kubernetes部署AliyunLogConfig這個(gè)特殊的CRD資源來聲明需要采集的數(shù)據(jù)。例如下面的示例就是部署一個(gè)容器標(biāo)準(zhǔn)輸出的采集,其中定義需要Stdout和Stderr都采集,并且排除環(huán)境變量中包含COLLEXT_STDOUT_FLAG:false的容器。
基于CRD的配置方式以Kubernetes標(biāo)準(zhǔn)擴(kuò)展資源的方式進(jìn)行管理,支持配置的增刪改查完整語義,而且支持各種高級(jí)配置,是我們極其推薦的采集配置方式。
采集規(guī)則推薦的配置方式
實(shí)際應(yīng)用場(chǎng)景中,一般都是使用DaemonSet或DaemonSet與Sidecar混用方式,DaemonSet的優(yōu)勢(shì)是資源利用率高,但有一個(gè)問題是DaemonSet的所有Logtail都共享全局配置,而單一的Logtail有配置支撐的上限,因此無法支撐應(yīng)用數(shù)比較多的集群。
上述是我們給出的推薦配置方式,核心的思想是:
實(shí)踐1-中小型集群
絕大部分Kubernetes集群都屬于中小型的,對(duì)于中小型沒有明確的定義,一般應(yīng)用數(shù)在500以內(nèi),節(jié)點(diǎn)規(guī)模1000以內(nèi),沒有職能明確的Kubernetes平臺(tái)運(yùn)維。這種場(chǎng)景應(yīng)用數(shù)不會(huì)特別多,DaemonSet可以支撐所有的采集配置:
實(shí)踐2-大型集群
對(duì)于一些用作PAAS平臺(tái)的大型/超大型集群,一般業(yè)務(wù)在1000以上,節(jié)點(diǎn)規(guī)模也在1000以上,有專門的Kubernetes平臺(tái)運(yùn)維人員。這種場(chǎng)景下應(yīng)用數(shù)沒有限制,DaemonSet無法支持,因此必須使用Sidecar方式,整體規(guī)劃如下:
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的系列文章:Kubernetes日志采集最佳实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冠赢网络:游戏盾彻底解决DDoS/CC攻
- 下一篇: 【开发者成长】每个人都在编写草率代码