第 42 篇 k8s之日志管理:使用 EFK 或 Loki 采集日志
发布时间:2026/6/5 23:56:08
分类:文化教育
浏览:1234

IT策士 10余年一线大厂经验专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章助你少走弯路。在第 41 篇中我们用 Prometheus Grafana 搭建了监控体系。监控告诉我们“集群出问题了”——某个 Pod 的 CPU 飙升、某个 Deployment 的请求延迟突然变高。但接下来你一定会问为什么是代码逻辑错误、数据库连接池耗尽、还是外部 API 超时答案藏在日志里。在 Docker 时代docker logs查看单个容器的日志就够了。在第 6 篇中我们甚至配置了日志轮转策略来防止日志文件撑爆磁盘。但在 Kubernetes 集群中几十个 Pod 分散在多台节点上Pod 随时可能被删除重建滚动更新、节点故障、资源驱逐容器内的日志会随之消失。你不可能 SSH 到每台节点上tail -f日志文件——你需要一个集中式日志系统。今天这篇我们从容器日志的短暂性讲起对比 EFK 和 Loki 两种主流的日志方案最终用 Loki 为贯穿案例的 Flask 应用构建一个轻量、高效的日志聚合系统。一、为什么需要集中式日志Kubernetes 中容器的 stdout/stderr 输出由容器运行时containerd/docker捕获写入节点上的临时文件。这些日志的生命周期与 Pod 绑定——Pod 被删除后kubelet 会清理这些日志文件。即使你为 Pod 挂载了持久化卷来保存日志当应用有 10 个副本时你需要查看 10 个 Pod 的日志才能找到某一个错误。集中式日志系统的核心价值就是聚合将所有 Pod、节点的日志汇聚到一个地方一处查询全局日志。持久化日志独立于 Pod/容器的生命周期Pod 重建后日志依然可查。搜索与分析通过标签Pod 名、命名空间、容器名快速过滤通过关键词搜索定位错误。可视化结合 Grafana 在同一平台查看监控指标和日志形成完整的可观测性闭环。二、方案选型EFK vs LokiKubernetes 生态中最主流的两种日志方案是 EFKElasticsearch Fluentd Kibana和 Loki Promtail。2.1 EFK 栈EFK 是日志领域的经典组合三个组件分工明确Elasticsearch分布式搜索引擎用于存储和索引日志。它会对日志内容做全文分词索引使搜索速度极快但代价是资源消耗极高——CPU、内存、磁盘 IO 都很大。Fluentd日志采集器以 DaemonSet 形式部署在每个节点上收集容器日志并发送到 Elasticsearch。它支持丰富的插件生态和强大的日志处理解析、过滤、转换能力。Kibana数据可视化界面提供丰富的仪表板、图表和查询功能。EFK 的典型场景是大规模、对全文搜索要求高的生产环境比如需要每秒处理数万条日志或日志分析团队需要对日志内容做复杂的聚合查询。2.2 Loki PromtailLoki 是 Grafana Labs 推出的轻量级日志聚合系统设计理念与 Prometheus 一脉相承Loki类似 Prometheus但不索引日志内容只索引元数据标签Pod 名、命名空间、容器名。这使得它的资源消耗远低于 Elasticsearch运维复杂度也大大降低。Promtail日志采集代理以 DaemonSet 形式部署在每个节点上收集日志并推送给 Loki。它自动为日志附加 Kubernetes 元数据标签Pod 名、命名空间、标签等。Grafana与监控使用同一套 Grafana无需额外维护可视化工具。你可以把监控仪表板和日志查询面板放在同一页面上排查问题时在指标和日志间无缝切换。Loki 的典型场景是资源敏感、追求轻量和简洁的中小规模集群或者已经使用了 Prometheus Grafana 技术栈的团队。2.3 选型决策对于我们的贯穿案例来说Loki 是更合适的选择——轻量、与 Prometheus Grafana 技术栈天然集成且 Minikube 单节点环境资源有限。三、Loki 的架构与核心概念Loki 的架构与 Prometheus 高度相似如果你理解了第 41 篇的 PrometheusLoki 的概念几乎可以 1:1 映射Loki 的查询语言LogQL由两部分组成日志流选择器{appflask-counter, namespacedefault}选择特定的日志流日志管道| ERROR包含关键词、! DEBUG排除关键词、| json解析 JSON 格式日志四、部署 Loki Promtail我们将使用 Helm Chart 来部署 Loki Stack包含 Loki 和 Promtail。4.1 添加 Grafana 仓库并安装# 添加 Grafana 官方 Helm 仓库helm repoaddgrafana https://grafana.github.io/helm-charts helm repo update# 安装 Loki Stack包含 Loki 和 Promtailhelm upgrade--installloki grafana/loki-stack\--namespacelogging --create-namespace\--setloki.auth_enabledfalse\--setpromtail.config.snippets.extraScrapeConfigs[ { job_name: flask-logs, kubernetes_sd_configs: [{role: pod}], relabel_configs: [ { source_labels: [__meta_kubernetes_pod_label_app], action: keep, regex: flask-counter } ] } ]参数说明loki.auth_enabledfalse开发环境关闭认证简化配置promtail.config.snippets.extraScrapeConfigs额外的日志采集配置只采集带有appflask-counter标签的 Pod 日志减少噪音数据4.2 验证部署kubectl get pods-nlogging输出NAME READY STATUS RESTARTS AGE loki-01/1 Running030s promtail-xxxxx1/1 Running030sloki-0Loki 实例负责接收和存储日志Minikube 单节点使用 StatefulSet 以便持久化promtail-xxxxxPromtail DaemonSet每个节点上运行一个自动采集所有容器的日志五、在 Grafana 中查询日志5.1 添加 Loki 数据源访问 Grafana第 41 篇已部署默认通过kubectl port-forward -n monitoring svc/monitoring-grafana 3000:80访问。左侧菜单 →Connections→Data Sources→Add data source→ 搜索Loki。URL 填写http://loki.logging:3100因为 Loki 部署在logging命名空间Grafana 在monitoring命名空间需跨命名空间 DNS 解析。点击Save Test应显示绿色成功提示。5.2 查询 Flask 应用日志在 Grafana 左侧菜单点击Explore选择 Loki 数据源输入查询{appflask-counter,namespacedefault}点击Run query你会看到 Flask 应用的实时日志流。每条日志都标注了时间戳和来源 Pod 名称。过滤包含错误关键词的日志{appflask-counter}|ERROR排除健康检查请求的日志减少噪音{appflask-counter}!/health使用正则表达式匹配{appflask-counter}|~(?i)error|exception|fail5.3 查看 Redis 日志{appredis,namespacedefault}现在你可以从 Redis 日志中看到连接请求、数据持久化RDB/AOF状态、内存使用报告等信息。六、实战模拟错误并排查现在我们把日志系统真正用起来——模拟一个生产故障并追踪定位。6.1 制造错误# 进入 Flask 容器手动触发一个错误kubectlexecdeploy/flask-deployment --curl-XPOST http://localhost:5000/nonexistent应用代码中没有/nonexistent端点Flask 会返回 404 错误并在日志中记录这个错误请求。6.2 在 Loki 中定位错误回到 GrafanaExplore使用 LogQL 查询{appflask-counter}|404你会看到类似如下的日志行2025-05-2710:15:3010.244.1.25 - -[27/May/2025:10:15:30 0000]POST /nonexistent HTTP/1.1404-同时可以查询同一时间段内该 Pod 的所有请求日志分析在错误发生前后是否有异常{appflask-counter,podflask-deployment-xxxxxxxx-xxxxx}6.3 结合监控指标与日志可观测性闭环这是 Loki 与 Grafana 同平台的最大优势——你可以在一个页面上同时看到监控指标和对应时间段的日志在Explore中打开 Loki 查询输入{appflask-counter} | ERROR。点击Split按钮在右侧面板选择 Prometheus 数据源。输入rate(flask_http_request_total{status404}[5m])查看 404 错误请求的速率趋势。如果指标显示 10:15 左右 404 速率突然升高日志面板中同时段会显示对应的错误日志详情——指标告诉你“发生了什么”日志告诉你“为什么会发生”。七、日志轮转与保留策略Loki 默认使用本地存储Minikube 环境。生产环境建议使用对象存储S3、GCS来持久化日志并配置保留策略。在values.yaml中配置loki: persistence: enabled:truesize: 10Gi config: table_manager: retention_deletes_enabled:trueretention_period: 168h# 保留 7 天这比 Docker Compose 时代手动配置max-size: 10m, max-file: 3的日志轮转更加集中化和可管理——你不再需要逐个容器配置日志轮转而是在日志聚合层统一控制保留策略。八、对比 Docker Compose 的日志管理从 Docker Compose 到 K8s Loki日志管理从“本地、分散、手动”演进到“集中、聚合、可检索”。在第 6 篇学到的docker logs -f --tail 50和日志轮转配置在 Loki 中变成了{appxxx} | ERROR和统一的retention_period。九、命令速查表十、本篇总结集中式日志的必要性Pod 日志是短暂的必须聚合到外部系统才能持久化和检索。kubectl logs只是临时调试工具不是日志管理的最终方案。EFK vs LokiEFK 功能强大但资源消耗高适合大规模全文搜索场景Loki 轻量、与 Grafana 原生集成适合已采用 Prometheus 技术栈的团队。Loki 实战部署了 Loki Promtail在 Grafana 中添加 Loki 数据源通过 LogQL 查询 Flask 和 Redis 日志。指标和日志在同一平台展示从“发现问题”到“定位原因”只需一次界面切换。日志与监控的闭环Prometheus 告诉你“Pod 在频繁重启”Loki 告诉你“因为数据库连接超时”。两者结合才能真正做到快速排错。下一篇——第 43 篇集群网络策略NetworkPolicy 入门我们将学习如何通过 NetworkPolicy 实现 Pod 间的网络隔离为微服务集群加上一道关键的网络安全防线。想了解更多还可以去各个平台搜索「IT策士」一起升级 IT 思维