iLogtail和Loggie:K8S環境下日誌收集利器

ITPUB社群發表於2023-03-09


預計閱讀時間5分鐘

iLogtail和Loggie:K8S環境下日誌收集利器

需求

在傳統的使用虛擬機器/雲主機/物理機的時代,業務程式部署在固定的節點上,業務日誌直接輸出到宿主機上,運維只需要手動或者使用自動化工具把日誌採集Agent部署在節點上,加一下Agent的配置,就可以開始採集日誌了。而在Kubernetes環境中,情況就沒這麼簡單了:

  • 「動態遷移」:在Kubernetes叢集中經常存在Pod主動或者被動的遷移,頻繁的銷燬、建立,我們無法和傳統的方式一樣人為的給每個服務下發日誌採集配置。
  • 「日誌儲存方式多樣性」:容器的日誌儲存方式有很多不同的型別,例如stdout、hostPath、emptyDir、pv等。
  • 「Kubernetes元資訊」:由於日誌資料採集後會被集中儲存,所以查詢日誌時,需要根據namespace、pod、container、node,甚至包括容器的環境變數、label等維度來檢索、過濾,此時要求Agent感知並預設在日誌裡注入這些元資訊。

以上都是有別於傳統日誌採集配置方式的需求和痛點,究其原因,還是因為傳統的方式脫離了Kubernetes,無法感知Kubernetes,無法和Kubernetes整合。

解決方案

針對以上痛點,我們特對Kubernetes環境下的日誌收集方式進行整理總結。

1.iLogtail

iLogtail 為可觀測場景而生,擁有的輕量級、高效能、自動化配置等諸多生產級別特性,在阿里巴巴以及外部數萬家阿里雲客戶內部廣泛應用。你可以將它部署於物理機,虛擬機器,Kubernetes等多種環境中來採集遙測資料,例如logs、traces和metrics。

ilogtail的核心優勢:

  • 支援多種Logs、Traces、Metrics資料採集,尤其對容器、Kubernetes環境支援非常友好
  • 資料採集資源消耗極低,相比同類遙測資料採集的Agent效能好5-20倍
  • 高穩定性,在阿里巴巴以及數萬阿里雲客戶生產中使用驗證,部署量近千萬,每天採集數十PB可觀測資料
  • 支援外掛化擴充套件,可任意擴充資料採集、處理、聚合、傳送模組
  • 支援配置遠端管理,支援以圖形化、SDK、K8s Operator等方式進行配置管理,可輕鬆管理百萬臺機器的資料採集
  • 支援自監控、流量控制、資源控制、主動告警、採集統計等多種高階特性

2.Loggie

Loggie是一個基於Golang的輕量級、高效能、雲原生日誌採集Agent和中轉處理Aggregator,支援多Pipeline和元件熱插拔。

Loggie的優勢與特性:

  • 可擴充套件、熱插拔:配置不同的Source/Interceptor/Sink,獲得中轉、過濾、解析、切分等能力,可快速自研外掛
  • 強隔離:多Pipeline設計,減少互相干擾,支援同時傳送多個不同資料來源
  • 輕量級、高效能:基於Golang,極少的資源佔用,強大的吞吐效能,滿足各類場景需求
  • 可靠性保障:完善的日誌可觀測性,原生Prometheus metrics支援,還有限流、背壓等Interceptor
  • 雲原生:配置中心整合Kubernetes,建立CRD例項即可採集容器或節點日誌
  • 不僅僅是日誌:資料流基於Source/Interceptor/Sink模型,可採集各種可觀測性事件,擴充套件更多的可能性

應用

本次應用以iLogtail為主,以收集nginx和java日誌為示例。

1.快速部署

# 1.建立名稱空間
wget
kubectl apply -f ilogtail-ns.yaml

# 2.configmap 定義配置檔案
wget
kubectl apply -f ilogtail-user-configmap.yaml

# 3.DaemonsSet 部署應用
wget
kubectl apply -f ilogtail-daemonset.yaml

2.收集Nginx日誌

# 1.Deployment部署Nginx
wget
kubectl apply -f nginx-deployment.yaml
# 2.訪問日誌
kubectl exec nginx-<pod-id> -- curl localhost/hello/ilogtail
# 3.檢視測試日誌
# 注意:需要檢視和nginx 在同一個node節點上的ilogtail-ds
kubectl logs ilogtail-ds-<pod-id> -n ilogtail
# json格式化後,日誌檢視
{
 "_time_": "2022-07-15T00:36:48.489153485+08:00",
 "_source_": "stdout",
 "_image_name_": "docker.io/library/nginx:latest",
 "_container_name_": "nginx",
 "_pod_name_": "nginx-76d49876c7-r892w",
 "_namespace_": "default",
 "_pod_uid_": "07f75a79-da69-40ac-ae2b-77a632929cc6",
 "_container_ip_": "10.223.0.154",
 "remote_addr": "::1",
 "remote_user": "-",
 "time_local": "14/Jul/2022:16:36:48",
 "method": "GET",
 "url": "/hello/ilogtail",
 "protocol": "HTTP/1.1",
 "status": "404",
 "body_bytes_sent": "153",
 "http_referer": "-",
 "http_user_agent": "curl/7.74.0",
 "http_x_forwarded_for": "-",
 "__time__": "1657816609"
}

從JSON日誌中我們可以看出,除了Nginx日誌常規的欄位,ilogtail還增加了namespace、pod、container、node等各維度的容器資訊。

「iLogtail 配置檔案解析」

# ilogtail-user-configmap.yaml 配置檔案
nginx_stdout.yaml: |
   enable: true
   inputs:
     - Type: service_docker_stdout
       Stderr: false
       Stdout: true                # only collect stdout
       IncludeK8sLabel:
         app: nginx                # choose containers with this label
   processors:
     - Type: processor_regex       # structure log
       SourceKey: content
       Regex: '([\d\.:]+) - (\S+) \[(\S+) \S+\] \"(\S+) (\S+) ([^\\"]+)\" (\d+) (\d+) \"([^\\"]*)\" \"([^\\"]*)\" \"([^\\"]*)\"'
       Keys:
         - remote_addr
         - remote_user
         - time_local
         - method
         - url
         - protocol
         - status
         - body_bytes_sent
         - http_referer
         - http_user_agent
         - http_x_forwarded_for
   flushers:
     - Type: flusher_stdout
       OnlyStdout: true

ilogtail-user-configmap.yaml 配置檔案中關於nginx日誌收集配置,位於nginx_stdout.yaml處:

  1. 輸入inputs
  • Type,容器標準輸出外掛即service_docker_stdout
  • Stdout、Stderr,是否採集標準輸出錯資訊
  • IncludeK8sLabel,透過Kubernetes Label(定義在template.metadata中)白名單指定待採集的容器
  1. 處理processors
  • Type,processor_regex外掛可以透過正則匹配的模式實現文字日誌的欄位提取
  • SourceKey,原始欄位名
  • Regex,正規表示式,使用()標註待提取的欄位
  • Keys,提取的欄位名,例如["ip", "time", "method"]
  1. 輸出flushers
  • Type,flusher_stdout外掛可以實現將採集到的資料,經過處理後,列印到標準輸出或者自定義檔案
  • OnlyStdout,是否列印列印到標準輸出,true表示標準輸出;false表示檔案;

3.收集Java日誌

透過以上Nginx日誌的收集,我們已經對ilogtail有了大致的瞭解,因此我們進一步探索Java日誌的收集,先來分析下Java日誌收集的需求:

  • Java日誌列印在檔案,而非容器標準輸出
  • Java日誌一般為多行日誌,因此我們需要對日誌按日期分行
  • Java日誌是否有規範,例如按日期、應用名、子執行緒、父執行緒等欄位進行定義,以便後續排查問題

以上都是在真正進行Java日誌收集前需要了解的。下面我們再來確定下ilogtail 對Java多行日誌檔案的收集配置:

log_file.yaml: |
enable: true
inputs:
 - Type: file_log
   LogPath: /data/logs/
   FilePattern: java.log
processors:
 - Type: processor_split_log_regex
   SplitRegex: \d+-\d+-\d+\s\d+:\d+:\d+\s\[.*
   SplitKey: content
   PreserveOthers: true
flushers:
 - Type: flusher_stdout
   OnlyStdout: true

透過實際執行,ilogtail對Java多行日誌檔案的收集並沒有像期望的那樣收整合功。經仔細閱讀官方文件,並對配置檔案進行了如下修改才成功收集,我們來具體分析下:

log_file.yaml: |
enable: true
inputs:
 - Type: file_log
   LogPath: /data/logs/
   FilePattern: "*.log"
   MaxDepth: 5
   ContainerFile: true
   ContainerInfo:
     IncludeK8sLable:
       log: java
processors:
 - Type: processor_split_log_regex
   SplitRegex: \d+-\d+-\d+\s\d+:\d+:\d+\s\[.*
   SplitKey: content
   PreserveOthers: true
flushers:
 - Type: flusher_stdout
   OnlyStdout: true

Java日誌按規範要求:

  • 日誌目錄為/data/logs;
  • 日誌名以 *.log 結尾;
  • 日誌目錄深度不固定,但5層深度肯定是夠的;
  • 日誌欄位格式,以通用為主,可按需定義;

最終的具體定義如下:

  1. 輸入inputs
  • Type,file_log外掛可以實現從文字檔案中採集日誌。採集的日誌內容將會儲存在content欄位中,後續對該欄位進行處理,以實現日誌格式的解析。此外,透過__tag__:__path__欄位也可以檢視日誌的採集路徑。
  • LogPath,採集文字日誌所在的目錄,支援完整目錄和萬用字元兩種模式。
  • FilePattern,採集文字日誌的檔名,支援完整檔名和萬用字元兩種模式。
  • MaxDepth,日誌目錄被監控的最大深度,範圍:0~1000。如果未新增該引數,則預設使用0,代表只監控本層目錄。
  • ContainerFile,iLogtail與待採集日誌是否處於不同環境中。「若待採集的日誌和iLogtail在不同的容器中,請將引數值置為true,其餘情況請置為false。」

注意:正是由於ilogtail和採集的日誌處於不同的名稱空間和容器,導致日誌收集不成功。

  • ContainerInfo,容器相關引數,僅當ContainerFile引數為true時有效。
  • IncludeK8sLable,對於部署於K8s環境的容器,指定待採集容器所在Pod的標籤條件,多個條件之間為“或”的關係,即Pod標籤滿足任一條件即可匹配並被採集。
  • log: java,透過標籤採集特定Key:Value的pod。
  1. 處理processors
  • Type,processor_split_log_regex processor外掛實現多行日誌(例如Java程式日誌)的採集。備註:該外掛必須設定為processor的第一個外掛。
  • SplitKey,切分依據的欄位
  • SplitRegex,行首正則,只有匹配上的才認為是多行日誌塊的行首。預設為.*,表示每行都進行切分。
  • PreserveOthers,是否保留其他非SplitKey欄位。
  1. 輸出flushers
  • Type,flusher_stdout外掛可以實現將採集到的資料,經過處理後,列印到標準輸出或者自定義檔案
  • OnlyStdout,是否列印列印到標準輸出,true表示標準輸出;false表示檔案

總結

至此我們只是帶大家對Kubernete容器環境下的日誌收集進行了初步的介紹,但是在實際使用過程中,我們還需要多關注下以下幾個方面:

  • stdout、hostPath、emptyDir、pv 日誌儲存方式
  • DaemonSet / Sidecar 哪一種方式更適合來部署ilogtail及loggie
  • Pod動態遷移下日誌收集



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2938838/,如需轉載,請註明出處,否則將追究法律責任。

相關文章