我們在k8s部署服務時,一般來說一個服務會對應一類pod,而pod通過rs實現副本集,而這些pod的日誌一般有控制台stdout和文件的,一般會把這些日誌最終輸出到elasticsearch里,再通過kabana進行分析,而在實現由pod到elasticsearch(es)時有多種方法,下麵我列舉一 ...
我們在k8s部署服務時,一般來說一個服務會對應一類pod,而pod通過rs實現副本集,而這些pod的日誌一般有控制台stdout和文件的,一般會把這些日誌最終輸出到elasticsearch里,再通過kabana進行分析,而在實現由pod到elasticsearch(es)時有多種方法,下麵我列舉一下:
- 直接從標準控制台 stdout中通過fluentd進行收集,再存到es( 早期docker有實現)
- 通過logback里的fluentd包,直接把日誌輸出到fluentd,再存到es
- 在k8s里,可以為pod添加一個邊車(邊鬥,sidecar),這個邊車主要是fluentd插件,從容器日誌文件里讀取日誌,收集到es
從上面的解析可以看到第1種如果你是docker swarm環境可以使用,而第2種與業務代碼耦合太緊也不合適,只有第三種是未來的趨勢,目前大都是使用這種方式!
實現方式
1 sidecar的fluentd的mapconfig
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: saas
data:
fluentd.conf: |
<source>
type tail
format none
path /var/log/*.log
pos_file /var/log/log.pos
tag saas
</source>
<match **>
@id elasticsearch
@type elasticsearch
@log_level debug
index_name fluentd
type_name _doc
host elasticsearch.elk
port 9200
include_tag_key true
tag_key @log_name
logstash_format true
flush_interval 10s
</match>
運行
kubectl create -f fluentd-config-sidecar.yaml
測試一個pod,像容器輸出日誌到目錄,定時反覆輸出
apiVersion: v1
kind: Pod
metadata:
labels:
example: logging-sidecar
name: logging-sidecar-example
spec:
containers:
- name: synthetic-logger
image: 172.17.0.22:8888/saas/hello-world:latest
command: ["bash", "-c", "i=\"0\"; while true; do echo \"`hostname`: $i \" >> /var/log/1.log; date --rfc-3339 ns >> /var/log/1.log; sleep 4; i=$[$i+1]; done"]
volumeMounts:
- name: varlog
mountPath: /var/log
- name: sidecar-log-collector
image: registry.cn-beijing.aliyuncs.com/k8s-mqm/fluentd-elasticsearch:v2.1.0
env:
- name: FLUENTD_ARGS
value: -c /etc/fluentd-config/fluentd.conf
volumeMounts:
- name: varlog
mountPath: /var/log
- name: config-volume
mountPath: /etc/fluentd-config
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config
部署它
kubectl create -f fluentd-demo.yaml
然後去你的kabana里查看日誌,可以按著@log_name欄位去查詢,這就是我們日誌里的tag,這個我們可以在代碼里配置,可以設置成一個namespace,這樣方便日誌的跟蹤!