EKS 環境上, AWS CloudWatch [1] 提供了數種方式提供使用者監控 EKS cluster,如 OpenTelemetry、FluentD 或 Fluent Bit 作為 DaemonSet 方式部署收集 logs。實際這些作為 log agent 又是如何收集對應 log。本文將探討 CloudWatch Agent 及 FluentD 是如何收集 logs。
根據 Kubernetes Logging Architecture [2] 文件,大致上分為兩類 node-level 及 cluster-level:
node-level 透過 logrotate 命令或是 kubelet containerLogMaxSize 及 containerLogMaxFiles 參數 [3] rotate log。
cluster-level 使用以下三種方式實現:
於每一個節點上接部署 Logging Agent 收集 application log 並上傳回 logging 系統。例如:Flutend 或是 Grafana Loki 都是比較接近這種方式,於每一個節點透過 DaemonSet 部署方式,等同有一支 agent process 收集每個節點上的 log 。執得注意的是,倘若 logging system 也是依賴於 Kubernetes 環境,而 Kubernetes 無法正常運作時,logging system 也可能癱瘓,需要注意環境相依性及單點故障。
那到底這些 Logging system 本質上是怎麼於節點上採集 application log 呢?
以下以 EKS 官方 CloudWatch Agent for Container Insights Kubernetes Monitoring[1] 解決方案為例,提供了 Flutend 及 Fluent Bit 兩種 Logging system。
有趣的是,這兩種不同的 Logging system 卻同時收集了相同 /var/log/containers/*.log
目錄作為 application log,預設 config 分別如下方所示:
預設 Flutend containers.conf 收集 /var/log/containers/*.log
containers.conf: |
<source>
@type tail
@id in_tail_container_logs
@label @containers
path /var/log/containers/*.log
exclude_path ["/var/log/containers/cloudwatch-agent*", "/var/log/containers/fluentd*"]
pos_file /var/log/fluentd-containers.log.pos
tag *
read_from_head true
<parse>
@type json
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
...
...
預設 Fluent Bit application-log.conf 收集 /var/log/containers/*.log
application-log.conf: |
[INPUT]
Name tail
Tag application.*
Exclude_Path /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy*
Path /var/log/containers/*.log
Docker_Mode On
Docker_Mode_Flush 5
Docker_Mode_Parser container_firstline
Parser docker
DB /var/fluent-bit/state/flb_container.db
Mem_Buf_Limit 50MB
Skip_Long_Lines On
Refresh_Interval 10
Rotate_Wait 30
storage.type filesystem
Read_from_Head ${READ_FROM_HEAD}
...
/var/log/containers
目錄難道 Kubernetes cluster 本就會將 container log 輸出至 /var/log/containers
目錄嗎?
根據 Kubernetes Proposals [4],明確定義 Pod 是基於 cluster-level 收集 log 目的導向,都會 kubelet 透過 soft link 方式關聯 Container Runtime(如 Docker)至 /var/log/containers
目錄,並且依照 /var/log/containers/<pod_name>_<pod_namespace>_<container_name>-<container_id>.log
格式作為 log 名稱。
附註:Kubernetes Proposals 從 2021 4 月 起已經將相關 Proposal 遷移至 kubernetes / enhancements GitHub。
故現況我們多半關注到的所有 Kubernetes - Using a node logging agent 架構,皆是收集 /var/log/contianers
目錄作為一個 Kubernetes 收集 container application log 的共用規範,而 Fluentd/Fluent Bit 第三方 log 收集工具也是依循此規範。