日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

文章圖片

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

文章圖片

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

文章圖片

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

文章圖片

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

文章圖片

跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案

文章圖片


阿里妹導(dǎo)讀


iLogtail 作為開(kāi)源可觀(guān)測(cè)數(shù)據(jù)采集器 , 對(duì) Kubernetes 環(huán)境下日志采集有著非常好的支持 , 本文跟隨 iLogtail 的腳步 , 了解容器運(yùn)行時(shí)與 K8s 下日志數(shù)據(jù)采集原理 。
如今 , Kubernetes在業(yè)界幾乎已經(jīng)成為了容器管理的標(biāo)準(zhǔn) 。 在 Kubernetes 架構(gòu)中 , 容器運(yùn)行時(shí)(如Docker、containerd等)充當(dāng)了基礎(chǔ)層的角色 , 負(fù)責(zé)容器的創(chuàng)建、執(zhí)行和管理 。 由于Kubernetes的設(shè)計(jì)是高度模塊化的 , 它支持多種容器運(yùn)行時(shí) , 這給開(kāi)發(fā)者帶來(lái)了靈活性 。 開(kāi)發(fā)者可以根據(jù)不同的需求選擇最合適的運(yùn)行時(shí) , 甚至在同一個(gè)集群內(nèi)使用多種運(yùn)行時(shí) , 這是Kubernetes生態(tài)的一個(gè)顯著優(yōu)勢(shì) 。
iLogtail 作為開(kāi)源可觀(guān)測(cè)數(shù)據(jù)采集器 , 對(duì) Kubernetes 環(huán)境下日志采集有著非常好的支持 , 下面就跟隨 iLogtail 的腳步 , 了解容器運(yùn)行時(shí)與 K8s 下日志數(shù)據(jù)采集原理 。
K8s 與容器運(yùn)行時(shí)簡(jiǎn)介
正如前面所說(shuō) , Kubernetes的設(shè)計(jì)是高度模塊化的 , 那么模塊化的基礎(chǔ)就是統(tǒng)一的接口或者標(biāo)準(zhǔn) 。 容器運(yùn)行時(shí)這個(gè)概念比較廣泛 , 我們平常所聽(tīng)到的 Docker、Containerd、Runc、Kata 等都可以叫做運(yùn)行時(shí) , 但是他們又明顯地處于不同層次上 , 比如 Containerd 會(huì)依賴(lài) Runc 去真正地拉起容器 。 因此在這里做了一些概念劃分 , 在Kubernetes 架構(gòu)下 , 像Containerd 這種跟 CRI 進(jìn)行交互的 , 叫做高級(jí)容器運(yùn)行時(shí);像 RunC 這種跟 OCI 交互的 , 叫做基礎(chǔ)容器運(yùn)行時(shí) 。
接下來(lái)我們先了解一下 CRI 和 OCI 的概念 。


CRI 與高級(jí)容器運(yùn)行時(shí)
CRI(Container Runtime Inteface 容器運(yùn)行時(shí)接口)本質(zhì)上就是 Kubernetes 定義的一組與容器運(yùn)行時(shí)進(jìn)行交互的接口 , 所以只要實(shí)現(xiàn)了這套接口的容器運(yùn)行時(shí)都可以對(duì)接到 Kubernetes 平臺(tái)上來(lái) 。





Kubelet 通過(guò) gRPC 框架與容器運(yùn)行時(shí)或 shim 進(jìn)行通信 , 其中 kubelet 作為客戶(hù)端 , CRI shim(也可能是容器運(yùn)行時(shí)本身)作為服務(wù)器 。 通過(guò) CRI 的接口定義可以看到 , 大概分了兩套接口:
1.針對(duì) container 和 sandbox 的接口;
2.針對(duì)鏡像操作的接口;
比方說(shuō)我們通過(guò) kubectl 命令來(lái)運(yùn)行一個(gè) Pod , 那么 Kubelet 就會(huì)通過(guò) CRI 執(zhí)行以下操作:

  • 首先調(diào)用 RunPodSandbox 接口來(lái)創(chuàng)建一個(gè) Pod 容器 , Pod 容器是用來(lái)持有容器的相關(guān)資源的 , 比如說(shuō)網(wǎng)絡(luò)空間、PID 空間、進(jìn)程空間等資源;
  • 然后調(diào)用 CreatContainer 接口在 Pod 容器的空間創(chuàng)建業(yè)務(wù)容器;
  • 再調(diào)用 StartContainer 接口啟動(dòng)容器 , 相對(duì)應(yīng)的銷(xiāo)毀容器的接口為 StopContainer 與 RemoveContainer 。
DockerDocker的歷史可以追溯到2010年 , 當(dāng)時(shí)由容器技術(shù)的先驅(qū)Solomon Hykes在法國(guó)巴黎的dotCloud公司創(chuàng)立 。 最初 , Docker并不是一個(gè)獨(dú)立的項(xiàng)目 , 而是dotCloud平臺(tái)的一部分 , 旨在提供一種輕量級(jí)的虛擬化解決方案 。 Docker的核心思想是通過(guò)使用Linux內(nèi)核的命名空間和控制組(cgroups)技術(shù) , 來(lái)實(shí)現(xiàn)輕量級(jí)的容器化 , 這使得應(yīng)用程序可以在隔離的環(huán)境中運(yùn)行而不需要整個(gè)操作系統(tǒng)的虛擬化 。 這種方式大大減少了資源開(kāi)銷(xiāo) , 提高了應(yīng)用的部署速度 。
在 Kubernetes 的早期 , 也只支持一個(gè)容器運(yùn)行時(shí) , 那就是 Docker 。 Kubernetes 推出 CRI 這套標(biāo)準(zhǔn)的時(shí)候 , 比如 Docker 本身并沒(méi)有實(shí)現(xiàn) CRI 接口 , 于是就有了 shim(墊片) ,一個(gè) shim 的職責(zé)就是作為適配器將各種容器運(yùn)行時(shí)本身的接口適配到 Kubernetes 的 CRI 接口上 , 其中 dockershim 就是 Kubernetes 對(duì)接 Docker 到 CRI 接口上的一個(gè)墊片實(shí)現(xiàn) 。





當(dāng) Kubelet 想要使用 Docker 運(yùn)行時(shí)創(chuàng)建一個(gè)容器時(shí) , 它需要以下幾個(gè)步驟:
  • Kubelet 通過(guò) CRI 接口(gRPC)調(diào)用 dockershim , 請(qǐng)求創(chuàng)建一個(gè)容器 , CRI(容器運(yùn)行時(shí)接口 , Container Runtime Interface) 。 在這一步中, Kubelet 可以視作一個(gè)簡(jiǎn)單的 CRI Client , 而 dockershim 就是接收請(qǐng)求的 Server 。
  • dockershim 收到請(qǐng)求后 , 它會(huì)轉(zhuǎn)化成 Docker Daemon 的請(qǐng)求 , 發(fā)到 Docker Daemon 上 , 并請(qǐng)求創(chuàng)建一個(gè)容器 。
  • Docker Daemon 在 1.12 版本中將針對(duì)容器的操作移到另一個(gè)守護(hù)進(jìn)程 containerd 中了 。 因此 Docker Daemon 請(qǐng)求 containerd 創(chuàng)建一個(gè)容器 。
  • containerd 收到請(qǐng)求后 , 創(chuàng)建一個(gè) containerd-shim 的進(jìn)程 , 讓 containerd-shim 去操作容器 。 containerd-shim 在這一步需要調(diào)用 Runc 這個(gè)命令行工具 , 來(lái)真正啟動(dòng)容器 。
  • Runc 啟動(dòng)完容器后 , 它會(huì)直接退出 , containerd-shim 則會(huì)成為容器進(jìn)程的父進(jìn)程 , 負(fù)責(zé)收集容器進(jìn)程的狀態(tài) , 上報(bào)給 containerd 。
Containerd從前面 Kubelet 使用 Docker 啟動(dòng)容器的過(guò)程可以看到 , 從Kubelet 到容器啟動(dòng)的過(guò)程中 , 有非常長(zhǎng)的鏈路和非常多的步驟 。 但是最核心的步驟是 Containerd->Containerd-shim->Runc ,
Docker Daemon 和 Docker-shim 仿佛是可以忽略的 。
因此在Kubernetes 提出 CRI 之后 , Containerd 迅速完成了適配 。 在 Containerd v1.0 中 , 對(duì) CRI 的適配通過(guò)一個(gè)單獨(dú)的進(jìn)程CRI-containerd來(lái)完成:





Containerd v1.1 中做的又更漂亮一點(diǎn) , 砍掉 CRI-containerd 進(jìn)程 , 直接把適配邏輯作為插件放進(jìn) containerd 主進(jìn)程中:





CRI-OKubernetes 的主流運(yùn)行時(shí)經(jīng)歷了從 Docker 到 Containerd 的轉(zhuǎn)變 , 流程變得愈加簡(jiǎn)化 。 此外 , 還有一個(gè)比 Containerd 更為純粹且專(zhuān)注的 Kubernetes 運(yùn)行時(shí)解決方案—CRI-O , 它專(zhuān)為 Kubernetes 設(shè)計(jì) , 并且兼容 CRI 和 OCI , 提供了更為簡(jiǎn)單的運(yùn)行時(shí)體驗(yàn) 。










Containerd 是一個(gè)更通用的容器運(yùn)行時(shí) , 旨在提供一個(gè)高效的容器管理系統(tǒng) 。 它支持構(gòu)建、運(yùn)行和存儲(chǔ)容器鏡像 , 適用于各種編排工具 , 如 Kubernetes 和 Docker Swarm 。 Containerd 提供了豐富的 API 和插件機(jī)制 , 使其能夠與多種環(huán)境和體系結(jié)構(gòu)兼容 。
相對(duì)而言 , CRI-O 是專(zhuān)為 Kubernetes 設(shè)計(jì)的輕量級(jí)容器運(yùn)行時(shí) 。 它遵循 Kubernetes 的 CRI(容器運(yùn)行時(shí)接口)標(biāo)準(zhǔn) , 專(zhuān)注于提供與 Kubernetes 生態(tài)系統(tǒng)的無(wú)縫集成 。 CRI-O 旨在簡(jiǎn)化對(duì) Kubernetes 的容器管理 , 去掉了不必要的功能 , 力求在安全性、性能和資源占用上做到極致 , 減少了額外的復(fù)雜性 。


OCI 與基礎(chǔ)容器運(yùn)行時(shí)
開(kāi)放容器標(biāo)準(zhǔn)(Open Container Initiative , OCI)是一個(gè)由多個(gè)技術(shù)公司、開(kāi)發(fā)者和社區(qū)成員組成的行業(yè)合作項(xiàng)目 , 旨在為容器技術(shù)建立開(kāi)放標(biāo)準(zhǔn) 。 OCI 于 2015 年成立 , 目的是為了推動(dòng)容器生態(tài)系統(tǒng)的發(fā)展 , 減少不同容器運(yùn)行時(shí)及映像格式之間的不兼容性 。
OCI 目前包含三個(gè)規(guī)范:
  • 運(yùn)行時(shí)規(guī)范 (runtime-spec):定義了如何運(yùn)行容器 , 包括配置、生命周期和沙箱環(huán)境 。 它提供了一種標(biāo)準(zhǔn)的方法 , 使得容器能夠在任何遵循該標(biāo)準(zhǔn)的運(yùn)行時(shí)中被啟動(dòng) 。 簡(jiǎn)單來(lái)說(shuō) , 它規(guī)定的就是“容器”要能夠執(zhí)行“create”“start”“stop”“delete”這些命令 , 并且行為要規(guī)范 。
  • 鏡像規(guī)范 (image-spec) :規(guī)定了容器映像的格式和內(nèi)容結(jié)構(gòu) , 確保鏡像可以在不同的容器運(yùn)行時(shí)之間順利傳輸和使用 。
  • 分發(fā)規(guī)范 (distribution-spec):是關(guān)于如何在不同的容器注冊(cè)中心之間分發(fā)和獲取容器映像的標(biāo)準(zhǔn) 。
CRI 和 OCI 一起 , 構(gòu)成了 Kubernetes 容器領(lǐng)域的事實(shí)規(guī)范 。 任何實(shí)現(xiàn)了 CRI 的高級(jí)容器運(yùn)行時(shí) , 都可以成為 Kubernetes 的運(yùn)行時(shí) 。 任何實(shí)現(xiàn)了 OCI 的低級(jí)運(yùn)行時(shí) , 也可以成為高級(jí)容器運(yùn)行時(shí)的基礎(chǔ)依賴(lài) 。





RuncRunc的前身實(shí)際上是Docker的libcontainer項(xiàng)目演化而來(lái) 。 Runc實(shí)際上就是libcontainer配上了一個(gè)輕型的客戶(hù)端 。
Runc是一個(gè)輕量級(jí)的容器運(yùn)行時(shí) , 用于根據(jù)OCI(Open Container Initiative)標(biāo)準(zhǔn)運(yùn)行容器 。 它是最基礎(chǔ)的容器運(yùn)行時(shí)解決方案 , 可以在沒(méi)有額外服務(wù)管理的情況下啟動(dòng)和運(yùn)行容器 。 Docker和其他較高級(jí)的容器管理工具在內(nèi)部使用Runc來(lái)實(shí)際啟動(dòng)和運(yùn)行容器 。 Runc的目標(biāo)是提供一個(gè)通用的容器運(yùn)行時(shí) , 側(cè)重于簡(jiǎn)單、可移植和可擴(kuò)展 。
  • 隔離機(jī)制:它直接在宿主機(jī)上運(yùn)行容器進(jìn)程 , 并使用Linux的namespace和cgroups等內(nèi)核特性來(lái)提供隔離和資源限制 。
  • 安全性:雖然 Runc 通過(guò) Linux 的安全特性(如 SELinux、AppArmor、seccomp等)提供基本的安全保障 , 但它仍然共享同一內(nèi)核 , 與其他在同一宿主機(jī)上運(yùn)行的容器相比 , 隔離性并不是最強(qiáng)的 。 對(duì)于需要強(qiáng)隔離的場(chǎng)景 , 可能需要其他解決方案 。
  • 性能:Runc 為容器提供了接近原生Linux性能 , 啟動(dòng)速度快 , 資源開(kāi)銷(xiāo)小 , 適合大規(guī)模部署和微服務(wù)架構(gòu) 。
  • 使用場(chǎng)景:廣泛用于開(kāi)發(fā)、測(cè)試和生產(chǎn)環(huán)境 , 是Docker和許多Kubernetes部署的默認(rèn)容器運(yùn)行時(shí) 。 ?
Runc 作為一種容器運(yùn)行時(shí) , 使用共享內(nèi)核的方式來(lái)管理容器的隔離和資源分配 。 然而 , 這種共享內(nèi)核的架構(gòu)也帶來(lái)了一些安全隱患 , 主要體現(xiàn)在以下幾個(gè)方面:
1.內(nèi)核漏洞:所有容器共享同一內(nèi)核 , 因此如果內(nèi)核出現(xiàn)漏洞 , 攻擊者可以利用這些漏洞從一個(gè)容器突破到宿主機(jī)或其他容器 。 這使得容器之間的隔離不如完全虛擬化的方式安全 。
2.系統(tǒng)調(diào)用濫用:容器內(nèi)的進(jìn)程可以通過(guò)系統(tǒng)調(diào)用與內(nèi)核交互 。 一些系統(tǒng)調(diào)用可能被惡意容器濫用以獲取更高的權(quán)限或訪(fǎng)問(wèn)宿主機(jī)的資源 。
3.特權(quán)容器:如果某個(gè)容器被配置為特權(quán)容器 , 它將擁有更高的權(quán)限 , 可能直接訪(fǎng)問(wèn)宿主機(jī)的硬件或敏感資源 , 從而導(dǎo)致安全風(fēng)險(xiǎn) 。
4.配置錯(cuò)誤:容器的配置不當(dāng)可能導(dǎo)致安全漏洞 , 如未正確配置的網(wǎng)絡(luò)或存儲(chǔ) , 可能使容器之間能夠互相訪(fǎng)問(wèn) , 從而影響隔離性 。 ?
Kata/RunD正如前面所說(shuō)的 ,Runc 在安全方面的各種問(wèn)題 , 因此需要一種更加安全的運(yùn)行時(shí) 。
Kata安全容器和普通容器相比有2個(gè)主要的區(qū)別:
1.容器運(yùn)行在虛擬機(jī)里;
2.鏡像要從宿主機(jī)上傳遞給虛擬機(jī);





  • Shim-v2 會(huì)為 Pod 啟動(dòng)一個(gè)虛擬機(jī)作為 PodSandbox提供隔離性 , 其中運(yùn)行著一個(gè) Linux 內(nèi)核 , 通常這個(gè) Linux 內(nèi)核是一個(gè)裁剪過(guò)的內(nèi)核 , 不會(huì)支持沒(méi)有必要的設(shè)備 。
  • 這里用的虛擬機(jī)可以是 Qemu 或是 Firecracker , 它只是支撐容器應(yīng)用運(yùn)行的基礎(chǔ)設(shè)施沒(méi)有完整操作系統(tǒng) 。
RunD 是阿里提出的新型安全容器 , 簡(jiǎn)言之就是增強(qiáng)版的 Kata , 在資源占用、網(wǎng)絡(luò)、存儲(chǔ)等方面均有優(yōu)化 。 ?
K8s 下容器日志數(shù)據(jù)采集難點(diǎn)
在 Kubernetes(K8s)環(huán)境下 , 容器日志數(shù)據(jù)采集面臨著多重挑戰(zhàn):
1.生命周期短容器的短暫性和高度動(dòng)態(tài)特性使得它們的生命周期極其短暫 , 這意味著許多容器可能在運(yùn)行期間生成重要的日志信息 , 但一旦容器被銷(xiāo)毀 , 這些信息就會(huì)隨之消失 。 日志的瞬時(shí)性給日志采集帶來(lái)了極大的挑戰(zhàn) 。
2.分布式架構(gòu)容器通常部署在多個(gè)節(jié)點(diǎn)上 , 這種分布式架構(gòu)導(dǎo)致日志數(shù)據(jù)存儲(chǔ)在不同的位置 。 數(shù)據(jù)的分散性不僅增加了管理的復(fù)雜性 , 而且可能導(dǎo)致實(shí)時(shí)數(shù)據(jù)采集和分析的困難 。
3.存儲(chǔ)方式多樣容器的存儲(chǔ)方式各異 , 包括卷、掛載等 。 這些存儲(chǔ)方式的多樣性使得日志的寫(xiě)入、讀取和管理變得更加復(fù)雜 。
4.數(shù)據(jù)與容器元信息關(guān)聯(lián)容器日志作為可觀(guān)測(cè)數(shù)據(jù) , 必須與容器的元信息(如容器 ID、名稱(chēng)、標(biāo)簽等)進(jìn)行精準(zhǔn)關(guān)聯(lián) , 以便于后續(xù)的查詢(xún)與分析 , 有效地匹配數(shù)據(jù)與容器信息有助于快速定位問(wèn)題源頭 。 然而 , 由于容器的頻繁創(chuàng)建和銷(xiāo)毀 , 以及其動(dòng)態(tài)變化的特性 , 在數(shù)據(jù)采集時(shí)及時(shí)、準(zhǔn)確地建立這種關(guān)聯(lián) , 依然是一大挑戰(zhàn) 。 ?
開(kāi)源采集器容器日志采集方案


Filebeat
容器標(biāo)準(zhǔn)輸出采集通過(guò)官方文檔[1
可以看到 , Filebeat 推薦是以 daemonset 的方式部署在 K8s 集群中的 , 然后這里需要把節(jié)點(diǎn)宿主機(jī)上的:/var/log 和/var/lib/docker/containers掛載進(jìn)filebeat的pod中 。 這個(gè)采集原理跟前面運(yùn)行時(shí)就有關(guān)系了 。





當(dāng)Docker 作為 K8s 容器運(yùn)行時(shí) , 容器日志的落盤(pán)將由 docker 來(lái)完成 , 保存在:
/var/lib/docker/containers/ 目錄下 。 Kubelet 會(huì)在 /var/log/pods 和 /var/log/containers 下建立軟鏈接 , 指向 /var/lib/docker/containers/ 目錄下的容器日志文件 。
當(dāng)Containerd 作為 k8s 容器運(yùn)行時(shí) ,容器日志的落盤(pán)由 Kubelet 來(lái)完成 , 保存至 /var/log/pods/ 目錄下 , 同時(shí)在 /var/log/containers 目錄下創(chuàng)建軟鏈接 , 指向日志文件 。
所以 , 總結(jié)下來(lái):
1./var/lib/docker/containers/ : Docker 日志落盤(pán)路徑 , 文件路徑格式/var/lib/docker/containers/${container_id/${container_id-json.log
2./var/log/containers/ : 一般都是軟連接 , 文件路徑格式/var/log/containers/${pod_name_${namespace_${container_name-${container_id.log
3./var/log/pods/ :kubelet 日志落盤(pán)路徑 , 文件路徑格式/var/log/pods/${namespace_${pod_name_${pod_uid
/${container name/0.log
所以一般采集標(biāo)準(zhǔn)輸出文件 , 都是采集/var/log/containers 路徑 , 因?yàn)檫@個(gè)路徑下有完整的所有容器的標(biāo)準(zhǔn)輸出文件 。
從官方文檔[1
, 可以看到 ,F(xiàn)ilebeat 支持在 K8s 環(huán)境自動(dòng)發(fā)現(xiàn)容器并采集容器數(shù)據(jù) 。
K8s 配置樣例:
filebeat.autodiscover:providers:- type: kubernetestemplates:- condition:equals:kubernetes.namespace: kube-systemconfig:- type: containerpaths:- /var/log/containers/*-${data.kubernetes.container.id.logexclude_lines: [\"^\\\\s+[\\\\-`('.|_
\"
# drop asciiart lines
從源碼[2
中我們可以看到 , Filebeat 在 Kubernetes 場(chǎng)景下 , 采用了向 API Server 進(jìn)行 List-Watch 的方式來(lái)處理與集群相關(guān)的各種資源 , 例如 Pod、Namespace、Node 等 。 首先 , Filebeat 會(huì)向 API Server 發(fā)送請(qǐng)求以獲取當(dāng)前所有相關(guān)資源的列表 , 并持續(xù)監(jiān)控這些資源的變化 。 當(dāng)有新的資源被創(chuàng)建、更新或刪除時(shí) , API Server 會(huì)通過(guò)事件通知的方式將變更信息推送給 Filebeat 。
在獲取到這些資源后 , Filebeat 會(huì)將它們存儲(chǔ)在本地緩存中 , 以便后續(xù)的訪(fǎng)問(wèn)和處理 。 通過(guò)這種List-Watch 機(jī)制 , Filebeat 能夠?qū)崟r(shí)獲取資源的狀態(tài) , 確保信息的時(shí)效性和準(zhǔn)確性 。 接下來(lái) , Filebeat 會(huì)進(jìn)行條件過(guò)濾 , 數(shù)據(jù)上報(bào)的時(shí)候 , 還可以進(jìn)行數(shù)據(jù)的富化處理 , 比如添加上下文信息、標(biāo)簽或其他的容器元信息數(shù)據(jù) , 從而使得最終的日志更加豐富和有意義 。 ?
容器內(nèi)自定義文件采集配置目前 , 針對(duì)容器內(nèi)自定義文件采集配置 , Filebeat 提供 sidecar 模式的部署 。 比如如下樣例 , Filebeat 作為一個(gè) sidecar container , 跟業(yè)務(wù)容器部署在同一個(gè) Pod 內(nèi) , 同時(shí) , 業(yè)務(wù)容器要采集的日志文件路徑需要通過(guò)數(shù)據(jù)卷掛載的方式共享給 Filebeat , 這樣才能完成容器內(nèi)自定義文件采集 。
apiVersion: apps/v1kind: Deploymentmetadata:name: app-log-logfilespec:replicas: 3selector:matchLabels:project: microserviceapp: nginx-logfiletemplate:metadata:labels:project: microserviceapp: nginx-logfilespec:containers:# 應(yīng)用容器- name: nginximage: lizhenliang/nginx-php# 將數(shù)據(jù)卷掛載到日志目錄volumeMounts:- name: nginx-logsmountPath: /usr/local/nginx/logs# 日志采集器容器- name: filebeatimage: elastic/filebeat:7.10.1args: [\"-c\" \"/etc/filebeat.yml\"\"-e\"
resources:requests:cpu: 100mmemory: 100Milimits:memory: 500MisecurityContext:runAsUser: 0volumeMounts:# 掛載filebeat配置文件- name: filebeat-configmountPath: /etc/filebeat.ymlsubPath: filebeat.yml# 將數(shù)據(jù)卷掛載到日志目錄- name: nginx-logsmountPath: /usr/local/nginx/logs# 數(shù)據(jù)卷共享日志目錄volumes:- name: nginx-logsemptyDir: {- name: filebeat-configconfigMap:name: filebeat-nginx-config
Sidecar 模式雖然能夠采集到容器內(nèi)的日志文件 , 但是它也有一些劣勢(shì):
1.資源占用提升:一個(gè) Pod 就要部署一個(gè)采集器 , CPU、內(nèi)存等資源占用勢(shì)必增加 。
2.無(wú)法跟容器元信息關(guān)聯(lián):Sidecar 模式采集文件就跟主機(jī)上普通文件采集類(lèi)似 , 很難跟容器元信息關(guān)聯(lián)上 。
聰明的社區(qū)用戶(hù)提出了一個(gè)創(chuàng)新性的方案[3
不直接使用 sidecar 模式來(lái)部署 filebeat 。 首先 , 引入一個(gè)輕量級(jí)的 sidecar 容器 , 主容器在運(yùn)行時(shí)將日志文件共享給這個(gè) sidecar 容器 。 接下來(lái) , 在 sidecar 容器中 , 僅需運(yùn)行簡(jiǎn)單的 tail 命令 , 將主容器輸出的日志文件轉(zhuǎn)換成標(biāo)準(zhǔn)輸出的方式 , 然后就可以通過(guò) filebeat 的 damonset 方式進(jìn)行容器標(biāo)準(zhǔn)輸出的采集 。 ?
apiVersion: v1kind: Podmetadata:name: counterspec:containers:- name: countimage: busyboxargs:- /bin/sh- -c- >i=0;while true;doecho \"$i: $(date)\" >> /var/log/1.log;echo \"$(date) INFO $i\" >> /var/log/2.log;i=$((i+1));sleep 1;donevolumeMounts:- name: varlogmountPath: /var/log- name: count-log-1image: busyboxargs: [/bin/sh -c 'tail -n+1 -F /var/log/1.log'
volumeMounts:- name: varlogmountPath: /var/log- name: count-log-2image: busyboxargs: [/bin/sh -c 'tail -n+1 -F /var/log/2.log'
volumeMounts:- name: varlogmountPath: /var/logvolumes:- name: varlogemptyDir: {


Fluent bit
容器標(biāo)準(zhǔn)輸出采集從 Fluent Bit 的官方文檔[4
可以看到 , Fluent Bit 也是推薦使用 Daemonset 的部署模式部署到每一個(gè)節(jié)點(diǎn)上 , 然后 , 可以支持如下信息富化:
  • Pod Name
  • Pod ID
  • Container Name
  • Container ID
  • Labels
  • Annotations
為了獲取此信息 , Fluent Bit 的內(nèi)置過(guò)濾器插件會(huì)與 Kubernetes API Server 通信以檢索相關(guān)信息 , 例如 pod_id、label 和 annotation , 其他字段(例如 pod_name、container_id 和 container_name)從日志文件名本地獲取的(/var/log/containers/目錄下文件路徑格式為:/var/log/containers/${pod_name_${namespace_${container_name-${container_id.log) 。 ?
K8s 日志采集配置樣例[5

input-kubernetes.conf: |[INPUT
NametailTagkube.*Path/var/log/containers/*.logParserdockerDB/var/log/flb_kube.dbMem_Buf_Limit5MBSkip_Long_LinesOnRefresh_Interval10[FILTER
NamekubernetesMatchkube.*Kube_URLhttps://kubernetes.default.svc:443Kube_CA_File/var/run/secrets/kubernetes.io/serviceaccount/ca.crtKube_Token_File/var/run/secrets/kubernetes.io/serviceaccount/tokenKube_Tag_Prefixkube.var.log.containers.Merge_LogOnMerge_Log_Keylog_processedK8S-Logging.ParserOn
在 INPUT 配置段中 , tail 插件將監(jiān)控路徑 /var/log/containers/ 路徑以 .log 結(jié)尾的所有文件 。 對(duì)于每個(gè)文件 , 它將讀取每一行日志記錄并應(yīng)用 docker 解析器 。 然后 , 日志記錄將被附加標(biāo)簽并發(fā)送到下一步 。
從源代碼[6
可以看到 , Fluent bit 容器元信息富化與 Filebeat 不太一樣 , Filebeat 采取的是 List-Watch api server 的方式 , 而 Fluent bit 則是從文件名中解析得到 namespace 和 pod name , 然后向api server 請(qǐng)求單個(gè) pod 的元信息 。
如果想要過(guò)濾掉某個(gè) pod 的日志 , 那么 Fluent bit 還支持使用注解的方式 , 請(qǐng)求將指定日志排除 , 如下樣例就是使用fluentbit.io/exclude 這個(gè)注解 , 將該 pod 的日志排除掉 。
【跟著iLogtail學(xué)習(xí)容器運(yùn)行時(shí)與K8s下日志采集方案】apiVersion: v1kind: Podmetadata:name: apache-logslabels:app: apache-logsannotations:fluentbit.io/exclude: \"true\"spec:containers:- name: apacheimage: edsiper/apache_logs容器內(nèi)自定義文件采集配置對(duì)于容器內(nèi)自定義文件的采集 , Fluent bit 同樣采取的是 sidecar 的部署模式 。 ?


小結(jié)
K8s 場(chǎng)景 , 開(kāi)源采集器一般都支持 Daemonset 和 Sidecar 兩種部署模式:
Daemonset 部署模式:一般都是用來(lái)采集 K8s 場(chǎng)景下容器標(biāo)準(zhǔn)輸出日志 , 容器元信息獲取都是通過(guò)與 K8s 的 api server 交互獲取 , 但是實(shí)現(xiàn)細(xì)節(jié)上有所不同 , Filebeat 采用的是 List-Watch 機(jī)器 , 獲取全量的資源信息 , FluentBit 則是按需獲取對(duì)應(yīng) Pod 信息 。
Sidercar 部署模式:一般都是用來(lái)采集容器內(nèi)自定義日志文件 , 沒(méi)有辦法獲取容器元信息數(shù)據(jù) , 難以富化日志字段 。
iLogtail 容器日志采集方案


Daemonset 模式
部署說(shuō)明iLogtail Daemonset 部署模版可以參考文檔?[7

其中比較關(guān)鍵的配置如下:
volumeMounts:- mountPath: /var/run # for container runtime socketname: run- mountPath: /logtail_host # for log access on the nodemountPropagation: HostToContainername: rootreadOnly: truevolumes:- hostPath:path: /var/runtype: Directoryname: run- hostPath:path: /type: Directoryname: root
  • 一個(gè)是將節(jié)點(diǎn)的/var/run 目錄掛載待 iLogtail-ds 里面 , 主要作用是讓 iLogtail-ds 可以訪(fǎng)問(wèn)到容器運(yùn)行時(shí)的 sock 文件 , 比如
  • Docker:/run/docker.sock 。
  • Containerd:/run/containerd/containerd.sock 。
  • 還有一個(gè)是把節(jié)點(diǎn)根目錄掛載到 iLogtail-ds 里面 , 主要作用就是讓 iLogtail-ds 可以訪(fǎng)問(wèn)節(jié)點(diǎn)上的路徑 , 從而實(shí)現(xiàn)標(biāo)準(zhǔn)輸出日志和容器內(nèi)自定義日志文件的采集 。 ?
iLogtail 在 Daemonset 部署模式下支持以下功能:
1.靈活的采集配置
iLogtail 提供強(qiáng)大的配置選項(xiàng) , 使用戶(hù)能夠根據(jù)不同的 Pod 和 Container 條件進(jìn)行精確的篩選 。 用戶(hù)可以根據(jù)標(biāo)簽、命名空間、環(huán)境變量等多種條件靈活定義目標(biāo)容器 , 從而確保所需日志的高效采集與處理 。
2.容器元信息富化
為了提升日志數(shù)據(jù)的價(jià)值 , iLogtail 支持對(duì)容器的元信息進(jìn)行富化 。 這意味著用戶(hù)可以自動(dòng)獲取并附加如 Pod 名稱(chēng)、命名空間、節(jié)點(diǎn)名稱(chēng)、容器狀態(tài)等關(guān)鍵信息 , 使得后續(xù)的數(shù)據(jù)分析和監(jiān)控變得更加直觀(guān)和高效 。
3.支持標(biāo)準(zhǔn)輸出和容器內(nèi)自定義文件采集
iLogtail 支持采集采集標(biāo)準(zhǔn)輸出日志和容器內(nèi)任意文件日志采集
4.全量掛載模式支持
iLogtail 支持多種掛載模式 , 以適應(yīng)業(yè)務(wù)不同的部署需求 。 無(wú)論是使用 hostPath、emptyDir 還是其他持久化存儲(chǔ)的掛載方式 , 都可以支持 , 確保日志采集的穩(wěn)定性與靈活性 。
5.主機(jī)文件采集能力
除了容器內(nèi)的日志采集 , iLogtail 還支持直接在主機(jī)上進(jìn)行文件的采集 。 這一功能使得用戶(hù)能夠靈活地從主機(jī)文件系統(tǒng)中提取重要的日志數(shù)據(jù) , 滿(mǎn)足不同場(chǎng)景下的日志收集需求 , 并提供全面的日志分析能力 。
容器元信息獲取原理介紹在容器元信息獲取方面 , iLogtail 的設(shè)計(jì)思路與開(kāi)源 API server 請(qǐng)請(qǐng)求的解決方案有所不同 。 它采用了直接與容器運(yùn)行時(shí)進(jìn)行交互的方式 , 以確保高效、可靠地獲取所需的元數(shù)據(jù) 。 目前 , iLogtail 支持多種主流的容器運(yùn)行時(shí) , 具體包括:
使用 Docker Client , 支持 Docker 運(yùn)行時(shí)iLogtail 利用 Docker Client 與 Docker Daemon 進(jìn)行通信 , 直接獲取容器的元信息 。 通過(guò)這種方式 , 可以實(shí)現(xiàn)對(duì)容器的深入監(jiān)控和管理 。 主要使用到的接口包括:
  • ?ContainerList:獲取當(dāng)前運(yùn)行容器的列表 , 這使得 iLogtail 能夠快速了解當(dāng)前節(jié)點(diǎn)上有哪些容器在運(yùn)行 。
  • ?ContainerInspect:提供每個(gè)容器的詳細(xì)信息 , 包括配置、狀態(tài)等關(guān)鍵信息 。
  • ?Events:實(shí)時(shí)監(jiān)聽(tīng)容器變化事件 , 允許動(dòng)態(tài)跟蹤容器的生命周期 , 及時(shí)更新相關(guān)處理邏輯 。
通過(guò) Docker Client 獲取的容器元信息示例中 , 有幾項(xiàng)信息尤為重要:
  • LogPath:這是容器標(biāo)準(zhǔn)輸出日志文件在宿主機(jī)上的存放路徑 , 方便用戶(hù)進(jìn)行日志收集和分析 。
  • GraphDriver.Data:提供容器 rootfs 在節(jié)點(diǎn)宿主機(jī)上的路徑 , 關(guān)鍵于了解容器文件系統(tǒng)的存儲(chǔ)方式 , 有助于進(jìn)行故障診斷和性能優(yōu)化 。
這種直接與運(yùn)行時(shí)交互的機(jī)制 , 不僅增強(qiáng)了數(shù)據(jù)獲取的實(shí)時(shí)性 , 還提高了對(duì)于容器狀態(tài)的管控能力 , 使得 iLogtail 能夠更好地適應(yīng)云原生環(huán)境下的動(dòng)態(tài)和復(fù)雜性 。
[{\"Id\": \"1eb334fb59429d77dbfc9ab50f17d72558099532dd33486efd23e817dc3a1fe8\"\"Created\": \"2024-01-15T06:58:13.23781656Z\"\"Path\": \"nginx\"\"Args\": [
\"State\": {\"Image\": \"sha256:261c66bffbc8e04810eb3c292a1c666ee92a11fb874f4585471d70635afafc90\"\"ResolvConfPath\": \"/var/lib/docker/containers/8b187cf41801560981deaf0b4389516ec532a58508899895bcb88aa683feb898/resolv.conf\"\"HostnamePath\": \"/var/lib/docker/containers/8b187cf41801560981deaf0b4389516ec532a58508899895bcb88aa683feb898/hostname\"\"HostsPath\": \"/var/lib/kubelet/pods/5fca5fc9-55fe-40cd-a2b2-9abe81796486/etc-hosts\"http:// 標(biāo)準(zhǔn)輸出日志文件路徑\"LogPath\": \"/var/lib/docker/containers/1eb334fb59429d77dbfc9ab50f17d72558099532dd33486efd23e817dc3a1fe8/1eb334fb59429d77dbfc9ab50f17d72558099532dd33486efd23e817dc3a1fe8-json.log\"\"Name\": \"/k8s_nginx-1215_nginx-1215-b749b6c4f-q4pzb_default_5fca5fc9-55fe-40cd-a2b2-9abe81796486_0\"\"RestartCount\": 0\"Driver\": \"overlay2\"\"Platform\": \"linux\"\"MountLabel\": \"\"\"ProcessLabel\": \"\"\"AppArmorProfile\": \"\"\"ExecIDs\": null\"HostConfig\": {\"LogConfig\": {// 日志配置\"Type\": \"json-file\"\"Config\": {\"max-file\": \"10\"\"max-size\": \"100m\"\"GraphDriver\": {// rootfs路徑\"Data\": {\"LowerDir\": \"/var/lib/docker/overlay2/1e8847504f60ee1e159aa12f09fe9c92e4f5165ff01991b29fd1a0c36d2aec9e-init/diff:/var/lib/docker/overlay2/b1fc28e304c04200359f045995ad78cdcd418c13ce058255f6c85b4d5bff2000/diff:/var/lib/docker/overlay2/ec56a2a3384cc1c0753295bbb1dcc268db23bc13077622e27f7c7d16663f8c7a/diff:/var/lib/docker/overlay2/f2c8d0f32b19d1725a8fb377230b8c18f3ad3b794b77fbfcf3b259fb8e502fd0/diff:/var/lib/docker/overlay2/2b578df4e8cd6d7ce189ccd413096f5a54218a4f90ca34e3ca16732401301833/diff\"\"MergedDir\": \"/var/lib/docker/overlay2/1e8847504f60ee1e159aa12f09fe9c92e4f5165ff01991b29fd1a0c36d2aec9e/merged\"\"UpperDir\": \"/var/lib/docker/overlay2/1e8847504f60ee1e159aa12f09fe9c92e4f5165ff01991b29fd1a0c36d2aec9e/diff\"\"WorkDir\": \"/var/lib/docker/overlay2/1e8847504f60ee1e159aa12f09fe9c92e4f5165ff01991b29fd1a0c36d2aec9e/work\"http:// rootfs類(lèi)型\"Name\": \"overlay2\"http:// 掛載信息 , 如果Pod有配置卷掛載等 , 這里會(huì)有體現(xiàn)\"Mounts\": [
\"Config\": {\"NetworkSettings\": {
使用 CRI , 支持 Containerd 和 CRI-O 運(yùn)行時(shí)通過(guò) CRI(Container Runtime Interface) , iLogtail 充分支持在 containerd 和 cri-o 運(yùn)行時(shí)環(huán)境下的多種應(yīng)用場(chǎng)景 。 無(wú)論底層使用的是 runc 還是 Kata Containers , iLogtail 都能夠高效地采集和獲取容器的元信息 。 這意味著 , 無(wú)論容器運(yùn)行在何種環(huán)境下 , iLogtail 都能保證準(zhǔn)確、統(tǒng)一的日志數(shù)據(jù)采集 , 幫助用戶(hù)實(shí)時(shí)監(jiān)控和分析日志數(shù)據(jù) 。 如下就是一個(gè) containerd 的運(yùn)行時(shí)通過(guò) CRI 接口拿到的信息:
{\"status\": {\"id\": \"7b46331103c28c3cd0198e22fa85f81e2fef50141e1074f67cfdad942c76ebea\"\"metadata\": {\"attempt\": 0\"name\": \"nginx\"\"state\": \"CONTAINER_RUNNING\"\"createdAt\": \"2024-03-12T14:54:48.225783056+08:00\"\"startedAt\": \"2024-03-12T14:54:48.329066862+08:00\"\"finishedAt\": \"1970-01-01T08:00:00+08:00\"\"exitCode\": 0\"image\": {\"image\": \"docker.io/library/nginx:latest\"\"imageRef\": \"docker.io/library/nginx@sha256:c26ae7472d624ba1fafd296e73cecc4f93f853088e6a9c13c0d52f6ca5865107\"\"reason\": \"\"\"message\": \"\"\"labels\": {\"io.kubernetes.container.name\": \"nginx\"\"io.kubernetes.pod.name\": \"nginx-778b4fd69-p4xf2\"\"io.kubernetes.pod.namespace\": \"default\"\"io.kubernetes.pod.uid\": \"9bd59318-b2ba-4357-8faa-6906d7c827ba\"\"annotations\": {\"com.aliyun.ack.hashVersion\": \"v1.22.3-aliyun.1\"\"io.kubernetes.container.hash\": \"47cfd8d4\"\"io.kubernetes.container.restartCount\": \"0\"\"io.kubernetes.container.terminationMessagePath\": \"/dev/termination-log\"\"io.kubernetes.container.terminationMessagePolicy\": \"File\"\"io.kubernetes.pod.terminationGracePeriod\": \"30\"\"mounts\": [
// 標(biāo)準(zhǔn)輸出日志文件路徑\"logPath\": \"/var/log/pods/default_nginx-778b4fd69-p4xf2_9bd59318-b2ba-4357-8faa-6906d7c827ba/nginx/0.log\"\"info\": {\"sandboxID\": \"34560e346f5245926d1466b59b2f0906aae95b392277f55a52c5895cc3a65f6e\"\"pid\": 500599\"removing\": false\"snapshotKey\": \"7b46331103c28c3cd0198e22fa85f81e2fef50141e1074f67cfdad942c76ebea\"\"snapshotter\": \"overlayfs\"\"runtimeType\": \"io.containerd.runc.v2\"\"runtimeOptions\": {\"systemd_cgroup\": true\"config\": {\"metadata\": {\"name\": \"nginx\"\"image\": {\"image\": \"sha256:e4720093a3c1381245b53a5a51b417963b3c4472d3f47fc301930a4f3b17666a\"\"envs\": [
\"mounts\": [
\"labels\": {\"io.kubernetes.container.name\": \"nginx\"\"io.kubernetes.pod.name\": \"nginx-778b4fd69-p4xf2\"\"io.kubernetes.pod.namespace\": \"default\"\"io.kubernetes.pod.uid\": \"9bd59318-b2ba-4357-8faa-6906d7c827ba\"\"annotations\": {\"io.kubernetes.container.hash\": \"47cfd8d4\"\"io.kubernetes.container.restartCount\": \"0\"\"io.kubernetes.container.terminationMessagePath\": \"/dev/termination-log\"\"io.kubernetes.container.terminationMessagePolicy\": \"File\"\"io.kubernetes.pod.terminationGracePeriod\": \"30\"\"log_path\": \"nginx/0.log\"\"linux\": {// OCI配置\"runtimeSpec\": {
不過(guò) , CRI 所提供的容器元信息中 , 僅包含了容器標(biāo)準(zhǔn)輸出日志文件在節(jié)點(diǎn)宿主機(jī)上的路徑 , 而容器的 Rootfs 路徑卻無(wú)法直接獲取 。 為了解決這一問(wèn)題 , iLogtail 采取了以下兩種有效方案[8

1.文件路徑搜索:通過(guò)對(duì)宿主機(jī)的文件系統(tǒng)進(jìn)行智能搜索 , iLogtail 能夠定位到容器的 Rootfs 路徑 。 這種方法包括遍歷宿主機(jī)上的文件目錄 , 利用容器的唯一標(biāo)識(shí)符(如容器 ID)進(jìn)行關(guān)聯(lián)查找 , 從而實(shí)現(xiàn)對(duì)容器文件系統(tǒng)的檢索和獲取 。 這種動(dòng)態(tài)搜索機(jī)制 , 能夠在一定程度上克服路徑信息缺失帶來(lái)的困擾 , 為后續(xù)的日志收集和監(jiān)控提供支持 。
2.繞過(guò) CRI , 直接與 containerd 進(jìn)行交互:iLogtail 選擇與 containerd 進(jìn)行低層次的直接通訊 , 以獲取更全面和準(zhǔn)確的容器信息 。 通過(guò)這種方式 , iLogtail 能夠繞過(guò) CRI 的限制 , 獲得容器的 Rootfs 路徑和其他重要元數(shù)據(jù) 。 ?


SiderCar 模式





  • 在Sidecar模式中 , 每個(gè)容器組(Pod)運(yùn)行一個(gè)Logtail容器 , 用于采集當(dāng)前容器組(Pod)所有容器(Containers)的日志 。 不同Pod的日志采集相互隔離 。
  • 為了采集同一Pod中其它容器的日志文件 , 需要通過(guò)共享存儲(chǔ)卷的方式來(lái)完成 , 即將同一份存儲(chǔ)卷分別掛載到業(yè)務(wù)容器和Logtail容器 。
apiVersion: batch/v1kind: Jobmetadata:# 在這里添加 Job 元信息 , 比如 name 和 namespacename: ${job_namenamespace: ${namespacespec:template:spec:restartPolicy: Nevercontainers:# 業(yè)務(wù)容器- name: ${main_container_nameimage: ${main_container_imagecommand: [\"/bin/sh\" \"-c\"
args:- until [[ -f /tasksite/cornerstone

; do sleep 1; done;# 替換為業(yè)務(wù)容器的實(shí)際啟動(dòng)命令${container_start_cmd;retcode=$?;touch /tasksite/tombstone;exit $retcodevolumeMounts:# 業(yè)務(wù)容器的日志目錄掛載到共享存儲(chǔ)卷- name: ${shared_volume_namemountPath: ${dir_containing_your_files# 與 Logtail 容器交互的掛載點(diǎn)- mountPath: /tasksitename: tasksite# Logtail sidecar 容器- name: logtailimage: ${logtail_imagecommand: [\"/bin/sh\" \"-c\"
args:- /etc/init.d/ilogtaild start;sleep 10; # 等待 Logtail 配置下載完成touch /tasksite/cornerstone;until [[ -f /tasksite/tombstone

; do sleep 1; done;sleep 10; # 等待 Logtail 完成日志發(fā)送/etc/init.d/ilogtaild stop;livenessProbe:exec:command:- /etc/init.d/ilogtaild- statusinitialDelaySeconds: 30periodSeconds: 30env:# 設(shè)置時(shí)區(qū) 。 請(qǐng)根據(jù)kubernetes集群所在地域 , 配置時(shí)區(qū) , 格式為\"地區(qū)/城市\(zhòng)" 。 如果是中國(guó)大陸 , 可以設(shè)置時(shí)區(qū)為Asia/Shanghai 。# 如果沒(méi)有正確配置時(shí)區(qū) , 可能導(dǎo)致原始日志與處理日志的時(shí)間標(biāo)簽不匹配 , 進(jìn)而將日志數(shù)據(jù)歸檔到錯(cuò)誤的時(shí)間點(diǎn) 。- name: TZvalue: \"${timezone\"- name: ALIYUN_LOGTAIL_USER_IDvalue: \"${your_aliyun_user_id\"- name: ALIYUN_LOGTAIL_USER_DEFINED_IDvalue: \"${your_machine_group_user_defined_id\"- name: ALIYUN_LOGTAIL_CONFIGvalue: \"/etc/ilogtail/conf/${your_region_config/ilogtail_config.json\"# 追加 Pod 環(huán)境信息作為日志標(biāo)簽- name: \"ALIYUN_LOG_ENV_TAGS\"value: \"_pod_name_|_pod_ip_|_namespace_|_node_name_|_node_ip_\"# 獲取 Pod 和 Node 的信息- name: \"_pod_name_\"valueFrom:fieldRef:fieldPath: metadata.name- name: \"_pod_ip_\"valueFrom:fieldRef:fieldPath: status.podIP- name: \"_namespace_\"valueFrom:fieldRef:fieldPath: metadata.namespace- name: \"_node_name_\"valueFrom:fieldRef:fieldPath: spec.nodeName- name: \"_node_ip_\"valueFrom:fieldRef:fieldPath: status.hostIPvolumeMounts:# Logtail 容器的日志目錄掛載到共享存儲(chǔ)卷- name: ${shared_volume_namemountPath: ${dir_containing_your_files# 與業(yè)務(wù)容器交互的掛載點(diǎn)- mountPath: /tasksitename: tasksitevolumes:# 定義空的共享存儲(chǔ)卷用于日志存儲(chǔ)- name: ${shared_volume_nameemptyDir: {# 定義存儲(chǔ)卷用于容器間通信- name: tasksiteemptyDir:medium: Memory
iLogtail 的 SideCar 模式用于日志數(shù)據(jù)采集 , 適用于多種特定場(chǎng)景 , 具體包括:
1.單節(jié)點(diǎn) Pod 數(shù)據(jù)量大:當(dāng)一個(gè)節(jié)點(diǎn)上的 Pod 數(shù)據(jù)量異常龐大 , 遠(yuǎn)超出 Daemonset 的采集性能上限時(shí) , 使用 SideCar 模式是非常推薦的 。 這種模式允許我們?yōu)?iLogtail 分配特定的資源 , 從而提升其日志采集的性能和穩(wěn)定性 , 確保關(guān)鍵 Pod 的日志能夠被及時(shí)高效地收集 , 為后續(xù)的監(jiān)控和分析提供堅(jiān)實(shí)的數(shù)據(jù)基礎(chǔ) 。
2.Serverless 容器日志采集:在 Serverless 容器架構(gòu)中 , 由于缺乏節(jié)點(diǎn)的概念 , 傳統(tǒng)的 Daemonset 部署模式無(wú)法應(yīng)用 。 此時(shí) , SideCar 模式顯得尤為重要 , 它能夠有效地與無(wú)服務(wù)器架構(gòu)結(jié)合 , 保證日志采集過(guò)程的靈活性和適應(yīng)性 。
3.K8s + 安全容器運(yùn)行時(shí)的日志采集:在使用安全容器運(yùn)行時(shí)的 Kubernetes 環(huán)境中 , Daemonset 無(wú)法訪(fǎng)問(wèn)宿主機(jī)的其他容器的標(biāo)準(zhǔn)輸出文件或日志 。 這時(shí) , SideCar 模式便成為唯一可行的解決方案 。 通過(guò)在同一 Pod 內(nèi)集成 iLogtail , 能夠直觀(guān)地獲取和處理容器里的日志 , 確保即使在安全限制下 , 重要的日志數(shù)據(jù)依然能夠被實(shí)時(shí)采集 。


SiderCar 模式 + 容器元信息文件
iLogtail 商業(yè)版與阿里云的容器團(tuán)隊(duì)緊密合作 , 推出了一種優(yōu)化版本的 Sidecar 模式 。 具體而言 , 當(dāng)容器團(tuán)隊(duì)啟動(dòng) iLogtail Sidecar 容器時(shí) , 會(huì)通過(guò)掛載的方式將業(yè)務(wù)容器的相關(guān)信息提供給 iLogtail 。 這一機(jī)制使得 iLogtail 在進(jìn)行日志數(shù)據(jù)上報(bào)時(shí) , 不僅能傳遞基本的日志內(nèi)容 , 還能夠附帶業(yè)務(wù)容器的豐富字段信息 , 如容器名稱(chēng)、標(biāo)簽、環(huán)境變量等 。 這種深度集成的方式極大地增強(qiáng)了日志的上下文信息 , 提高了后續(xù)數(shù)據(jù)分析的效率 , 為用戶(hù)提供了更為全面、直觀(guān)的日志信息 。





目前該模式支持的容器場(chǎng)景有彈性容器 ECI [9
和容器計(jì)算服務(wù) ACS[10



總結(jié)
在 Daemonset 模式下 , 與開(kāi)源的 API server 請(qǐng)求的解決方案有顯著的不同 , iLogtail 選擇了與運(yùn)行時(shí)進(jìn)行直接交互 。 這種與運(yùn)行時(shí)的交互方式帶來(lái)了多個(gè)顯著優(yōu)勢(shì):
1.獲取容器內(nèi)的 rootfs 掛載信息:通過(guò)與運(yùn)行時(shí)的交互 , iLogtail 能夠深入挖掘容器內(nèi)的文件系統(tǒng)信息 , 從而成功采集節(jié)點(diǎn)上 Pod 內(nèi)自定義日志文件 。 這一能力是通過(guò) API server 交互無(wú)法實(shí)現(xiàn)的 。
2.實(shí)時(shí)獲取容器元信息:與運(yùn)行時(shí)的直接交互方式使得 iLogtail 能夠更快速地獲取節(jié)點(diǎn)上正在運(yùn)行的容器的元數(shù)據(jù)信息 , 這種實(shí)時(shí)性對(duì)日志監(jiān)控的實(shí)時(shí)性至關(guān)重要 。
3.減輕 API Server 壓力:Daemonset 通過(guò) API Server 進(jìn)行交互時(shí) , 往往會(huì)對(duì) API server 造成顯著的壓力 , 尤其是在大規(guī)模集群中 。 iLogtail 的設(shè)計(jì)減少了這種依賴(lài) , 從而使 API Server 能夠更專(zhuān)注于處理其他重要的請(qǐng)求 , 提升整體系統(tǒng)的穩(wěn)定性和響應(yīng)能力 。
4.兼容非 K8s 場(chǎng)景:iLogtail 的設(shè)計(jì)不僅限于 Kubernetes 環(huán)境 , 也兼顧到純 Docker 等其他容器運(yùn)行環(huán)境 。 這種靈活性使得 iLogtail 能夠在更廣泛的場(chǎng)景中應(yīng)用 , 不論是在微服務(wù)架構(gòu)下的 Kubernetes 部署 , 還是在傳統(tǒng)的 Docker 容器中 , 都能夠提供強(qiáng)大的日志采集能力 。
在 Sidecar 模式下 , iLogtail 更是與阿里云的 Serverless 容器實(shí)現(xiàn)了深度集成 。 通過(guò)這種集成 , iLogtail 能夠輕松獲取容器的元信息 , 為日志數(shù)據(jù)提供更精準(zhǔn)的字段豐富化 。 這一特性進(jìn)一步增強(qiáng)了日志分析的效果 , 使得用戶(hù)能夠通過(guò)更為詳盡的信息做出快速響應(yīng) 。 ?
參考文章:[1
https://www.elastic.co/guide/en/beats/filebeat/current/running-on-kubernetes.html
[2
https://github.com/elastic/elastic-agent-autodiscover/blob/main/kubernetes/watcher.go
[3
https://github.com/elastic/beats/issues/9776
[4
https://docs.fluentbit.io/manual/installation/kubernetes
[5
https://github.com/fluent/fluent-bit-kubernetes-logging/blob/master/output/kafka/fluent-bit-configmap.yaml
[6
https://github.com/fluent/fluent-bit/blob/master/plugins/filter_kubernetes/kube_meta.c
[7
https://github.com/alibaba/ilogtail/tree/main/example_config/start_with_k8s
[8
https://github.com/alibaba/ilogtail/blob/main/pkg/helper/docker_cri_adapter.go
[9
https://help.aliyun.com/zh/eci/?spm=a2c4g.11174283.0.0.6b1c6b06zzLIjW
[10
https://help.aliyun.com/product/2584271.html?spm=a2c4g.2584271.0.0.3dd7585fXUF3a7
?[11
一文搞懂容器運(yùn)行時(shí) Containerd?:https://www.qikqiak.com/post/containerd-usage/
[12
?OCI Runtime Specification 介紹?:https://yochalyc.com/2024/02/oci-runtime-specification-介紹/
[13
?cri-o 文檔?:https://cri-o.io/
[14
?k3s 文檔?:https://docs.k3s.io/architecture
[15
?micro k8s 文檔?:https://microk8s.io/docs
[16
?K8S Runtime 種類(lèi)多 , 使用復(fù)雜?那是你沒(méi)明白其中的門(mén)道?:https://cloud.tencent.com/developer/article/1426607
[17
?從零開(kāi)始入門(mén) K8s:理解容器運(yùn)行時(shí)接口 CRI?:https://www.infoq.cn/article/eah8zm3vh8mgwot5hokc
[18
?Fluent Bit 文檔?:https://hulining.gitbook.io/fluentbit/pipeline/filters/kubernetes#configuration-parameters

    推薦閱讀