數人云工程師手記 | 容器日誌管理實踐

業務平臺天天產生大量日誌數據,爲了實現數據分析,須要將生產服務器上的全部日誌收集後進行大數據分析處理,Docker提供了日誌驅動,然而並不能知足不一樣場景需求,本次將結合實例分享日誌採集、存儲以及告警等方面的實踐經驗。docker

2013年以來Docker迅速火了起來,它的理念帶來了很是大的便利性,不過實際應用中會發現還有監控、日誌、網絡等問題尚待解決,本文會結合實例分享數人云作容器日誌系統的經驗。json

基於ELK的日誌管理系統架構

日誌收集是大數據的基礎,業務平臺天天產生大量日誌數據,爲了實現數據分析,須要將生產服務器上的全部日誌收集後進行分析處理;高可用性,高可靠性以及可擴展性是日誌收集系統的必備要素。後端

ELK是目前較流行的日誌一體化解決方案,提供日誌收集、處理、存儲、搜索、展現等功能。容器標準輸出日誌經常使用的查詢方式是經過Docker命令 docker logs containerid來查看,容器內日誌受容器隔離性影響不便於收集,所以當面對大型系統,用單一命令管理日誌是不可行的,須要一個對於容器日誌統一檢索管理的方案。基於ELK實踐了一套容器日誌管理系統,架構以下:
圖片描述服務器

日誌採集

傳統的日誌採集有較成熟的解決方案,如Flume、Logstash等,但傳統的採集方案不適用於容器日誌。Docker自己提供了LogDriver功能,能夠利用不一樣的driver把日誌輸出到不一樣地方,LogDriver具體有如下幾種:網絡

  • None(將日誌設置成再也不輸出)架構

  • json-file(Docker默認的LogDriver,將日誌以JSON文件的方式存儲在本地)框架

  • Syslog(標準輸出日誌可經過該方式傳輸)分佈式

  • Journal函數

  • SELF工具

  • Fluent

  • awslogs

  • Splunk

  • etwLogs

  • gcplogs

對於這些LogDriver就不一一詳細介紹了,你們有興趣能夠去Docker官網查看。可見Docker對日誌提供了較爲豐富的處理方式,供選擇的還有優秀的開源項目Logspout等,然而這並不能知足全部的使用場景。

容器的標準輸出日誌可從以上驅動中選擇,因爲大多數用戶選擇標準化輸出日誌,故Docker沒有提供採集功能,若是將日誌內的文件掛載出來進行採集,多個實例同名日誌則會沒法區分,容器內文件日誌處理、錯誤日誌多行處理等問題時有發生,若想標準輸出日誌和容器內文件日誌兼得,則需本身動手豐衣足食,如下爲數人云日誌採集系統實踐。

1. 標準輸出日誌

針對Marathon + Mesos環境開發了一套日誌採集工具,Docker的標準輸出日誌json-file默認持久化在本地上,Mesos對於標準輸出日誌也存了一份在Sandbox下:
圖片描述

所以標準輸出日誌也能夠經過Mesos文件的方式進行採集。

2. 容器內文件日誌

平臺支持的文件存儲是Overlay,避免了許多複雜環境的處理。關於Overlay盜用一張圖:
圖片描述

容器的存儲驅動運用寫時複製(Copy On Write),Overlay主要分爲lower和upper, 當須要修改一個文件時,使用CoW將文件從只讀的Lower層複製到可寫層Upper層進行修改,在Docker中,底部的只讀層是image,可寫層是Container,所以容器內日誌在宿主機上經過Upper的文件系統可找到,例如在容器內的/var/log/test.log中寫一個test字符,如圖:
圖片描述

同理,不管是標註輸出的日誌仍是容器內文件日誌,均可以經過文件的方式進行處理,也能夠同時把json-file關閉,以減輕Docker自己的壓力。

3. 自研日誌採集工具

基於上述方式開發了一款日誌採集工具,對日誌進行統一收集管理,日誌經過TCP把JSON格式化的日誌輸出到Logstash,包括應用ID,容器Name,容器ID,TaskID等,固然開發的過程當中也遇到許多問題,如斷點續傳和錯誤日誌多行處理等功能,這其中參考了Filebeat(Go語言開發)對於日誌處理的方式,我的認爲若是是對於傳統文件日誌處理,Filebeat是不錯的選擇,日誌採集功能第一步支持:

  • 容器標準輸出日誌採集

  • 容器內文件日誌採集,支持同時採集多個文件

  • 斷點續傳 (若是Agent崩潰,從上次offset採集)

  • 多行日誌合併 (如:多行錯誤日誌合併)

  • 日誌文件異常處理 (如:日誌被rotate能夠從新採集)

  • TCP傳輸

  • --add-env --add-label標籤,能夠經過指定命令把container的env或者label加到日誌數據裏,如(--add-env hostname=HOST --add-env test=ENV_NAME1 --add-label tlabel=label_name)

  • Prometheus指標數據

日誌處理須要提供快速的數據處理能力,在開發過程當中遇到了性能問題,CPU佔用很是高,針對該問題對程序做調優,使用Golang內置的包net/http/pprof,對Golang程序調優很好用,可將程序中每一個函數佔用CPU內存的比例經過生成SVG的方式直觀的反映出來,如圖:
圖片描述

Golang內置包encoding/json json的序列化、正則、反射、字節轉字符串對於資源的消耗也比較高,可針對以上幾方面以及程序自己進行調整。

日誌存儲後端架構

日誌存儲功能有Logstash、Heka、Fluentd等方案,Logstash基於R uby,支持功能豐富,但性能方面詬病較多;Heka基於Go,性能方面比Logstash好不少,不過Heka好像已經不維護了。綜合考慮社區活躍度、迭代速度以及穩定性方面最終選擇了Logstash,實際應用過程當中比較重要的參數以下:

  • --pipeline-workers (命令行參數)

  • --pipeline-batch-size (命令行參數)

  • LS_HEAP_SIZE=${LS_HEAP_SIZE} (根據本身的實際狀況填寫,能夠寫到環境變量活着命令行參數裏面)

  • workers => 8(根據本身實際狀況,通常等於CPU數,配置文件參數)

  • flush_size => 3000(根據本身的實際狀況測試)

以上參數僅供參考,可根據實際環境進行調試。若是日誌量較大,爲了確保架構的穩定性,能夠在中間加一層消息隊列,比較經常使用的有Kafka、Redis等,相信你們對這方面應用比較多,再也不贅述。

ES應該是索引存儲的不二選擇,整個架構的緩解包括ES經過Docker的方式部署,壓測時用Marvel對ES的索引方式監控等,網上有不少調優資料,可自行實驗。日誌的展現是經過本身定製的,Kibana自己的功能比較強大的同時也略微有些學習成本,最終客戶想要的是很簡單的東西。

壓測工具選擇的是分佈式壓測工具Tsung,經過壓測一個應用產生日誌而後經過Log-Agent對日誌進行採集,模擬真實環境日誌採集。

日誌告警

日誌處理中,關鍵字報警是一個重要功能,對於監控報警主要用Prometheus + Alertmanager實現。應用運行過程當中,根據日誌關鍵字告警部的應用場景,從Logstash部分對日誌作分流(具體方案能夠看上面圖的報警部分),自研grok_export對日誌進行過濾分析生成Prometheus格式的數據,而後從Prometheus配置報警策略經過alertmanager報警。Log-Agent自己也支持Prometheus數據,Prometheus經過特定的規則查看日誌的統計信息。

  • Prometheus:
    Prometheus是開源的監控告警系統,經過pull的方式採集時間序列,以及用http傳輸,數據存儲在本地,支持豐富的查詢語法和簡單的Dashboard展現。

  • Alertmanager:
    Alertmanager做爲Prometheus的組件,全部達到閥值的時間都經過Alertmanager報警,Alertmanager支持很是強大的告警功能,包括http、email通知,以及靜默重複報警屏蔽等功能。

以上是數人云在實踐容器日誌系統過程當中遇到的問題,更高層次的應用包括容器日誌分析等,還有待繼續挖掘和填坑,歡迎你們提出建議,一塊兒交流。

Q&A

Q:Overlay 是沒有實現 inotify 接口的,是咋獲取文件日誌增量數據的?

A:經過循環讀取文件的方式,記錄文件offset。

Q:既然主要框架是 ELK,採集端不直接用 Filebeat 是由於 Filebeat 有侷限性嗎?

A:Filebeat沒有知足咱們產品基於Docker的需求,等於上面加了Docker的邏輯。

Q:自研的日誌系統,打出來的每條日誌格式都是規定好的嗎?開發中每一個人都要按這個規範來作嗎?不論是什麼級別的日誌?

A:其實並無,可是若是是內部使用,能規約好固然更好,能夠更方便的處理,並且能夠作更細粒度的分析。

Q:日誌收集有作分析展現處理嗎?用什麼處理的。

A:對於日誌內容的分析還沒作,例如Nginx請求日誌仍是有分析意義的。

Q:採集方面有考慮直接使用系統的Syslog和Logrotate嗎?

A:用過Syslog後來由於容器內的文件日誌需求從新開發的。

相關文章
相關標籤/搜索