K8s之Pod日志收集新贵Loki初体验
大多数的伙伴已经熟悉了EFK和Filebeat的使用,实际上无论是Filebeat还是Fluentd,都是将数据存储在Elasticsearch集群,之后用Kibana进行查询,所以为了查看日志,我们不得不去搭建一个Elasticsearch集群,但Elasticsearch集群本身的维护很麻烦,也比较消耗资源,如果不想大费周章地去维护ELK技术栈,那么Loki将是一个很好的选择。本文我们在Kubernetes集群中搭建一个Loki Stack,用于收集集群内Pod的日志。
一、安装Loki Stack
Loki提供了Helm的安装方式,可以直接下载包进行安装,首先添加并更新Loki的Helm仓库:
"grafana" has been added to your repositories
Hang tight while we grab the latest from your chart repositories...
...
...Successfully got an update from the "grafana" chart repository
创建Loki Namespace:
namespace/loki created
创建Loki Stack:
# helm upgrade --install loki grafana/loki-stack --set grafana.enabled=true --set grafana.service.type=NodePort -n loki
NAME: loki
NAMESPACE: loki
STATUS: deployed
REVISION: 1
NOTES:
The Loki stack has been deployed to your cluster. Loki can now be added as a datasource in Grafana.
See http://docs.grafana.org/features/datasources/loki/ for more detail.
上述安装携带了Grafana,如果公司已经有Grafana,可以不用安装,添加一个Loki的源即可。安装时,没有开启Loki的数据持久化,如果需要保留数据,需要配置动态存储,然后配置StorageClass即可,另外Loki只部署了一个副本,真正使用时需要3个以上的实例。
查看Pod的状态:
# kubectl get po -n loki
NAME READY STATUS RESTARTS AGE
loki-0 1/1 Running 0 4m23s
loki-grafana-5b57955f9d-48z6l 1/1 Running 0 4m23s
loki-promtail-2n24m 1/1 Running 0 4m23s
loki-promtail-59slx 1/1 Running 0 4m23s
loki-promtail-6flzq 1/1 Running 0 4m23s
loki-promtail-gq2hk 1/1 Running 0 4m23s
loki-promtail-sqwtv 1/1 Running 0 4m23s
查看Grafana的Service暴露的端口号:
# kubectl get svc -n loki
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
loki ClusterIP 192.168.67.18 <none> 3100/TCP 7m54s
loki-grafana NodePort 192.168.103.121 <none> 80:31053/TCP 7m54s
loki-headless ClusterIP None <none> 3100/TCP 7m54s
之后通过任意一个安装了kube-proxy节点的IP加上31053即可访问Grafana,如图1所示。
图1 访问Grafana
查看Grafana密码(账号为admin):
"{.data.admin-password}" | base64 --decode ; echo kubectl get secret --namespace loki loki-grafana -o jsonpath=
eD47DAbzhyPLgDeSM8C0LvBi3DksU73vZND8t4h0
登录后,按图2所示单击即可查看Loki语法指南。
图2 访问Explore
其他安装配置可以参考:https://grafana.com/docs/loki/latest/installation/helm/。
二、Loki语法入门
Loki是参考Prometheus设计的,所以查询语法和PromQL类似,比如查询命名空间为kube-system下的所有Pod的日志,只需要在Log browser中输入{namespace="kube-system"},然后单击Run query即可,如图3所示。
图3 查询日志
最下方为日志详情,如图4所示。
图4 日志详情
可以看到每条日志都被添加了很多标签,之后可以通过标签过滤日志,比如查看命名空间为kube-system且Pod名称包含calico的日志(下面的语法将不再提供截图,读者可以自行测试):
{namespace="kube-system", pod=~"calico.*"}
相当于=~,类似的语法还有:
l =~:正则模糊匹配。
l =:完全匹配。
l !=:不等于。
l !~:正则模糊不等于。
Loki语法同时支持Pipeline,比如需要过滤日志包含avg字段的日志:
{namespace="kube-system", pod=~"calico.*"} |~ "avg"
查询到的日志如图5所示。
图5 AVG过滤后的日志
还可以使用logfmt对日志进行格式化,然后进行值的判断,比如找到包含avg字段并且longest的值大于16ms的日志:
{namespace="kube-system", pod=~"calico.*"} |~ "avg" | logfmt | longest > 16ms
得到的日志如图6所示,和上一个结果相比,只有longest大于16ms的日志,其他的均已被过滤掉。
图6 longest过滤后的日志