ELK+logspout收集Docker日誌

SachinLea發表於2019-03-04

1. Docker日誌收集流程

在這裡插入圖片描述
  基本思路通過logstash獲取docker中的日誌,然後,將日誌轉發給elasticsearch進行索引,kibana分析和視覺化。
  獲取docker中的日誌檔案可以有多種方式:

  1. 新增一個MQ或者Redis作為docker容器和logstash的中間層,docker中的服務將日誌傳輸到中間層,然後,logstash從中間獲取
  2. 使用工具獲取docker中的日誌,例如:filebeat,logspout,log-pilot;但是不建議在每個伺服器上安裝logstash,因為logstash執行會佔有大量的伺服器資源,增加伺服器壓力。
    • filebeat的配置好像相對比較複雜,沒有具體瞭解;
    • logspout 可以獲取docker的stdout日誌
    • log-pilot 是阿里開源的日誌工具,可以處理stdout和日誌檔案

  本文中主要使用logspout.

2. Logspout+ELK收集日誌

2.1 Docker安裝ELK

  1. logstash配置檔案
input {
	tcp {
		port => 5000
		type => syslog
		codec => json
	}
	udp {
		port => 5000
		type => syslog
	}
	file {
	    codec => json
	    path => "/opt/build/*.json"-->
	}
}

filter {
	grok {
        match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
    }
}

output {
    elasticsearch { hosts => ["elasticsearch:9200"] }
    stdout { codec => rubydebug }
}
複製程式碼

配置解釋:logstash配置分為三個部分:

  • input: 輸入,也就是檔案輸入流,可以通過tcp,udp推送,或者到只能目錄獲取,其中file的配置,就是讀取指定目錄的內容(這裡可以不配置);配置tcp因為不同機器上的logspout需要通過tcp推送日誌;
  • filter: 過濾;gork將非標準化日誌轉化為標準化的
  • output:輸出,可以指定輸出的 index
  1. 配置elk的docker compose檔案
version: '3'
services:
 elasticsearch:
  image: elasticsearch:6.5.0
  # command: elasticsearch
  ports:
   - "9200:9200"   
   - "9300:9300"   
 logstash:
  image: logstash:6.5.0
  command: logstash -f /etc/logstash/conf.d/logstash.conf
  volumes:
   - ./config:/etc/logstash/conf.d
   - /opt/build:/opt/build
  ports:
   - "5001:5000"
 kibana:
  image: kibana:6.5.0
  environment:
   - ELASTICSEARCH_URL=http://elasticsearch:9200
  ports:
   - "5601:5601"
複製程式碼
  1. 安裝ELK映象
    使用docker-compose build命令構建映象; 構建過程可能會失敗,需要重複幾次; 執行使用docker-compose up -d

2.2 安裝logspout

  1. 其他機器上安裝logspout
version: "3"
networks:
  logging:
services:
  logspout:
    image: gliderlabs/logspout:latest
    networks:
      - logging
    volumes:
      - /etc/hostname:/etc/host_hostname:ro
      - /var/run/docker.sock:/var/run/docker.sock
    command:
      syslog+tcp://logstash的宿主機ip:5001
複製程式碼

其中,使用syslog+tcp的方式,將收集的日誌檔案推送到logstash;

  1. 介面檢視
    訪問:http://kibana宿主機ip:5601/ 可以看到kibana介面;
    首次訪問,需要建立一個index:
    在這裡插入圖片描述
    如果elasticsearch中有索引將會如下圖所示,index-name輸入框填寫logstash-*,然後點選Next step按鈕,選擇下拉框中的@timestamp,然後,點選建立索引,之後,點選選單欄中的Discover將會看到有日誌資訊:(ps:不同的版本,看到的介面可能會不一樣)
    在這裡插入圖片描述
    在這裡插入圖片描述
  2. 指定需要收集的容器 logspout預設收集所在主機的所有容器的日誌,但是,有時候我們只希望收集部分容器的日誌,有兩種方式可以解決:
  • 每個容器啟動時,新增環境變數LOGSPOUT=ignore,例如上邊ELK中的設定,官方例子:
docker run -d -e 'LOGSPOUT=ignore' image
// 或者
docker run -d --label logspout.exclude=true image
複製程式碼
  • logspout啟動時指定包含哪些容器,可以參考官方文件中介紹的方式:https://github.com/gliderlabs/logspout

我使用了第二種方式,將上邊logspout的docker-compose檔案修改,最後傳送訊息時增加 filter.name

command:
  syslog+tcp://172.16.52.23:5001?filter.name=*_monitor
複製程式碼

需要收集日誌的容器,啟動時需要設定字尾為_monitor的別名,即可監控該容器的日誌;

filter的其他引數:

// 指定容器id
filter.id=3b6ba57db54a
// 指定檔案
filter.sources=stdout%2Cstderr
// 標籤'a'以'x'開頭,標籤'b'以'y'結尾。
filter.labels=a:x*%2Cb:*y
複製程式碼

注意其中逗號的寫法;
如果有多個路由目的地,可以使用逗號分隔

docker run \
	--volume=/var/run/docker.sock:/var/run/docker.sock \
	gliderlabs/logspout \
	raw://192.168.10.10:5000?filter.name=*_db,syslog+tls://logs.papertrailapp.com:55555?filter.name=*_app
複製程式碼

參考

ELK+Filebeat 集中式日誌解決方案詳解
使用Docker Compose執行ELK
使用ELK處理Docker日誌(一)
https://github.com/gliderlabs/logspout
使用ELK收集Docker Swarm日誌
docker swarm叢集日誌管理ELK實戰
Docker 日誌收集新方案:log-pilot

相關文章