在本指南中,我們推薦了集群級別日志記錄和應用日志記錄的最佳實踐。
- Rancher v2.5 中日志記錄的變化
- 集群級別日志
- 應用程序日志
- 通用最佳實踐
Rancher v2.5 中日志記錄的變化
在 Rancher v2.5 之前,Rancher 中的日志記錄是一個靜態集成。有一個固定的聚合器列表可供選擇(ElasticSearch、Splunk、Kafka、Fluentd 和 Syslog),而且只有兩個配置點可供選擇(集群級別和項目級別)。
2.5 中的日志記錄已經被重構,為日志集成提供了更靈活的體驗。通過新的日志記錄功能,管理員和用戶都可以部署符合細粒度收集標准的日志記錄,同時提供更多的目標和配置選項。
Rancher 日志使用的是 Banzai Cloud logging operator。我們提供了這個 operator(及其資源)的可管理性,並將這種經驗與管理你的 Rancher 集群聯系起來。
集群級別日志
抓取集群范圍內日志
對於一些用戶來說,最好是從集群中運行的每個容器中抓取日志。這通常與你的安全團隊從所有容器收集所有日志的請求(或要求)相吻合。
在這種情況下,建議至少創建兩個 ClusterOutput 對象,一個用於你的安全團隊(如果有此要求),另一個用於你自己(集群管理員)。在創建這些對象時要注意選擇一個能夠處理來自整個集群的大量日志流量的輸出端點。同時要確保選擇一個合適的索引來接收所有這些日志。
一旦創建了這些 ClusterOutput 對象,請創建一個 ClusterFlow 來收集所有的日志。不要在這個 flow 上定義任何 Include 或 Exclude 規則。這將確保整個集群的所有日志都被收集。如果您有兩個 ClusterOutputs ,請確保兩個 ClusterOutputs 都能收到日志。
Kubernetes 組件
ClusterFlows 可以收集 Kubernetes 集群中所有主機上所有容器的日志。在這些容器是 Kubernetes pod 的一部分的情況下,這很好用;但是,RKE 容器存在於 Kubernetes 的范圍之外。
目前(從 v2.5.1 開始),Rancher 會搜集 RKE 容器的日志,但不能輕易過濾。這是因為這些日志不包含源容器的信息(如etcd或kube-apiserver)。
Rancher 的未來版本將包含源容器名稱,這將使這些組件日志的過濾成為可能。進行更改后,您將能夠自定義 ClusterFlow 以僅檢索 Kubernetes 組件日志,並將它們引導到一個適當的輸出。
應用程序日志
不僅在 Kubernetes 中,而且在所有基於容器的應用程序中的最佳做法是將應用程序日志引導到stdout/stderr。然后,容器運行時將捕獲這些日志,並對它們進行處理--通常將它們寫入一個文件。根據容器運行時(及其配置)的不同,這些日志可以放置在任意位置。
在將日志寫入文件的情況下,Kubernetes 通過在每個主機上創建一個/var/log/containers目錄來提供幫助。這個目錄將日志文件 symlinks 到它們的實際目的地(可以根據配置或容器運行時而有所不同)。
Rancher 日志記錄將讀取/var/log/containers中的所有日志條目,確保來自所有容器的所有日志條目(假設默認配置)將有機會被收集和處理。
特定日志文件
日志收集只能從 Kubernetes 中的 pod 中檢索stdout/stderr日志。但是,如果我們想從應用程序生成的其他文件中收集日志呢?這里,一個(或兩個)日志流 sidecar 可能會派上用場。
設置日志流 sidecar 的目的是獲取寫入磁盤的日志文件,並將其內容傳輸到stdout。這樣一來,Banzai Logging Operator 就可以接收這些日志,並把它們發送到你想要的輸出。
要設置這一點,請編輯您的工作負載資源(如 Deployment)並添加以下 sidecar 定義:
containers:
- args:
- -F
- /path/to/your/log/file.log
command:
- tail
image: busybox
name: stream-log-file-[name]
volumeMounts:
- mountPath: /path/to/your/log
name: mounted-log
這將為你的工作負載添加一個容器,現在將把/path/to/your/log/file.log的內容(在本例中)傳輸到stdout。
然后根據您設置的任何 Flows 或 ClusterFlows 自動收集該日志流。您還可以考慮通過針對容器的名稱,專門為該日志文件創建一個 Flow。請參見示例:
spec:
match:
- select:
container_names:
- stream-log-file-name
通用最佳實踐
- 在可能的情況下,輸出結構化的日志條目(例如syslog,JSON)。這使得日志條目的處理更容易,因為已經有了為這些格式編寫的解析器。
- 盡量提供創建日志條目的應用程序的名稱。這可以使故障排除更容易,因為 Kubernetes 對象並不總是將應用程序的名稱作為對象名稱。例如,一個 pod ID 可能是像myapp-098kjhsdf098sdf98這樣的東西,它並沒有提供太多關於容器內運行的應用程序的信息。
- 除了在整個集群范圍內收集所有日志的情況下,盡量將您的 Flow 和 ClusterFlow 對象嚴格限定范圍。這使得在出現問題時更容易進行故障排除,也有助於確保不相關的日志條目不會出現在您的聚合器中。嚴格限定范圍的一個例子是將 Flow 限制在一個命名空間中的單個 Deployment ,甚至可能是一個 Pod 中的單個容器。
- 除非故障排查,否則不要讓日志太長。冗長的日志會帶來許多問題,其中最主要的是干擾:重要事件可能會被淹沒在海量的 DEBUG 消息中。這種情況在一定程度上可以通過自動告警和腳本得到緩解,但高度啰嗦的日志記錄仍然會給日志記錄基礎設施帶來過大的壓力。
- 在可能的情況下,盡量在日志條目中提供一個事務或請求 ID。這可以使跨多個日志源追蹤應用程序活動變得更容易,特別是在處理分布式應用程序時。