容器日志采集利器Log-Pilot
容器時代越來越多的傳統應用將會逐漸容器化,而日志又是應用的一個關鍵環節,那么在應用容器化過程中,如何方便快捷高效地來自動發現和采集應用的日志,如何與日志存儲系統協同來高效存儲和搜索應用日志。本文將主要跟大家分享下如何通過Log-Pilot來采集容器的標準輸出日志和容器內文件日志。
日志采集難點
首先我們先看一下容器日志采集的一些難點,這里主要從兩個方面來講,第一個是容器本身的特性,第二個是現有采集工具的一些缺陷:
容器本身特性
- 采集目標多
容器一般推薦將日志寫在標準輸出,但是也有一些特殊的場景就是應用直接將日志寫在容器內部。對于容器的標準輸出日志來說,Docker Engine 本身就提供了一個很好的日志采集能力,但是對于容器內部的文件日志采集,現在并沒有一個很好的工具能夠去動態發現采集。 - 容器的彈性伸縮性
我們知道 Kubernetes 本身是一個分布式集群,那么我們事先就無法像傳統虛擬機環境下那樣,事先配置好日志的采集路徑等一些信息,因此這對于容器的日志采集來說也將面臨一個很大的挑戰。
現有采集工具缺陷
- 缺乏動態配置的能力
目前的采集工具都需要我們事先手動配置好日志采集方式和路徑等信息,由于它無法能夠自動感知到容器的生命周期變化或者動態漂移,所以它無法動態地去配置。 - 日志采集重復或丟失
現有的一些采集工具基本上是通過 tail 的方式來進行日志采集的,那么這里就可能存在兩個方面的問題:一個是可能導致日志丟失,比如采集工具在重啟的過程中,而應用依然在寫日志,那么就有可能導致這個窗口期的日志丟失;而對于這種情況一般保守的做法就是,默認往前多采集 1M 日志或 2M 的日志,那么這就又會可能引起日志采集重復的問題。 - 未明確標記日志源
一個應用可能有很多個容器,輸出的應用日志也是一樣的,那么當我們將所有應用日志收集到統一日志存儲后端時,在搜索日志的時候,我們就無法明確這條日志具體是哪一個節點上的哪一個應用容器產生的。
破解利器 Log-Pilot
針對這些問題,我們提供了一個智能容器采集工具 Log-Pilot,它不僅能夠高效便捷地將容器日志采集輸出到多種存儲日志后端,同時還能夠動態地發現和采集容器內部的日志文件。
Log-Pilot 本身分為三部分,其中一部分就是容器事件管理,它能夠動態地監聽容器的事件變化,然后依據容器的標簽來進行解析,生成日志采集配置文件,然后交由采集插件來進行日志采集。
下面看一下,針對前面容器日志采集的難點,Log-Pilot 是如何去解決的:
聲明式日志配置
Log-Pilot 支持聲明式日志配置,可以依據容器的 Label 或者 ENV 來動態地生成日志采集配置文件。這里重點說明兩個變量:
自動發現機制
Log-Pilot 能夠自動感知宿主機上容器的創建刪除事件,進而動態配置容器日志采集配置文件。
一般情況下我們是通過全量掃描加事件監聽的方式,比如采集工具進程在起來的時候,會先去全量掃描一遍宿主機上的所有容器列表,然后依據容器的聲明式配置來進行日志采集配置文件的動態生成,然后再注冊事件監聽,那么這樣可能會導致一個問題,在全量掃描配置的過程中并且在注冊事件監聽之前,這個窗口期的容器事件就有可能會丟失,因此這里我們采用的是先注冊事件監聽,然后再全量掃描,這樣就可以很好地規避容器事件丟失的問題。
句柄保持機制
自動 CheckPoint
Log-Pilot 內部會實時跟蹤日志采集偏移量,然后維持日志文件信息與偏移量的映射關系,最后定期地持久化到磁盤中。采用偏移量的方式我們可以避免日志采集丟失和重復的問題,同時即使當采集工具宕掉再起來,它可以通過加載持久化在磁盤上的元數據信息,然后從指定的日志偏移位置上繼續采集日志。
句柄保持機制
Log-Pilot 在監測到配置的日志路徑目錄下有新的日志文件產生時會主動地打開其句柄,并維持打開狀態,這樣是為了防止因日志采集工具比較慢或者應用日志輸出速率特別大,比如說當前已經生成五個日志文件但只采集到第三個,后面兩個還沒有開始采集,一旦這個容器退出就可能導致后面兩個文件的日志丟失了。
因此 Log-Pilot 在監測到有新的日志產生的時候,會立即將其文件句柄打開,這樣的話即使這個日志文件刪除,它在磁盤中的數據并沒有被擦除,只有當該日志文件采集完成后,我們才會主動去釋放這個文件句柄,這樣就可以保證日志文件里面的日志不會丟失。
自動數據打標
Log-Pilot 在采集容器日志的時候,同時也會收集容器的元數據信息,包括容器的名稱,容器所屬的服務名稱以及容器所屬的應用名稱,同時在 Kubernetes 里面也會采集容器所屬的 Pod 信息,包括 Pod 的名稱,Pod 所屬的 namespace 以及 Pod 所在的節點信息。這樣我們排查問題時,就可以很方便地知道這個日志數據是來源于哪個節點上的哪個應用容器。
支持高級特性
Log-Pilot 除了提供前面的幾個特性外,還支持一些其他的高級特性,比如低資源消耗,支持自定義 tag,支持多種日志解析格式,支持自定義日志輸出 target 以及支持 fluentd 和 filebeat 等插件,最后支持對接到多種日志存儲后端。
低資源消耗
針對低資源消耗,我們先簡單看一下容器日志采集一般采用的兩種部署模式:
- SideCar 模式
這種需要我們在每個 Pod 中都附帶一個 logging 容器來進行本 Pod 內部容器的日志采集,一般采用共享卷的方式,但是對于這一種模式來說,很明顯的一個問題就是占用的資源比較多,尤其是在集群規模比較大的情況下,或者說單個節點上容器特別多的情況下,它會占用過多的系統資源,同時也對日志存儲后端占用過多的連接數。當我們的集群規模越大,這種部署模式引發的潛在問題就越大。
- Node 模式
這種模式是我們在每個 Node 節點上僅需布署一個 logging 容器來進行本 Node 所有容器的日志采集。這樣跟前面的模式相比最明顯的優勢就是占用資源比較少,同樣在集群規模比較大的情況下表現出的優勢越明顯。
但對于這種模式來說我們就需要一個更加智能的日志采集工具來配合,那么這里用 Log-Pilot 工具就是一個很好的選擇,因此我們在布署 Log-Pilot 采集工具的時候采用的就是 Node 模式。
支持自定義Tag
Log-Pilot 也支持自定義Tag,我們可以在容器的標簽或者環境變量里配置 aliyun.logs.$name.tags: k=v,那么在采集日志的時候也會將k=v采集到容器的日志輸出中。
比如我們有一種場景,有一個開發環境和測試環境,應用日志都會被采集到統一的一個日志存儲后端,假設是一個 ElasticSearch 集群,但是我們在 ElasticSearch 中查詢日志的時候又想區分出來,具體某條日志記錄到底來源于生產環境,還是測試環境。
那么我們就可以通過給測試環境的容器打上 stage=dev 的 tag,給生產環境的容器打上 stage=pro 的 tag,Log-Pilot 在采集容器日志的時候,同時會將這些 tag 隨容器日志一同采集到日志存儲后端中,那么當我們在查詢日志的時候,就可以通過 stage=dev 或者 stage=pro 能明確地區分出某條日志是來源于生產環境的應用容器所產生,還是測試環境應用容器所產生的。另外通過自定義 tag 的方式我們還可以進行日志統計、日志路由和日志過濾。
支持多種日志解析格式
Log-Pilot 也支持多種日志解析格式,通過 aliyun.logs.$name.format: <format>標簽就可以告訴 Log-Pilot 在采集日志的時候,同時以什么樣的格式來解析日志記錄。目前主要支持六種:
支持自定義輸出Target
這里假設一種場景,我們同時有一個生產環境和一個測試環境,應用日志都需要被采集到同一套 Kafka 中,然后由不同的 consumer 去消費。
但是我們同樣希望區分出來,某條日志數據是由生產環境的應用容器產生的,還是測試環境的應用容器產生的,但我們在測試環境中的應用容器已經配置了 aliyun.logs.svc=stdout 標簽,那么當這些應用容器的標準輸出日志被采集到 kafka 中,它最終會被路由到 topic=svc 的消息隊列中,那么訂閱了 topic=svc 的 consumer 就能夠接收測試環境的應用容器產生的日志。
但當我們將該應用發布到生產環境時,希望它產生的日志只能交由生產環境的 consumer 來接收處理,那么我們就可以通過 target 的方式,給生產環境的應用容器額外定義一個 target=pro-svc,那么生產環境的應用日志在被采集到 Kafka 中時,最終會被路由到 topic 為 pro-svc 的消息隊列中,那么訂閱了 topic =pro-svc 的 consumer 就可以正常地接收到來自于生產環境的容器產生的日志。
因此這里的 target 本身也有三種含義:
- 當我們將日志對接到ElasticeSearch時,這個 target 字符串是 Index;
- 當我們對接到Kafka時,它指代的是 topic;
- 當我們將日志對接到日志服務時,它代表的是 Logstore Name。
支持多采集插件
目前 Log-Pilot 支持兩種采集插件:一個是CNCF社區的Fluentd插件,一個是Elastic的Filebeat插件;其同時其支持對接多種存儲后端,目前 Fluentd 和 Filebeat 都支持 Elasticsearch、Kafka、File、Console 作為日志存儲后端,而 Fluentd 還支持 Graylog、阿里云日志服務 以及 Mongodb 作為存儲后端。
社區支持
Log-Pilot在2017年初已在GitHub開源:https://github.com/AliyunContainerService/log-pilot,本著開源開放的原則,歡迎大家使用和貢獻支持,共同將Log-Pilot打造成更加智能更加高效的容器日志采集利器。
總結
以上是生活随笔為你收集整理的容器日志采集利器Log-Pilot的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RESTClient 用法
- 下一篇: Java Socket实战之三:传输对象