使用ELK處理Docker日誌(一)

[編者的話] Daniel Berman ( Logz.io 產品經理)爲了記念 Docker 四歲生日,撰寫一系列文章,介紹如何使用 ELK 收集和處理 Dockerized 環境日誌。小數今天給你們帶來的第一部分將介紹如何安裝各個組件以及不一樣日誌收集方案的特色,下一部分將側重於分析和可視化,近期發出,記得關注咱們噢~git

PS :數人云工程師們已奔赴奧斯汀 DockerCON2017 現場,更多最佳實踐後天爲您奉上!github

image

容器運行程序時產生的日誌具備「無常,分佈,隔離」等特色,所以在架構中收集 Docker 日誌面臨很大的挑戰,有待嘗試一種強有力的日誌收集和處理方案來解決此類複雜問題。docker

ELK ( Elasticsearch , Logstash 和 Kibana )是處理容器日誌的一種方式,儘管設置 ELK 工做流並不容易(難度取決於環境規格),但最終可使用 Kibana 的監控面板來展現 Docker 日誌:json

image.數組

爲了記念 Docker 四歲生日,咱們將撰寫一系列文章,介紹如何使用 ELK 收集和處理 Dockerized 環境日誌。第一部分將介紹如何安裝各個組件以及不一樣日誌收集方案的特色,並創建從容器中收集日誌的工做流,下一部分將側重於分析和可視化。bash

日誌收集的流程

Dockerized 環境中的典型 ELK 日誌收集流程以下所示:服務器

image

Logstash 負責從各類 Docker 容器和主機中提取日誌,這個流程的主要優勢是能夠更好地用過濾器來解析日誌, Logstash 將日誌轉發到 Elasticsearch 進行索引, Kibana 分析和可視化數據。網絡

固然這個流程能夠有多種不一樣的實現方式, 例如可使用不一樣的日誌收集和轉發組件, 如 Fluentd 或 Filebeat 將日誌發送到 Elasticsearch ,或者,添加一個由 Kafka 或 Redis 容器組成的中間層,做爲 Logstash 和 Elasticsearch 之間的緩衝區。上圖顯示了日誌從 Docker 到 ELK 的基本流程。架構

那麼,如何設置這個流程呢?app

組件安裝

能夠將 ELK 套件安裝在一個容器裏,也可使用不一樣的容器來分別安裝各個組件。
image

關於在 Docker 上部署 ELK 是不是生產環境的可行性解決方案(資源消耗和網絡是主要問題)仍然存在不少爭議,但在開發中這是一種很是方便高效的方案。

ELK 的 docker 鏡像推薦使用 docker-elk, 它支持豐富的運行參數(可以使用這些參數組合不一樣的版本)和文檔, 並且徹底支持最新版本的 Elasticsearch, Logstash, 和 Kibana.

在安裝組件以前須要確保如下端口沒有被佔用:5601 (Kibana), 9200 (Elasticsearch), and 5044 (Logstash).

同時須要確保內核參數 vm_max_map_count 至少設置爲 262144:

sudo sysctl -w vm.max_map_count=262144

To run the stack:

運行以下命令:

git clone https://github.com/deviantony/docker-elk.git
cd docker-elk
docker-compose up

正常狀況下, ELK 套件的三個服務(Elasticsearch, Logstash, Kibana)會啓動成功,默認持久化數據目錄 /var/lib/elasticsearch (Elasticsearch 的數據存儲目錄)

sudo docker ps

CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                                            NAMES

73aedc3939ad        dockerelk_kibana          "/bin/sh -c /usr/l..."   7 minutes ago       Up 6 minutes        0.0.0.0:5601->5601/tcp                           dockerelk_kibana_1

b684045be3d6        dockerelk_logstash        "logstash -f /usr/..."   7 minutes ago       Up 6 minutes        0.0.0.0:5000->5000/tcp                           dockerelk_logstash_1

a5778b8e4e6a        dockerelk_elasticsearch   "/bin/bash bin/es-..."   7 minutes ago       Up 7 minutes        0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   dockerelk_elasticsearch_1

測試安裝組件

可經過以下的方式來確保全部組件都能正常運行。

首先嚐試訪問 Elasticsearch 運行以下命令:

curl localhost:9200

輸出結果:

{
 "name" : "W3NuLnv",
 "cluster_name" : "docker-cluster",
 "cluster_uuid" : "fauVIbHoSE2SlN_nDzxxdA",
 "version" : {
   "number" : "5.2.1",
   "build_hash" : "db0d481",
   "build_date" : "2017-02-09T22:05:32.386Z",
   "build_snapshot" : false,
   "lucene_version" : "6.4.1"
 },
 "tagline" : "You Know, for Search"
}

打開 Kibaba 頁面經過 http://[serverIP]:5601:

image

值得注意的是須要輸入索引模式才能正常進行後續處理,這個稍後將會介紹。

發送 Docker 日誌到 ELK

安裝組件比較簡單,相比而言將 Docker 日誌發送到 ELK 有點複雜,這取決於輸出日誌的方式。

若是沒有額外指定,容器的 stdout 和 stderr 輸出(也稱爲「 docker logs 」)輸出到 JSON 文件。因此,若是是一個小型 Docker 環境,使用 Filebeat 來收集日誌將是不錯的選擇。但若是使用其餘日誌記錄驅動程序,則可能須要考慮其餘方法。

如下是將日誌導入 ELK 的三種不一樣的方法,切記,這並不能包含全部的方案。

使用 Filebeat

Filebeat 屬於 Elastic 的 Beats 系列日誌收集組件, Filebeat 是用 Go 語言開發的,支持追蹤特定文件和日誌加密的中間組件,它能夠配置將日誌導出到 Logstash 或者直接導出到 Elasticsearch.

如上所述,若使用默認的 json 文件記錄驅動程序, Filebeat 是一種相對簡便的方式,能夠輸出日誌到 ELK.Filebeat 部署在主機上,或將其做爲容器與 ELK 容器一塊兒運行(在這種狀況下,須要添加到 ELK 容器的連接),這裏有各類Filebeat Docker images可用,有些包括運行 Filebeat 並將其鏈接到 Logstash 的配置。

Filebeat 配置將須要指定 JSON 日誌文件的路徑(位於:/ var / lib / docker / containers / ...)和目標的詳細信息(一般是 Logstash 容器)。

下面是一個配置的例子

prospectors:     
 - paths:        
   - /var/log/containers/<xxx>          
   document_type: syslog     
output:
 logstash:  
  enabled: true  
  hosts:   
      - elk:5044

使用日誌驅動

Docker 從 1.12 開始支持Logging Driver,容許將 Docker 日誌路由到指定的第三方日誌轉發層,可將日誌轉發到 AWS CloudWatch , Fluentd , GELF 或 NAT 服務器。

使用 logging drivers 比較簡單,它們須要爲每一個容器指定,而且將須要在日誌的接收端進行其餘配置。

在將日誌發送到 ELK 的上下文中,使用 syslog 日誌驅動多是最簡單的方法。

下面是一個指定 Logging Driver 的例子:

docker run \
 --log-driver=syslog \
 --log-opt syslog-address=tcp://<SyslogServerIP>:5000
 \ --log-opt syslog-facility=daemon
 \ alpine ash

如此這樣運行每個容器,結果是將 Docker 容器日誌流輸出到 syslog 實例,這些日誌將轉發到 Logstash 容器進行解析和數據加強,進入 Elasticsearch 。

使用 Logspout

Logspout 是 Docker 流行和輕量級的( 15.2MB )日誌路由器,它將附加到主機中的全部容器,並將 Docker 日誌流輸出到 syslog 服務器(除非定義了不一樣的輸出目標)。

sudo docker run -d --name="logspout" --volume=/var/run/docker.sock:/var/run/docker.sock gliderlabs/logspout syslog+tls://<syslogServerIP>:5000

使用Logstash module直接將日誌路由到 Logstash 容器,但這須要其餘配置和編譯工做。

Logz.io 的日誌採集器

本人在 In this blog post這篇文章中介紹了 Logz.io 的日誌採集器,像 Logspout 同樣,它附加在 Docker 主機中的全部容器上,但它不只運送 Docker 日誌,還包含 Docker 統計信息和 Docker 守護程序事件。

docker run -d --restart=always -v /var/run/docker.sock:/var/run/docker.sock logzio/logzio-docker -t <YourLogz.ioToken>

目前它是爲 Logz.io ELK 套件的用戶設計的,咱們正在努力將它開源項目。

數據持久化

配置 Logstash 來解析數據相當重要,由於這部分過程將添加上下文到容器的日誌中,並可以更輕鬆地分析數據。

在 Logstash 配置文件中須要配置三個主要部分:輸入,過濾和輸出。 (若運行的是 Logstash 5.x ,則該文件位於:/ usr / share / logstash / pipeline )

輸入取決於日誌傳送方式,使用 Filebeat ,則須要指定 Beats 輸入插件。若是使用 logspout 或 syslog 日誌記錄驅動程序,則須要將 syslog 定義爲輸入。

過濾器部分包含用於分解日誌消息的全部過濾器插件,依賴於正在記錄的容器類型以及該特定容器生成的日誌消息。

這部分的配置沒有捷徑,由於每一個容器都輸出不一樣類型的日誌。有不少嘗試和錯誤涉及,可是有一些在線工具可參考, 好比:Grok Debugger

導出部分將指定 Logstash 輸出,例子中是 Elasticsearch 容器。

如下是經過 syslog 發送的 Docker 日誌的基本 Logstash 配置示例。注意一系列過濾器的使用( grok , date , mutate 和 if 條件):

input {
 syslog {
      port => 5000
      type => "docker"
      }
}

filter {
      grok {
            match => { "message" => "%{SYSLOG5424PRI}%{NONNEGINT:ver} +(?:%{TIMESTAMP_ISO8601:ts}|-) +(?:%{HOSTNAME:service}|-) +(?:%{NOTSPACE:containerName}|-) +(?:%{NOTSPACE:proc}|-) +(?:%{WORD:msgid}|-) +(?:%{SYSLOG5424SD:sd}|-|) +%{GREEDYDATA:msg}" }
      }
      syslog_pri { }
      date {
            match => [ "syslog_timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
      }
      mutate {
            remove_field => [ "message", "priority", "ts", "severity", "facility", "facility_label", "severity_label", "syslog5424_pri", "proc", "syslog_severity_code", "syslog_facility_code", "syslog_facility", "syslog_severity", "syslog_hostname", "syslog_message", "syslog_timestamp", "ver" ]
      }
      mutate {
            remove_tag => [ "_grokparsefailure_sysloginput" ]
      }
      mutate {
            gsub => [
                  "service", "[0123456789-]", ""
            ]
      }
      if [msg] =~ "^ *{" {
            json {
                  source => "msg"
            }
            if "_jsonparsefailure" in [tags] {
                  drop {}
            }
            mutate {
                  remove_field => [ "msg" ]
            }
      }
}

output {
 elasticsearch {
      hosts => "elasticsearch:9200"
      }
}

從新啓動 Logstash 容器以應用新的配置。檢查 Elasticsearch 索引,確保日誌流能正常工做:

curl 'localhost:9200/_cat/indices?v'

具備 Logstash 模式的索引:

health status index               uuid                   pri rep docs.count docs.deleted store.size pri.store.size

yellow open   logstash-2017.03.05 kgJ0P6jmQjOLNTSmnxsZWQ   5   1          3            0     10.1kb         10.1kb

yellow open   .kibana             09NHQ-TnQQmRBnVE2Y93Kw   1   1          1            0      3.2kb          3.2kb

打開 Kibana 的頁面
image

Kibana 已經建立了'logstash- *' 索引是標識,按下「建立」按鈕,可在 Kibana 中看到日誌。

結語

Docker 日誌記錄沒有完美的方案,不管選擇什麼解決方案,使用日誌記錄驅動程序, Filebeat 仍是 SaaS 監控平臺,每一個方案都有優缺點。

值得一提的是, Docker 日誌頗有用,但它們只表明由 Docker 主機生成的數據的一個維度,檢索容器統計信息和守護程序事件等還須要額外的日誌記錄層。

綜上所述, Logz.io 日誌收集器提供了一個全面的日誌解決方案,將三個數據流一塊兒拉到 ELK 中。如需統計數據,建議嘗試一下 Dockerbeat.

本系列的下一部分將重點介紹如何在 Kibana 中分析和可視化 Docker 日誌。

Docker 生日快樂!

Daniel Berman 是 Logz.io 產品經理。擅長日誌分析、大數據、雲計算,熱愛家庭,喜歡跑步,Liverpool FC 和寫顛覆性的技術內容。

原文連接: https://logz.io/blog/docker-l...

相關文章
相關標籤/搜索