理解OpenShift(6):集中式日誌處理

 

理解OpenShift(1):網絡之 Router 和 Routehtml

理解OpenShift(2):網絡之 DNS(域名服務)node

理解OpenShift(3):網絡之 SDNmysql

理解OpenShift(4):用戶及權限管理nginx

理解OpenShift(5):從 Docker Volume 到 OpenShift Persistent Volumegit

理解OpenShift(6):集中式日誌處理github

 

** 本文基於 OpenShift 3.11,Kubernetes 1.11 進行測試 ***sql

1. Docker 容器日誌處理的幾種方式

(1)由應用本身處理日誌,而不須要容器引擎參與docker

好比一個使用Log4j2 日誌組件的Java應用, 它經過日誌組件將日誌發往一個遠端日誌服務器。此時,不利用容器引擎的日誌功能。數據庫

(2)使用數據卷(Data volume)json

使用數據卷,容器內應用將日誌寫入數據卷中。此時,也不利用容器引擎的日誌功能。

(3)使用 Docker 日誌驅動(logging driver)

Docker 日誌驅動會讀取容器中主進程的 stdout(標準輸出) 和 stderr(錯誤輸出),而後將內容寫入容器所在的宿主機上的文件中。

Docker 支持多種日誌驅動。

(圖片來源:https://jaxenter.com/docker-logging-gotchas-137049.html

幾個比較常見的:

  • json-file: 這是默認驅動。容器主進程(PID 爲1的進程)的 stdout 和 stderr 會被輸出到宿主機上的 JSON 文件。該文件能夠在 docker inspect 命令的"LogPath"輸出中看到,好比 "LogPath": "/var/lib/docker/containers/a44b41506dc48a469fd69ddbdf84ad16d14f16191164361a69606c579c506a2c/a44b41506dc48a469fd69ddbdf84ad16d14f16191164361a69606c579c506a2c-json.log"。
  • syslog: 將日誌信息發送到 syslog 服務器
  • journald: 將容器日誌信息寫入journald (journald 是 systemd 提供的一個日誌服務)
  • gelf: 將日誌消息寫入一個 GELF 端點,好比 Logstash
  • fluentd: 將日誌信息發送到 Fluentd 服務 

更多日誌驅動,能夠查看 https://docs.docker.com/config/containers/logging/configure/#supported-logging-drivers。 

Docker 還支持插件形式的更多日誌驅動,具體請看 https://docs.docker.com/config/containers/logging/plugins/

(4)使用專門的日誌容器

Docker 日誌驅動這種實現方式有一些限制:

  • 只支持日誌轉發,不會作日誌解析和處理
  • 只支持容器內應用發到 stdout 和 stderr 的日誌,不支持其它日誌,好比日誌文件內的日誌

對於這些不支持的場景,好比應用有將日誌寫到日誌文件,此時能夠利用在同一個Pod中的專門日誌容器。它會以邊車(sidecar)形式讀取應用容器中的日誌產生,而後作處理和轉發,好比轉發到 stdout 和 stderr。

另外,某些這種場景還有另一種更簡單的處理方式。以 Nginix 爲例,它默認寫入日誌文件,而後經過下面的方式,將日誌也輸出到 stdout 和 stderr。這種方式有一些限制,具體可參考 https://github.com/moby/moby/issues/19616

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
    && ln -sf /dev/stderr /var/log/nginx/error.log

2. Kubernetes/OpenShfit 日誌處理

2.1 EFK 概述

OpenShift/Kubernetes 環境的日誌處理可分爲三個發展階段,或三種處理類型:

類型 說明 使用方式
容器本地日誌(container local logging) 寫到容器內部的標準輸出(standard output)和標準錯誤流(stand error),或者容器內日誌文件。這種日誌的問題是當容器死掉後,日誌也會丟失,也就沒法再訪問了。 需登陸進容器查看日誌文件,或使用容器命令獲取日誌。OpenShift 提供 oc rsh 命令以進入容器,oc logs 命令以獲取日誌。
節點本地日誌(node-level logging) 容器引擎將容器中全部的標準輸出和標準錯誤輸出都轉發到容器所在的本地節點上。Docker 可利用其日誌驅動(logging driver)。爲了不容器中的日誌將節點撐爆,能夠作 log rotation。這種方式比 local logging 方式要好,可是還不是很是好,由於日誌會保存在本地節點上。 需登陸宿主機,查看本地日誌文件
集羣集中日誌(cluster-level-loggin) 這須要另外的後端來存儲、分析和查詢日誌。後端能夠在集羣內,也可在集羣外。一個  node-level 日誌處理插件(好比 Fluentd)會運行在每一個節點上,將節點上的日誌發到集中的日誌處理後端。還有一個可視化組件,讓用戶能夠可視化地查看日誌。 可經過瀏覽器或其它可視化界面在線查看日誌

EFK(ElasticSearch - Fluentd - Kibana)是一種可以實現集羣集中日誌處理的開源套件。其中,

三個組件中,Fluentd 會直接和Docker/K8S/OKD打交道,而 ES 和 Kibana 則相對獨立,不和容器集羣有直接關係,除了用戶校驗之外。Fluentd 致力於解決多種日誌來源和多種日誌存儲之間的複雜問題。它做爲日誌和日誌存儲之間的中間件,負責日誌的收集、過濾和轉發工做。

 

Fluentd 採用插件形式的架構,支持爲了知足各類需求的日誌採集、過濾、緩存和輸出等功能。其v0.12 版本架構以下:

其中:

  • Input: 告訴 Fluentd 引擎待收集的日誌
  • Engine:  主引擎,實現核心功能,好比緩存(buffering)、錯誤處理、消息路由等
  • Output:  告訴 Fluentd 將輸出的日誌發往何處,經過插件支持多種目的,好比 ElasticSearch、MongoDB 或數據庫等。 

2.2 OpenShift 環境中的EFK

2.2.1 EFK 部署

2.2.2 Fluentd

在 K8S/OKD 環境中,Fulentd 以 DeamonSet 形式運行在每一個節點上。它會以 Volume 形式將所在宿主機上的多個保存日誌的目錄或文件掛載進容器,以被容器中的Fluentd進程所讀取:

  • /run/log/journal:這是系統 systemd 輸出日誌的目錄。
  • /var/log:這是系統全部日誌的根目錄。
  • /var/lib/docker:Docker 容器引擎經過日誌驅動將本機上全部容器的標準輸出和標準錯誤輸出保存在該目錄中,每一個容器一個文件。

Fluentd 的配置文件被建立了一個 OpenShfit ConfigMap 對象(名爲logging-fluentd),而後該對象被以 Volume 形式掛載爲Fluentd容器目錄 /etc/fluent/configs.d/user。其中的配置文件 fluentd.conf 指定了Fluentd 所使用的 input、filter 和 output 插件及其配置:

其中

  • input 指定了將被收集的日誌,主要包括 audit log、容器 log 和 systemd log 等。
  • filter 部分則指定了各類過濾和處理被收集到的日誌的方式。
  • output 定義了目標 ElasticSerach。K8S/OKD EFK 容許存在兩個 ES 集羣,一個用於保存容器中應用的日誌,一個用於保存系統日誌。 

ES 環境的信息以環境變量的形式保存在 Fluentd pod 上:

 

2.3 採用EFK後的好處和影響

被影響人員 影響(好的方面) 影響(很差的方面)/要求
容器雲平臺運維人員
  • 對平臺全部有價值的日誌能作到統一收集、統一存儲和查詢
  • 統一了日誌處理的技術棧
  • 爲未來進一步數據處理作準備
  • 會引入一套新的技術棧和工具,須要有學習成本
容器應用開發人員
  • 能夠在統一的瀏覽器界面(Kibana)上查詢全部容器的應用
  • 要求將容器中應用的日誌都輸出到標準輸出和標準錯誤輸出
  • 須要改變傳統的登陸到環境中查看日誌的習慣,改成在Kibana界面上查看日誌
  • 須要有Kibana 界面使用的一些技能和知識
容器雲平臺研發團隊
  • 集中式日誌是容器雲平臺不可或缺的一個重要組件
  • 須要考慮具體的實現架構和部署架構,作到穩定、可靠、彈性
  • 須要考慮在瀏覽器中查看日誌這種新方式對應用開發人員的影響,須要注意用戶體驗,讓用戶接受這種新方式

3. 日誌系統的集中部署模式

備註:本部份內容引用自 http://blog.51cto.com/13527416/2051506

3.1 簡單架構

這種架構只適合於開發測試環境,以及小型生產環境。

3.2 集羣架構

這種架構適合於較大型可是日誌產生量不大及頻率不高的環境。

3.3 引入消息隊列

在日誌產生量大頻率高的狀況下,須要引入消息隊列,以減輕對後端日誌存儲的壓力,減小日誌丟失機率。

3.4 多機房部署 - 獨立部署

採用單元化部署的方式來解決 ELK 多機房中遇到的問題(延時、專線流量過大等),從日誌的產生、收集、傳輸、存儲、展現都是在同機房裏面閉環消化,不存在跨機房傳輸與調用的問題。由於交互緊密的應用盡可能部署在同機房,因此這種方案並不會給業務查詢形成困擾。
Logstash、Elasticsearch、Kafka、Kibana 四個集羣都部署到同一機房中,每一個機房都要每一個機房本身的日誌服務集羣,好比A機房業務的日誌只能傳輸給本機房 Kafka ,而A機房 Indexer 集羣消費並寫入到A機房 Elasticsearch 集羣中,並由A機房 Kibana 集羣展現,中間任何一個步驟不依賴B機房任何服務。
該架構比較簡單直接,但問題是用戶須要在多個 Kibana 上查看部署在各個數據中心的應用產生的日誌。

3.5 多機房部署 - 跨機房部署

目前沒有特別成熟的方案,估計大部分的架構仍是前面的架構,這種跨機房架構更多地在大型互聯網公司有落地。一般有幾種方案供參考:

方案一,雙寫。技術可行。
在數據寫入ES時,經過MQ或者其餘方式實現數據雙寫或者多寫,目前不少MQ都有數據持久化功能,能夠保障數據不丟;再結合ES各類狀態碼來處理數據重複問題,便可實現多中心數據的最終一致。
 
方案二,第三方數據同步。基本上不可行。
例如使用mysql的主從同步功能,在不一樣數據中心之間,從本機房的mysql同步數據到ES,依託mysql數據一致性來保障ES數據一致。datax,StreamSet均提供了相似功能。
 
方案三,基於ES translog同步。基本上不可行。
讀取translog,同步並重放,相似於mysql binlog方式。看起來這種方式最乾淨利落,但涉及到ES底層代碼修改,成本也較高,目前已有的實踐。
 
方案4,ES 正在實現新的 CCR(當前爲beta版本)。期待未來可行。
cross cluster replication, 基於底層 sequence id 機制,實現的 Changes API,一個集羣可被另一個集羣或是本集羣「訂閱」,從而能夠實現數據複製,進行同步,能夠是跨數據中心集羣也能夠本地集羣的數據同步。
 
方案5,ElasticSearch Tribe 方案。這種方案在 ES 前面放置一個集中式中間件,用於 Kibana 訪問。好像也不是特別靠譜。

 

參考鏈接:

感謝您的閱讀,歡迎關注個人微信公衆號:

相關文章
相關標籤/搜索