讓我們看一下 Docker 和 Kubernetes 中的日誌記錄基礎知識,然後看一下可以在生產中安全使用的兩個工具:Grafana Loki 和 EFK 堆棧(Elasticsearch + Fluent Bit + Kibana)。
文章的材料是擠壓自 。 如果有願望,更何況有生產需要,您可以接受全面的培訓 - 報名參加以下課程: .

Docker 日誌記錄
在 Kubernetes 層面,應用程序運行在 Pod 中,但在較低層面,它們仍然在 Docker 中正常運行。 因此,您需要配置日誌記錄以從容器中收集日誌。 容器是由 Docker 啟動的,這意味著您需要弄清楚在 Docker 級別如何安排日誌記錄。
我希望每個讀者都知道:應用程序日誌應該寫入 stdout / stderr,而不是寫入容器內。 日誌由 Docker Daemon 聚合,並且它與發送到 stdout/stderr 的日誌完全兼容。 此外,在容器內寫入日誌充滿了問題:容器會因不斷增長的日誌而膨脹(因為容器中很可能沒有 Logrotate),而 Docker Daemon 不知道該日誌。
Docker 有多個日誌驅動程序或插件用於收集容器日誌記錄。 免費的 Docker 社區版 (CE) 的日誌驅動程序比商業 Docker 企業版 (EE) 少。

我從未在實踐中使用過 Docker EE:在南橋,我們嘗試堅持開源解決方案,客戶不需要 Docker EE 的大部分附加功能。
Docker CE 中的日誌驅動程序:
當地 - 將日誌寫入內部 Docker Daemon 文件;
json 文件 - 在每個容器的文件夾中創建json-log;
日記 - 將日誌發送到日誌。
Docker 日誌記錄設置位於 daemon.json 文件中。
“log-driver”字段指定插件,“log-opts”字段指定其設置。 上例中指定了“json-file”插件,日誌大小限制為“max-size”:“10m”; 文件數量限制(旋轉設置)——“max-file”:“3”; 以及將附加到日誌的值。

一些日誌驅動程序設置可以通過命令行實用程序進行設置。 如果需要使用不同的日誌驅動程序運行單獨的容器,這非常有用。
Docker 中的日誌記錄方案如下所示:

該方案如何工作:像 json-file 這樣的日誌驅動程序創建文件。 日誌收集器(Rsyslog、Fluentd、Logagent 等)收集這些文件並將其傳輸到 Elastic、Sematext 或其他存儲中。
Kubernetes 日誌功能
簡單來說,Kubernetes 中的日誌記錄方案如下所示:有一個 pod,其中運行一個容器,容器將日誌發送到 stdout / stderr。 然後,Docker 創建一個文件並寫入日誌,然後可以輪換日誌。

考慮 Kubernetes 中的日誌記錄功能。
在部署之間保存日誌。 這是正確日誌記錄設置的先決條件。 如果在部署之間不保存日誌,那麼當應用程序發布新版本時,前一個版本的日誌將被覆蓋,重新加載容器也會導致日誌丟失。 Kubernetes 有 --previous 鍵,它允許您查看上次 Pod 重新啟動之前的應用程序日誌,但不能更深入。
聚合所有實例的日誌。 如果微服務託管在雲中,則云提供商負責系統控制。 如果微服務位於自己的硬件上,那麼除了容器中的日誌之外,還需要收集系統日誌。
之前,沒有便捷的工具可以同時收集系統日誌和微服務日誌。通常情況下,一個工具會收集系統日誌(例如 Rsyslog),另一個工具會收集 Docker 日誌(例如 journal-bit,並配置 Docker 日誌驅動程式為 journald)。我們嘗試使用 journal-bit 同時收集容器日誌(透過在 Docker 日誌驅動程式中指定日誌寫入 journald)和系統日誌(在 CentOS 系統版本 7 已經自備 systemd 和 journald。這個方案可行,但並不理想。如果日誌量很大,journal-bit 就會出現延遲,導致訊息遺失。
實驗繼續進行,並找到了另一種方法。 CentOS 7 個主要係統日誌(訊息、稽核、安全)以檔案的形式複製到 var log 中。 Docker 也可以設定為將日誌儲存到 JSON 檔案。相應地,這些文件是 CentOS 7 和 Docker 可以一起建置。
隨著時間的推移,ELK Stack 解決方案開始流行。 它是幾個工具的組合:Elasticsearch、Logstash 和 Kibana。
Elasticsearch 存儲來自容器的日誌,Logstash 從實例收集日誌,Kibana 允許您處理接收到的日誌並基於它們構建圖表。 ELK Stack 已經被積極使用了一段時間,但在我看來,它的時代已經過去了。 稍後我會告訴你原因。
添加元數據。 Pod、應用程序、容器可以在任何地方運行。 此外,一個應用程序可以有多個實例。 日誌以相同的格式寫入,我們需要了解它是什麼類型的副本,它是由什麼 Pod 寫入的,它位於什麼命名空間中。 這就是日誌需要添加元數據的原因。
解析日誌。 這很有趣,但是維護日誌記錄和監控系統的成本可能超過主應用程序的成本。 當每秒有數以萬計的原木飛行時,這似乎很自然,但您仍然需要了解界限。 找到這條邊的一種方法是解析日誌。
通常,您不需要收集和存儲所有日誌,只需發送一部分進行存儲 - 例如狀態為“警告”或“錯誤”的日誌。 如果我們談論的是nginx 或入口控制器日誌,那麼只有那些狀態不同於200 的日誌可以被發送以進行存儲。但這不是通用建議:如果您以某種方式基於Nginx 日誌構建分析,那麼它們顯然值得收集。
不建議隨意過濾日誌,因為過濾後的數據可能不足以進行正常分析。 另一方面,也許分析不應該在日誌記錄級別進行,而應該在收集指標的級別進行。 那麼您就不必存儲數十萬行代碼 200。一種方法是從入口控制器的指標中獲取有關流量和錯誤的信息。
一般來說,這裡你需要仔細考慮:你想要存儲什麼以及存儲多長時間,因為否則會出現日誌系統比主項目佔用更多資源的情況。
目前還沒有標準的日誌記錄解決方案。 與監控不同,監控有一種最常見的 Prometheus 解決方案,而日誌記錄沒有標準。
在本次講座中,我們將介紹兩種工具:一是流行的工具,二是正在流行的工具。 除了它們之外,還有其他的,但在本文中我們不會觸及它們。
考慮到上面討論的所有功能,Kubernetes 中的日誌記錄現在可以用以下方式表示:

容器日誌保持不變,輪換,但會出現一個收集器代理,它拾取日誌並將其發送以進行存儲(在圖中 - 在日誌記錄後端中)。 代理運行在每個節點上,通常運行在 Kubernetes 上。
現在考慮日誌記錄工具。
格拉法娜·洛基
最近才出現,但已經相當有名了。 其優點是:安裝方便,資源消耗少,不需要安裝Elasticsearch,數據存儲在TSDB(時序數據庫)中。 在上一篇文章中,我寫道 Prometheus 將數據存儲在這樣的數據庫中,這是這兩個產品之間的眾多相似之處之一。 開發者甚至聲稱洛基是“伐木界的普羅米修斯”。
給那些沒有讀過的人一個關於 TSDB 的小題外話 :TSDB 在存儲大量數據、時間序列方面做得很好,但不是為長期存儲而設計的。 如果由於某種原因您需要存儲日誌超過兩週,那麼最好將其配置為傳輸到另一個數據庫。
Loki的另一個優點是Grafana用於數據可視化。 這非常方便:在 Grafana 中我們查看監控數據,在同一個地方,通過連接 Loki,我們查看日誌。 日誌可用於構建圖表。
Loki 架構看起來像這樣:

使用 DaemonSet,代理部署在所有集群服務器上 - Promtail 或 Fluent Bit。 代理收集日誌。 Loki 拾取它們並將它們存儲在他的 TSDB 中。 元數據會立即添加到日誌中,這很方便:您可以按 Pod、命名空間、容器名稱甚至標籤進行過濾。
Loki 在熟悉的 Grafana 界面中運行。 Loki 甚至有自己的查詢語言,稱為 LogQL,其名稱和語法與 Prometheus 中的 PromQL 類似。 Loki界面有查詢提示,因此無需背誦它們。

Grafana 界面中的 Loki
使用過濾器,Loki 可以找到代碼(“400”、“404”和任何其他代碼); 查看整個節點的日誌; 過濾掉所有包含“錯誤”一詞的日誌。 如果您單擊日誌,將會打開一張包含該事件所有信息的卡片。
Loki 中有足夠的工具可以讓你提取必要的日誌,儘管說實話,從技術上講可能還有更多。 現在Loki正在積極發展並獲得知名度。
Elastic + Fluent Bit + Kibana(EFK 堆棧)
EFK 堆棧是一種更經典但同樣流行的日誌記錄工具。
文章開頭提到了 ELK(Elasticsearch + Logstash + Kibana),但由於 Logstash 生產力不高且資源密集,因此該堆棧已經過時。 相反,他們開始使用更輕量級、更高效的 Fluentd,過了一段時間他就來救援了 - 更輕量級、更高效的代理收集器。
據開發人員稱,Fluent Bit 的性能比 Fluentd 好 100 倍以上:“Fluentd 消耗 20 MB RAM,Fluent Bit 將消耗 150 KB”——文檔中的直接引用。 由此看來,Fluent Bit 的應用已經更加廣泛。
Fluent Bit 的功能比 Fluentd 少,但涵蓋了主要需求,所以我們主要使用 Fluent Bit。
EFK 堆棧的工作原理:代理從所有 pod(通常是在所有集群服務器上運行的 DaemonSet)收集日誌並將其發送到存儲(Elasticsearch、PostgreSQL 或 Kafka)。 Kibana 連接到存儲庫並從那裡檢索所有必要的信息。

在用戶友好的網絡界面中呈現信息。 有圖表、過濾器等等。

日誌可用於創建整個儀表板。

Fluent Bit 特點
由於 Fluent Bit 通常比 Logstash 鮮為人知,所以讓我們仔細看看它。 Fluent Bit 在邏輯上可以分為 6 個模塊,並且可以將插件附加到某些模塊上以擴展 Fluent Bit 的功能。

輸入模塊 從文件、systemd 服務甚至從 tcp-socket 收集日誌(您只需要指定一個端點,Fluent Bit 將開始前往那裡)。 這些功能足以從系統和容器收集日誌。
在生產中,我們最常使用插件 (可以設置在有日誌的文件夾中)和 (可以告訴他從哪些服務收集日誌)。
解析器模塊 將日誌帶到一個共同的視圖中。 默認情況下,Nginx 日誌是一個字符串。 使用該插件,可以將此字符串轉換為 JSON:設置字段及其值。 JSON 比字符串日誌更容易使用,因為有更靈活的排序選項。
過濾模塊。 在此級別,不必要的日誌將被消除。 例如,日誌僅與值“警告”或帶有某些標籤一起發送以供存儲。 所選日誌將被緩衝。
緩沖模塊。 Fluent Bit 有兩種類型的緩衝區:內存緩衝區和磁盤緩衝區。 緩衝區是日誌的臨時存儲,在發生錯誤或故障時需要。 每個人都希望在 RAM 上保存數據,因此他們通常選擇磁盤緩衝區。 但請記住,在進入磁盤之前,日誌仍會卸載到內存中。
路由/輸出模塊 包含發送日誌的規則和地址。 如前所述,日誌可以發送到 Elasticsearch、PostgreSQL 或 Kafka。
有趣的是,日誌可以從 Fluent Bit 發送到 Fluentd。 由於第一個更輕量級且功能較少,您可以通過它收集日誌並將它們發送到 Fluentd,並且已經在那裡,在其他插件的幫助下,可以進一步處理它們並將其發送到存儲。
如果您打算使用 Elasticsearch...
最後,為那些計劃在生產中使用 Elasticsearch 作為日誌存儲庫的人提供兩個提示。
- 設置警報 。 該程序將重要消息與一般日誌流隔離開來,並通過郵件或其他渠道對其發出警報。 確實,不久前 .
- 使用應用程序輪換日誌 或調用 Elasticsearch API。 原則上,Elastic 本身現在正在採取重大措施來管理索引的生命週期,而無需使用第三方工具。 一般來說,長時間保存日誌是沒有意義的:兩週後不太可能需要任何日誌——如果真的很關鍵,那麼兩週內肯定會解決。 在極端情況下,舊日誌可以歸檔並發送到某個地方進行長期存儲。 我聽說法律要求特殊日誌保存長達 5 年。 就我個人而言,我還沒有遇到過這種情況,但我不會將此類信息與普通日誌等同起來,甚至可能將它們分開存儲。
待續...
作者:Marcel Ibraev,認證 Kubernetes 管理員,公司執業工程師 、演講者和課程開發者 .
來源: www.habr.com
