在现代服务器运维中,Kubernetes(简称K8s)成了部署应用的标配。但随着服务被拆成一个个小容器跑在不同节点上,传统的查看日志方式就不太灵了。以前直接ssh进机器看log文件就行,现在Pod可能几分钟就重启一次,IP也变来变去,日志往哪找?这时候就得靠一套靠谱的日志管理方案。
为什么K8s日志不好管?
想象一下,你家楼下有家快餐店,厨师、打包员、送餐员各司其职。如果顾客投诉说饮料洒了,老板得知道是哪个环节出的问题。但在K8s里,服务像流水线上的工人一样动态调度,今天这个Pod干活,明天可能就被新实例替换。如果不集中收集日志,排查问题就像大海捞针。
主流方案:EFK组合
目前最常见的解法是EFK——Elasticsearch + Fluentd + Kibana。Fluentd作为日志采集器,部署在每个节点上,自动抓取容器的标准输出和日志文件;Elasticsearch负责存储和索引;Kibana提供可视化界面,能按服务名、时间、关键字快速筛选。
比如你在测试环境发现某个订单服务报错频繁,打开Kibana输入service: order-service level: error,几秒钟就能定位到具体错误堆栈。
如何部署Fluentd?
一般通过DaemonSet确保每个节点都运行一个Fluentd Pod。配置YAML大致如下:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-logging
namespace: kube-system
spec:
selector:
matchLabels:
name: fluentd-logging
template:
metadata:
labels:
name: fluentd-logging
spec:
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.14
volumeMounts:
- name: varlog
mountPath: /var/log
- name: containerlogs
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: containerlogs
hostPath:
path: /var/lib/docker/containers
结构化日志更省心
建议应用输出JSON格式日志,比如{"time":"2024-04-05T10:00:00","level":"error","msg":"db timeout"}。这样Fluentd可以直接解析字段,查询时就能用level:error而不是全文模糊匹配,效率高很多。
资源控制别忽视
日志采集本身也会消耗CPU和磁盘。曾见过一个案例,某团队没设限,日志量暴增导致节点磁盘写满,Kubelet直接OOM。建议给Fluentd设置资源request和limit,并开启日志轮转。
替代选择:Loki轻量登场
如果你觉得Elasticsearch太重,可以试试Grafana Loki。它专为日志设计,存储成本低,查询语法和Prometheus接近,适合已有Grafana监控体系的团队。搭配Promtail采集,配置简单,几百个Pod的集群跑起来毫不吃力。
无论选哪种方案,核心思路都是:统一采集、集中存储、快速检索。毕竟出问题时,谁能最快看到日志,谁就能最快恢复服务。