1. Docker日誌收集流程
基本思路通過logstash獲取docker中的日誌,然後,將日誌轉發給elasticsearch進行索引,kibana分析和視覺化。獲取docker中的日誌檔案可以有多種方式:
- 新增一個MQ或者Redis作為docker容器和logstash的中間層,docker中的服務將日誌傳輸到中間層,然後,logstash從中間獲取
- 使用工具獲取docker中的日誌,例如:filebeat,logspout,log-pilot;但是不建議在每個伺服器上安裝logstash,因為logstash執行會佔有大量的伺服器資源,增加伺服器壓力。
- filebeat的配置好像相對比較複雜,沒有具體瞭解;
- logspout 可以獲取docker的stdout日誌
- log-pilot 是阿里開源的日誌工具,可以處理stdout和日誌檔案
本文中主要使用logspout.
2. Logspout+ELK收集日誌
2.1 Docker安裝ELK
- 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
- 配置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"
複製程式碼
- 安裝ELK映象
使用docker-compose build
命令構建映象; 構建過程可能會失敗,需要重複幾次; 執行使用docker-compose up -d
2.2 安裝logspout
- 其他機器上安裝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;
- 介面檢視
訪問:http://kibana宿主機ip:5601/ 可以看到kibana介面;
首次訪問,需要建立一個index: 如果elasticsearch中有索引將會如下圖所示,index-name輸入框填寫logstash-*,然後點選Next step
按鈕,選擇下拉框中的@timestamp
,然後,點選建立索引,之後,點選選單欄中的Discover
將會看到有日誌資訊:(ps:不同的版本,看到的介面可能會不一樣) - 指定需要收集的容器 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