簡介
-
關於日志收集這個主題,這已經是第三篇了,為什么一再研究這個課題,因為這個課題實在太重要,而當今優秀的開源解決方案還不是很明朗;
-
就docker微服務化而言,研發有需求標准輸出,也有需求文件輸出,每次登錄到服務器上去查看日志又多有不妥;現有的解決方案ELK,每次收集新應用日志都要更改配置文件重新適配日志路徑足以讓我們崩潰;
-
對於k8s,沒有日志系統推行工作就無法進行,總不能讓開發小伙伴登錄到k8s上去找日志吧,鬼知道在哪個pod里;當然,k8s官方提供了解決方案efk,efk最大的問題就是無法對日志有效分組,所有日志都在一個索引里,影響查詢速度不說,對於研發小伙伴查找屬於自己應用的日志也很困難,不得不說,這個解決方案很雞肋;
-
綜上三條,能夠統籌普通應用、docker微服務、k8s的日志收集方案迫在眉睫,今天就將能解決這些問題的日志收集方案的最佳實踐分享給大家;
-
該實踐采用的是阿里雲的開源工具 log-pilot 采集日志,采集的過程中就將各種日志打標分類,類似最近比較火的垃圾分類,邏輯結構圖如下:
-
三種節點類型:
- k8s使用daemonset類型的副本集,使每個節點運行一個
log-pilot
來收集日志,該日志會含有k8s_container_name、k8s_pod、k8s_node_name、 k8s_pod_namespace
等打標數據,輸出到相應的logstash
來做索引 - 運行docker微服務的主機上運行一個
log-pilot
來收集日志,該日志會含有docker_container、topic、index
等打標數據,輸出到相應的logstash
來做索引 - 普通非容器程序的日志可以采用
filebeat
收集,日志中可以自定義標簽和字段,輸出到對應的logstash
來做索引
- k8s使用daemonset類型的副本集,使每個節點運行一個
log-pilot 說明和配置
- 容器日志采集模式現在流行的方式有 SideCar模式和 Node模式,SideCar模式會占用大量資源,而Node模式需要智能的
logging agent
配合,而log-pilot
就是那個智能的agent - log-pilot 可同時支持stdout和容器內文件日志采集,支持聲明式日志配置,同時擁有自動感知(發現)機制、自動checkpoint及具柄保持機制和自動日志數據打標
- log-pilot 除擁有上述功能,還支持多插件多后端,低消耗,高性能,具體情況請看 K8S 日志實踐
log-pilot 插件支持
log-pilot 工作模式
log-pilot 配置方法
- 在
Kubernetes
下,Log-Pilot
可以依據環境變量aliyun_logs_$name = $path
動態地生成日志采集配置文件,其中包含兩個變量:$name
是我們自定義的一個字符串,它在不同的場景下指代不同的含義,在本場景中,將日志采集到ElasticSearch
的時候,這個$name
表示的是Index
。- 另一個是
$path
,支持兩種輸入形式,stdout
和容器內部日志文件的路徑,對應日志標准輸出和容器內的日志文件。 - 第一種約定關鍵字
stdout
表示的是采集容器的標准輸出日志,如本例中我們要采集tomcat
容器日志,那么我們通過配置標簽aliyun.logs.catalina=stdout
來采集tomcat
標准輸出日志。 - 第二種是容器內部日志文件的路徑,也支持通配符的方式,通過配置環境變量
aliyun_logs_access=/usr/local/tomcat/logs/*.log
來采集 tomcat 容器內部的日志。當然如果你不想使用aliyun
這個關鍵字,Log-Pilot
也提供了環境變量PILOT_LOG_PREFIX
可以指定自己的聲明式日志配置前綴,比如PILOT_LOG_PREFIX: "aliyun,custom"
。
- 此外,
Log-Pilot
還支持多種日志解析格式,通過aliyun_logs_$name_format=<format>
標簽就可以告訴 Log-Pilot 在采集日志的時候,同時以什么樣的格式來解析日志記錄,支持的格式包括:none、json、csv、nginx、apache2
和regxp
。 Log-Pilot
同時支持自定義tag
,我們可以在環境變量里配置aliyun_logs_$name_tags="K1=V1,K2=V2"
,那么在采集日志的時候也會將K1=V1
和K2=V2
采集到容器的日志輸出中。自定義tag
可幫助您給日志產生的環境打上tag
,方便進行日志統計、日志路由和日志過濾。
log-pilot 在k8s上的配置
cat > ops-log-pilot-filebeat-ds.yaml << EOF
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: ops-log-pilot-filebeat-ds
namespace: ops
spec:
selector:
matchLabels:
app: log-pilot-filebeat
release: stable
template:
metadata:
labels:
app: log-pilot-filebeat
release: stable
spec:
containers:
- name: log-pilot-filebeat
image: registry.cn-hangzhou.aliyuncs.com/acs/log-pilot:0.9.6-filebeat
env:
- name: "NODE_NAME"
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: "PILOT_LOG_PREFIX"
value: "glinux"
- name: "LOGGING_OUTPUT"
value: "logstash"
# 請確保集群到ES網絡可達
- name: "LOGSTASH_HOST"
value: "logstash.glinux.top"
- name: "LOGSTASH_PORT"
value: "5053"
volumeMounts:
- name: sock
mountPath: /var/run/docker.sock
- name: root
mountPath: /host
readOnly: true
- name: varlib
mountPath: /var/lib/filebeat
- name: varlog
mountPath: /var/log/filebeat
- name: localtime
mountPath: /etc/localtime
readOnly: true
livenessProbe:
failureThreshold: 3
exec:
command:
- /pilot/healthz
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
securityContext:
capabilities:
add:
- SYS_ADMIN
volumes:
- name: sock
hostPath:
path: /var/run/docker.sock
- name: root
hostPath:
path: /
- name: varlib
hostPath:
path: /var/lib/filebeat
type: DirectoryOrCreate
- name: varlog
hostPath:
path: /var/log/filebeat
type: DirectoryOrCreate
- name: localtime
hostPath:
path: /etc/localtime
EOF
# 調用方法
kubectl apply -f ops-log-pilot-filebeat-ds.yaml
log-pilot 在docker主機上配置
docker run -d \
--name log-pilot-filebeat \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/localtime:/etc/localtime \
-v /:/host:ro \
--cap-add SYS_ADMIN \
-e PILOT_LOG_PREFIX=glinux \
-e LOGGING_OUTPUT=logstash \
-e LOGSTASH_HOST=logstash..glinux.top \
-e LOGSTASH_PORT=5063 \
--restart=always \
registry.cn-hangzhou.aliyuncs.com/acs/log-pilot:0.9.5-filebeat
logstash 配置方法
- logstash的三個實例,我是運行在同一台機器上,同時kibana也是運行在這台機器上
- 當然也可以通過一個logstash實例,配置中采用判斷條件建立不同索引,但會影響性能,所以這里我起了三個實例
- logstash的主要功能是將收集到的日志進行拆分,采用某些字段建成索引,傳遞給
elasticsearch
集群 - 這里強烈建議使用阿里雲的
elasticsearch
集群,可以先使用免費版1核2G內存20G SSD 三組
,原因是阿里雲和elastic有合作,es有授權,很多功能可以使用,比如用戶管理,監控等,后面會說到
logstash 處理k8s日志
- logstash 監控配置文件,監控信息會體現在kibana中
cat > /data/logslogstash.yml << EOF
xpack.monitoring.elasticsearch.url: http://xxxxxxxxxxxxxxxx.es.aliyuncs.com:9200
xpack.monitoring.elasticsearch.username: "user"
xpack.monitoring.elasticsearch.password: "pass"
EOF
配置文件
cat > /data/conf/logstash-k8s.conf << EOF
input {
beats {
host => "0.0.0.0"
port => "5043"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:log-timestamp} %{LOGLEVEL:log-level} %{JAVALOGMESSAGE:log-msg}" }
}
mutate {
# remove_field => ["message"]
remove_field => ["beat"]
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => ["http://xxxxxxxxxxxxxxxx.es.aliyuncs.com:9200"]
user => ["user"]
password => ["pass"]
index => "%{k8s_container_name}-%{+YYYY.MM.dd}"
}
}
EOF
啟動命令
docker run -p 5053:5043 -d \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name logstash-k8s \
--restart=always \
-v /data/conf/logstash-k8s.conf:/usr/share/logstash/pipeline/logstash.conf \
-v /data/conf/logstash.yml:/usr/share/logstash/config/logstash.yml \
logstash:6.6.2
logstash 處理docker日志
配置文件
cat > /data/conf/logstash-docker.conf << EOF
input {
beats {
host => "0.0.0.0"
port => "5043"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:log-timestamp} %{LOGLEVEL:log-level} %{JAVALOGMESSAGE:log-msg}" }
}
mutate {
# remove_field => ["message"]
remove_field => ["beat"]
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => ["xxxxxxxxxxxxxxxx.es.aliyuncs.com:9200"]
user => ["uesr"]
password => ["pass"]
index => "%{docker_container}-%{+YYYY.MM.dd}"
}
}
EOF
啟動命令
docker run -p 5063:5043 -d \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name logstash-docker \
--restart=always \
-v /data/conf/logstash-docker.conf:/usr/share/logstash/pipeline/logstash.conf \
-v /data/conf/logstash.yml:/usr/share/logstash/config/logstash.yml \
logstash:6.6.2
elasticsearch 說明
- 如上所述,elasticsearch 使用阿里雲的產品 阿里雲 · Elasticsearch
- 可以先使用免費版
1核2G內存20G SSD 三組
- 開通后會有 地址、用戶名、密碼等信息,這些是要填寫在logstash的輸出配置文件中
- 阿里雲和elastic有合作,es有授權,用戶管理、用戶登錄、索引監控、節點監控、logstash監控等功能均可正常使用
- 除以上外,定期清理es的索引也很有必要,可以參考我之前的博客 ELK:收集Docker容器日志 中 定時刪除過期日志索引文件 章節
- 使用阿里雲的es后,kibana上會有授權體現,這里貼兩張圖展示一下功能
kibana 的監控
kibana 的管理
kibana 說明和配置
- 下面步驟操作完畢啟動后,此處訪問
http://IP:5603
,用戶名和密碼同elasticserach
的,輸入即可登錄kibana,如此建立索引,就可以正常的玩耍了
kibana 配置文件
- 如下的配置文件會屏蔽掉許多沒用的插件功能模塊,如上圖顯示的清爽界面
cat > /data/conf/kibana-es-aliyun.yml << EOF
# Default Kibana configuration from kibana-docker.
server.name: kibana
server.host: "0"
elasticsearch.hosts: http://xxxxxx.es.aliyuncs.com:9200
elasticsearch.username: user
elasticsearch.password: pass
xpack.monitoring.ui.container.elasticsearch.enabled: true
timelion.enabled: false
console.enabled: false
xpack.grokdebugger.enabled: false
xpack.searchprofiler.enabled: false
xpack.canvas.enabled: false
xpack.ml.enabled: false
xpack.infra.enabled: false
xpack.apm.enabled: false
xpack.graph.enabled: false
EOF
kibana 啟動命令
docker run -p 5603:5601 -d \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name kibana-es-aliyun \
--restart=always \
-e ELASTICSEARCH_URL=http://xxxxxx.es.aliyuncs.com:9200 \
kibana:6.6.2
- 下面來看下優秀的登錄界面
日志收集效果驗證
docker日志收集案例 tomcat
- 注意
label
的配置
docker run -it -d --name tomcat -p 10080:8080 \
-v /var/logs/:/usr/local/tomcat/logs \
--label glinux.logs.catalina=stdout \
--label glinux.logs.access=/usr/local/tomcat/logs/localhost_access_log.*.txt \
tomcat
- 日志收集效果如下圖:
k8s日志收集案例 tomcat
- 注意env的配置
cat > tomcat-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: tomcat
spec:
containers:
- name: tomcat
image: "tomcat:7.0"
env:
# 1、stdout為約定關鍵字,表示采集標准輸出日志
# 2、配置標准輸出日志采集到ES的catalina索引下
- name: glinux_logs_catalina
value: "stdout"
# 1、配置采集容器內文件日志,支持通配符
# 2、配置該日志采集到ES的access索引下
- name: glinux_logs_access
value: "/usr/local/tomcat/logs/catalina.*.log"
# 容器內文件日志路徑需要配置emptyDir
volumeMounts:
- name: tomcat-log
mountPath: /usr/local/tomcat/logs
volumes:
- name: tomcat-log
emptyDir: {}
EOF
# 調用
kubectl apply -f tomcat-pod.yaml -n ops
- 日志收集效果如下圖:
參考文檔
- 在阿里,我們是怎么做 K8S 日志實踐: https://toutiao.io/posts/k0qse0/preview
- 利用 Log-Pilot + Elasticsearch + Kibana 搭建 kubernetes 日志解決方案: https://help.aliyun.com/document_detail/86552.html
- log-pilot filebeat說明文檔: https://github.com/AliyunContainerService/log-pilot/blob/master/docs/filebeat/docs.md
- json格式化在線:https://www.bejson.com
- visual-paradigm:https://online.visual-paradigm.com/w/odyqcwvx/diagrams.jsp#diagramlist:proj=0&new=BubbleDiagram