天天看點

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

原文作者:EdisonZhou

原文連結:

https://developer.aliyun.com/article/727997 監控和日志曆來都是系統穩定運作和問題排查的關鍵,在微服務架構中,數量衆多的容器以及快速變化的特性使得一套集中式的日志管理系統變成了生産環境中一個不可擷取的部分。此次話題我們會集中在日志管理方面,本篇會介紹 Docker 自帶的 logs 子指令以及其 Logging driver,然後介紹一個流行的開源日志管理方案 ELK/EFK。

一、Docker logs 子指令

  預設情況下,Docker 的日志會發送到容器的标準輸出裝置(STDOUT)和标準錯誤裝置(STDERR),其中 STDOUT 和 STDERR 實際上就是容器的控制台終端。

  我們可以通過 logs 子指令來檢視具體某個容器的日志輸出:

docker logs edc-k8s-demo

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  這時看到的日志是靜态的,截止到目前為止的日志。如果想要持續看到新列印出的日志資訊,那麼可以加上 -f 參數,如:

docker logs -f edc-k8s-demo

二、Docker logging driver

  剛剛我們學習了預設配置下,Docker 日志會發送到 STDOUT 和 STDERR。但實際上,Docker 還提供了其他的一些機制允許我們從運作的容器中提取日志,這些機制統稱為 logging driver。

  對 Docker 而言,其預設的 logging driver 是 json-file,如果在啟動時沒有特别指定,都會使用這個預設的 logging driver。

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  json-file 會将我們在控制台通過 docker logs 命名看到的日志都儲存在一個json檔案中,我們可以在伺服器Host上的容器目錄中找到這個 json 檔案。

容器日志路徑:/var/lib/docker/containers/<container-id>/<container-id>-json.log

  例如我們可以檢視一個 exceptionless-api 容器的 json 日志:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  一個快速檢視某個容器的日志檔案路徑的方法:

docker inspect exceptionless_api_1

  通過 inspect 指令,可以查到該容器的 ID 及一系列配置資訊,我們重點關注 LogPath 即可:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  查到 LogPath 後,即可複制其後面的日志路徑了,打開這個 json 檔案你就可以看到輸出的容器日志了。

  除了 json-file,Docker 還支援以下多種 logging dirver,來源:Configure logging drivers

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  其中,none 代表禁用容器日志,不會輸出任何容器日志。

  其他幾個logging driver解釋如下:

  • syslog 與 journald 是Linux上的兩種日志管理服務
  • awslog、splunk 與 gcplogs是第三方日志托管服務
  • gelf 與 fluentd 是兩種開源的日志管理方案

      我們可以在容器啟動時通過加上 --log-driver 來指定使用哪個具體的 logging driver,例如:

docker run -d --log-driver=syslog ......

  如果想要設定預設的logging driver,那麼則需要修改Docker daemon的啟動腳本,例如:

{
  "log-driver": "json-file",
  "log-opts": {
    "labels": "production_status",
    "env": "os,customer"
  }
}
           

  每個logging driver都有一些自己特定的log-opt,使用時可以參考具體官方文檔。

三、關于ELK

3.1 ELK簡介

  ELK 是Elastic公司提供的一套完整的日志收集以及展示的解決方案,是三個産品的首字母縮寫,分别是ElasticSearch、Logstash 和 Kibana。

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

Elasticsearch 是實時全文搜尋和分析引擎,提供搜集、分析、存儲資料三大功能

Logstash 是一個用來搜集、分析、過濾日志的工具

Kibana 是一個基于 Web 的圖形界面,用于搜尋、分析和可視化存儲在 Elasticsearch 名額中的日志資料

3.2 ELK 日志處理流程

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  上圖展示了在 Docker 環境下,一個典型的 ELK 方案下的日志收集處理流程:

  • Logstash 從各個 Docker 容器中提取日志資訊
  • Logstash 将日志轉發到 ElasticSearch 進行索引和儲存
  • Kibana 負責分析和可視化日志資訊

      由于 Logstash 在資料收集上并不出色,而且作為 Agent,其性能并不達标。基于此,Elastic 釋出了 beats 系列輕量級采集元件。

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  這裡我們要實踐的 Beat 元件是 Filebeat,Filebeat 是建構于 beats 之上的,應用于日志收集場景的實作,用來替代 Logstash Forwarder 的下一代 Logstash 收集器,是為了更快速穩定輕量低耗地進行收集工作,它可以很友善地與 Logstash 還有直接與 Elasticsearch 進行對接。

  本次實驗直接使用Filebeat作為Agent,它會收集我們在第一篇《Docker logs & logging driver》中介紹的json-file的log檔案中的記錄變動,并直接将日志發給ElasticSearch進行索引和儲存,其處理流程變為下圖,你也可以認為它可以稱作 EFK。

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

四、ELK套件的安裝

  本次實驗我們采用 Docker 方式部署一個最小規模的 ELK 運作環境,當然,實際環境中我們或許需要考慮高可用和負載均衡。

  首先拉取一下 sebp/elk 這個內建鏡像,這裡選擇的 tag 版本是 640(最新版本已經是 7XX 了):

docker pull sebp/elk:640

  注:由于其包含了整個 ELK 方案,是以需要耐心等待一會。

  通過以下指令使用 sebp/elk 這個內建鏡像啟動運作 ELK:

docker run -it -d --name elk \
    -p 5601:5601 \
    -p 9200:9200 \
    -p 5044:5044 \
    sebp/elk:640
           

  運作完成之後就可以先通路一下

http://[Your-HostIP]:5601

看看Kibana的效果:  

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  Kibana管理界面

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

Kibana Index Patterns界面

  當然,目前沒有任何可以顯示的ES的索引和資料,再通路一下

http://[Your-HostIP]:9200

看看ElasticSearch的API接口是否可用:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

ElasticSearch API

  _Note:_如果啟動過程中發現一些錯誤,導緻ELK容器無法啟動,可以參考《Docker啟動ElasticSearch報錯》及《ElasticSearch啟動常見錯誤》一文。如果你的主機記憶體低于4G,建議增加配置設定ES記憶體使用大小,以免啟動不了。例如下面增加的配置,限制ES記憶體使用最大為1G:

docker run -it -d --name elk \
    -p 5601:5601 \
    -p 9200:9200 \
    -p 5044:5044 \
   -e ES_MIN_MEM=512m \
    -e ES_MAX_MEM=1024m \
    sebp/elk:640           

五、Filebeat配置

5.1 安裝Filebeat

  這裡我們通過rpm的方式下載下傳Filebeat,注意這裡下載下傳和我們ELK對應的版本(ELK是6.4.0,這裡也是下載下傳6.4.0,避免出現錯誤):

wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.4.0-x86_64.rpm
rpm -ivh filebeat-6.4.0-x86_64.rpm           

5.2 配置Filebeat  

  這裡我們需要告訴Filebeat要監控哪些日志檔案 及 将日志發送到哪裡去,是以我們需要修改一下Filebeat的配置:

cd /etc/filebeat
vim filebeat.yml           

  要修改的内容為:

  (1)監控哪些日志?

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

- type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/lib/docker/containers/*/*.log
    - /var/log/syslog           

  這裡指定paths:/var/lib/docker/containers/_/_.log,另外需要注意的是将 enabled 設為 true。

  (2)将日志發到哪裡?

#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["192.168.16.190:9200"]

  # Optional protocol and basic auth credentials.
  #protocol: "https"
  #username: "elastic"
  #password: "changeme"           

  這裡指定直接發送到ElasticSearch,配置一下ES的接口位址即可。

  _Note:_如果要發到Logstash,請使用後面這段配置,将其取消注釋進行相關配置即可:

#----------------------------- Logstash output --------------------------------
#output.logstash:
  # The Logstash hosts
  #hosts: ["localhost:5044"]

  # Optional SSL. By default is off.
  # List of root certificates for HTTPS server verifications
  #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]

  # Certificate for SSL client authentication
  #ssl.certificate: "/etc/pki/client/cert.pem"

  # Client Certificate Key
  #ssl.key: "/etc/pki/client/cert.key"           

5.3 啟動 Filebeat

  由于 Filebeat 在安裝時已經注冊為 systemd 的服務,是以隻需要直接啟動即可:

systemctl start filebeat.service           

  檢查 Filebeat 啟動狀态:

systemctl status filebeat.service           

5.4 驗證 Filebeat

  通過通路ElasticSearch API可以發現以下變化:ES建立了以filebeat-開頭的索引,我們還能夠看到其來源及具體的message。

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

六、Kibana 配置

  接下來我們就要告訴 Kibana,要查詢和分析 ElasticSearch 中的哪些日志,是以需要配置一個 Index Pattern。從 Filebeat 中我們知道 Index 是 filebeat-timestamp 這種格式,是以這裡我們定義 Index Pattern 為 filebeat-*

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  點選 Next Step,這裡我們選擇 Time Filter field name 為 @timestamp:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  單擊 Create index pattern 按鈕,即可完成配置。

  這時我們單擊 Kibana 左側的 Discover 菜單,即可看到容器的日志資訊啦:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  仔細看看細節,我們關注一下 message 字段:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  可以看到,我們重點要關注的是 message,是以我們也可以篩選一下隻看這個字段的資訊:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  此外,Kibana 還提供了搜尋關鍵詞的日志功能,例如這裡我關注一下日志中包含 unhandled exception(未處理異常)的日志資訊:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  這裡隻是樸素的展示了導入 ELK 的日志資訊,實際上 ELK 還有很多很豐富的玩法,例如分析聚合、炫酷 Dashboard 等等。筆者在這裡也是初步使用,就介紹到這裡啦。

七、Fluentd 引入

7.1 關于 Fluentd

  前面我們采用的是 Filebeat 收集 Docker 的日志資訊,基于 Docker 預設的 json-file 這個 logging driver,這裡我們改用 Fluentd 這個開源項目來替換 json-file 收集容器的日志。

  Fluentd 是一個開源的資料收集器,專為處理資料流設計,使用 JSON 作為資料格式。它采用了插件式的架構,具有高可擴充性高可用性,同時還實作了高可靠的資訊轉發。Fluentd 也是雲原生基金會 (CNCF) 的成員項目之一,遵循 Apache 2 License 協定,其 github 位址為:

https://github.com/fluent/fluentd/

Fluentd 與 Logstash 相比,比占用記憶體更少、社群更活躍,兩者的對比可以參考這篇文章《Fluentd vs Logstash》。

  是以,整個日志收集與處理流程變為下圖,我們用 Filebeat 将 Fluentd 收集到的日志轉發給 Elasticsearch。

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

  當然,我們也可以使用 Fluentd 的插件(fluent-plugin-elasticsearch)直接将日志發送給 Elasticsearch,可以根據自己的需要替換掉 Filebeat,進而形成 Fluentd => ElasticSearch => Kibana 的架構,也稱作 EFK。

7.2 運作 Fluentd

  這裡我們通過容器來運作一個 Fluentd 采集器:

docker run -d -p 24224:24224 -p 24224:24224/udp -v /edc/fluentd/log:/fluentd/log fluent/fluentd           

  預設 Fluentd 會使用 24224 端口,其日志會收集在我們映射的路徑下。

  此外,我們還需要修改 Filebeat 的配置檔案,将 /edc/fluentd/log 加入監控目錄下:

#=========================== Filebeat inputs =============================

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

- type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /edc/fluentd/log/*.log           

  添加監控配置之後,需要重新 restart 一下 filebeat:

systemctl restart filebeat           

7.3 運作測試容器

  為了驗證效果,這裡我們 Run 兩個容器,并分别制定其 log-dirver 為 fluentd:

docker run -d \
           --log-driver=fluentd \
           --log-opt fluentd-address=localhost:24224 \
           --log-opt tag="test-docker-A" \
           busybox sh -c 'while true; do echo "This is a log message from container A"; sleep 10; done;'

docker run -d \
           --log-driver=fluentd \
           --log-opt fluentd-address=localhost:24224 \
           --log-opt tag="test-docker-B" \
           busybox sh -c 'while true; do echo "This is a log message from container B"; sleep 10; done;'           

  這裡通過指定容器的 log-driver,以及為每個容器設立了 tag,友善我們後面驗證檢視日志。

7.4 驗證 EFK 效果

  這時再次進入 Kibana 中檢視日志資訊,便可以通過剛剛設定的 tag 資訊篩選到剛剛添加的容器的日志資訊了:

容器日志管理:從 docker logs 到 ELK/EFK一、Docker logs 子指令二、Docker logging driver三、關于ELK四、ELK套件的安裝五、Filebeat配置七、Fluentd 引入

八、小結

本文從 Docker 自帶的 logs 子指令入手,介紹了 Docker 具有多種 logging dirver,然後過度到 ELK 的基本組成,并介紹了 ELK 的基本處理流程,以及從 0 開始搭建了一個 ELK 環境,示範了基于 Filebeat 收集容器日志資訊的案例。然後,通過引入 Fluentd 這個開源資料收集器,示範了如何基于 EFK 的日志收集案例。當然,ELK/EFK 有很多的知識點,希望未來能夠分享更多的實踐總結。

“阿裡巴巴雲原生微信公衆号(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術公衆号。”