容器日志聚合的工作原理
容器日志聚合简化了从生命周期较短的容器收集和组织日志到单个集中式系统中的过程。. 这个过程至关重要,因为容器化环境会产生海量的日志,而且容器经常会迅速消失,日志也会随之消失。如果没有日志聚合,故障排除就会变得效率低下且支离破碎。.
以下是您需要了解的内容:
- 容器将日志记录到流(STDOUT/STDERR),而不是文件。. 除非日志被路由到外部系统,否则当容器停止运行时,日志将消失。.
- 托管 Kubernetes 将日志集中在节点级别。. 像 kubelet 这样的工具负责处理日志轮换,而像 这样的路径
/var/log/pods/临时存储日志。. - 收集方法包括节点级代理和边车。. 节点代理(例如 Fluent Bit)对于集群范围的日志非常有效,而 sidecar 则适用于具有自定义日志格式的应用程序。.
- 集中式存储确保数据持久性。. 日志会被发送到 Elasticsearch 或 Loki 等平台进行查询、分析和长期保存。.
为什么重要: 集中管理日志可以通过实现结构化搜索和实时监控来缩短故障排除时间。为避免日志丢失,请始终将其定向到标准流,并使用可靠的基础设施进行存储和传输。.
为了实现可扩展的部署,可以将节点级代理与 Kafka 或 Elasticsearch 等强大的存储后端相结合。这样即使在高容量环境下,也能确保日志的可访问性和有序性。.
容器日志聚合管道:从生成到存储
Kubernetes 日志聚合:收集集群级日志 | 完整指南

sbb-itb-59e1987
容器如何生成日志
容器使用流而非静态文件来生成日志。容器中的每个进程都使用源自 Unix 的三种 I/O 流: 标准输入 (流 0)用于输入,, 标准输出 (流 1)用于标准输出,以及 标准错误输出 (流 2)用于错误消息。.
应用程序运行时,它会将运行数据和状态更新发送到 标准输出, 而错误、警告和诊断信息则会发送到 标准错误输出. 容器运行时(无论是 Docker、Containerd 还是其他符合 CRI 标准的工具)直接从容器化进程捕获这些流。这是通过管道实现的,管道将容器隔离环境的输出重定向到…… 虚拟专用服务器 主机文件系统。.
"对于容器化应用程序来说,最简单且最常用的日志记录方法是写入标准输出和标准错误流。"——Kubernetes 文档
切勿将日志保存在容器的可写层中。一旦容器停止或被移除,其内部的所有内容(包括所有日志文件)都会消失。为避免丢失日志,应用程序必须将所有日志记录路由到其他位置。 标准输出 和 标准错误输出. 对于将日志写入文件的旧版应用程序,您可以创建指向这些文件的符号链接。 /dev/stdout 要么 /dev/stderr.
现在,让我们来探讨一下这些输出流是如何被捕获和管理的。.
容器日志输出流
容器运行时不仅会捕获日志,还会格式化和管理日志。当 Docker 或 Containerd 从以下位置接收数据时: 标准输出 要么 标准错误输出, 一个名为 垫片 处理该日志。Shim 读取输出,添加元数据,并将其写入主机日志文件。这种设置确保即使容器生命周期很短,日志数据也能得到保留。.
Docker 使用 日志驱动程序 确定日志的存储方式和位置。默认值 json文件 驱动程序将日志以 JSON 格式保存到主机磁盘上。每条日志条目都包含时间戳、源流(标准输出或标准错误)以及日志消息本身。为了防止在高输出量期间出现性能问题,Docker 提供了一种非阻塞模式。此模式为每个容器使用 1MB 的缓冲区来防止阻塞,但这也意味着如果缓冲区已满,则可能会丢弃一些消息。.
| 流名称 | 文件描述符 | 目的 |
|---|---|---|
| 标准输入 | 0 | 输入 |
| 标准输出 | 1 | 标准输出 |
| 标准错误输出 | 2 | 错误信息 |
了解两者之间的区别 标准输出 和 标准错误输出 对于过滤和警报至关重要。因为 标准错误输出 通常会突出显示错误或警告,监控工具可以配置为基于此信息流发送警报,同时进行处理 标准输出 作为信息性信息。然而,如果这些流由于反压而阻塞,应用程序可能会遇到问题。Docker 的非阻塞模式可以缓解这个问题,但代价是可能会丢失新的日志消息。.
虽然容器运行时可以处理基本的日志记录,但 Kubernetes 更进一步,提供了节点级管理策略。.
Kubernetes 日志管理
在 Kubernetes 中, kubelet 负责管理日志。它决定日志在每个节点上的存储位置,并强制执行轮换策略以防止磁盘空间耗尽。默认情况下,Kubernetes 将容器日志保存在以下路径:
/var/log/pods/{namespace}_{pod-name}_{pod-uid}/{container-name}/{restart-count}.log.
此外,它还在以下位置创建符号链接: /var/log/containers/ 便于人机访问和日志收集工具使用。.
Kubernetes 会在日志大小达到 10MiB 时进行轮换,每个容器最多保留五次轮换记录。例如,一个包含三个容器的 Pod 将有三组独立的日志文件。当您运行 kubectl 日志, kubelet 直接从节点的存储中检索这些文件。.
"Shim 的职责包括:读取容器进程的 stdout/stderr 输出……格式化日志……直接写入日志文件。——张亚东,CNCF 大使
kubelet 与容器运行时之间的集成遵循容器运行时接口 (CRI) 日志格式。该标准确保 Kubernetes 能够以一致的方式处理日志,无论使用的是 Docker、Containerd、CRI-O 还是其他选项。从 Kubernetes v1.32 开始,新增了一项名为“ PodLogsQuerySplitStreams 允许您查询 标准输出 和 标准错误输出 通过 Pod API 分别传输日志流。这样,您可以更好地控制要访问的日志流。.
这些机制确保 Kubernetes 能够为集中式系统提供结构化、可靠的日志数据。.
日志收集方法
当容器将日志写入节点的文件系统时,您需要一种可靠的方法来收集集群中的这些日志。主要有两种方法: 节点级代理 为了实现高效的集群级日志处理, 边车集装箱 针对特定应用需求。每种方法都根据您的设置和要求提供独特的优势。.
节点级日志代理
使用节点级日志代理需要通过 Kubernetes 在每个节点上部署日志工具。 守护进程集. 这样就确保每个工作节点上都有一个运行 Fluentd 或 Fluent Bit 等工具的代理 pod。这些代理会挂载类似这样的目录。 /var/log/pods 要么 /var/log/containers, 直接访问存储在主机上的容器日志。.
"节点级代理,例如 Fluentd 守护进程集。这是推荐的模式。"——AWS 原生可观测性指南
该代理持续监控日志文件,并使用 Kubernetes 元数据(例如,pod 名称、命名空间、容器名称和标签)丰富日志文件,以便更容易在 Elasticsearch 或 OpenSearch 等集中式存储系统中搜索日志。. Fluent Bit 由于其轻巧的设计和极低的资源消耗,它是该角色的热门选择。.
为了优化性能,请将代理配置为 在源端过滤日志. 在节点级别丢弃不必要的日志可以减少网络流量和存储成本。设置内存缓冲区限制(例如,, 内存缓冲区限制 在 Fluent Bit 中)以防止在日志峰值或后端中断期间内存使用过高。对于大型集群,配置代理以从 kubelet 本地检索元数据(使用 Kubelet) 而不是查询 Kubernetes API 服务器,这有助于避免 API 速率限制。.
| 特征 | 节点级代理(守护进程集) | 边车集装箱 |
|---|---|---|
| 资源使用情况 | 低(每个节点一个代理) | 高(每个舱段一个代理) |
| 应用程序修改 | 无需 | 需要修改烟弹规格 |
| 可扩展性 | 高的 | 中等(增加舱体占地面积) |
| 最佳用例 | 集群范围的日志处理 | 具有自定义日志格式的应用程序 |
kubectl 日志 支持 | 完全支持 | 不支持代理处理的日志 |
该方法提供了一种可扩展且高效的方式来收集集群中的日志,而无需修改单个应用程序。.
用于收集原木的边车式集装箱
Sidecar 容器提供了一种更加定制化的方法,尤其适用于应用程序直接将日志记录到文件的情况。 边车集装箱 它与主应用程序容器在同一 pod 内并行运行,共享存储和网络命名空间。这种设置非常适合将日志写入文件的应用程序,而不是直接写入磁盘。 标准输出 要么 标准错误输出, 尤其是在处理 Java 多行日志等复杂格式时,节点级代理可能难以处理。.
"当从容器日志中处理日志的效率不如直接从应用程序读取日志(例如,Java 多行处理)时,边车/代理模型就非常有用。"——Anurag Gupta,Fluent Bit
在此模型中,应用程序将日志写入共享卷(通常是 Kubernetes 卷)。 空目录),而边车容器会跟踪这些日志,并将它们转发到集中式后端。Fluentd、Fluent Bit 和 Filebeat 等工具通常用作边车容器。从 Kubernetes v1.29 开始,原生边车支持允许您将边车定义为可重启的初始化容器。 重启策略:始终, 确保它们在主容器之前启动,并在主容器终止后停止。.
虽然边车可以实现精确的日志处理,但它们也会带来更高的资源成本。每个 Pod 都运行着自己的日志代理,如果边车将日志流式传输到其他位置,则存储需求可能会翻倍。 标准输出. 为了最大限度地减少开销,仅对无法直接记录到标准流的应用程序使用边车,并确保边车容器尽可能轻量级。.
日志集中化和传输
在了解了日志的生成和收集之后,我们来详细探讨一下日志的集中化和传输方式。日志收集完成后,需要存储在一个可靠的存储库中,该存储库能够承受 Pod 重启和节点故障。这个过程通常涉及使用缓冲层来处理突发的流量高峰,以及一个专为快速查询而设计的远程存储系统。接下来,我们将探讨日志的传输和组织方式,以实现高效访问。.
日志传输的消息代理
使用消息代理 阿帕奇卡夫卡 Kafka 是一种常见的日志传输方式。它充当日志代理和存储之间的缓冲区,确保在流量高峰期间日志不会丢失。通过将日志生产者和消费者解耦,Kafka 允许代理即使在存储系统暂时不可用或过载的情况下也能继续写入日志。这种设置会将日志安全地排队,直到存储系统准备好处理它们。.
对于更简单的配置,, Redis 可以作为轻量级队列使用,但它不具备 Kafka 那样的持久性。在 AWS 环境中,, Kinesis Data Firehose Kafka 通常是一种首选的托管服务,它可以根据日志量自动扩展。设置 Kafka 时,务必仔细计算分区数——将总吞吐量除以生产者或消费者中较低的速率,并将每个 broker 的分区数保持在 4000 以下,以保证性能。.
日志存储组织
日志的存储方式很大程度上取决于所使用的存储系统。诸如此类的工具 Elasticsearch 和 OpenSearch 将日志整理成基于时间的索引(例如,, logstash-2026.02.16这使得查询最新数据的速度更快。另一方面,, 格拉法纳·洛基 它采用一种成本效益更高的方法,仅对元数据(如命名空间、pod 名称和容器名称)进行索引,同时将日志内容存储在压缩对象存储中。.
对于长期日志保留,通常使用分层存储系统:
- 热门级别日志存储在高性能 SSD 上 30-90 天,非常适合进行主动故障排除。.
- 温暖层日志会移至速度较慢的磁盘进行历史分析,通常保留 90 天到一年。.
- 寒层:超过一年的日志将被归档到对象存储(例如 AWS S3)中,以符合合规性或审计要求。.
当日志存储在对象存储中时,通常会按日期和服务名称进行分区。这种结构有助于优化 Amazon Athena 等工具的查询,从而在需要时更轻松地检索特定日志。.
分析和访问日志
日志集中化后,您可以使用 命令行工具 快速故障排除或依赖 集中式后端 用于深入分析。诸如此类的工具 kubectl 日志 和 Docker 日志 这些工具非常适合即时访问,因为它们可以直接与容器运行时或 kubelet 通信,读取本地日志文件。这些工具不需要集中式后端,因此便于进行实时检查。.
为了进行更高级的分析,日志会被发送到 Elasticsearch、OpenSearch 或 Grafana Loki 等平台。每个系统处理数据的方式都不同:Elasticsearch 使用基于时间的索引(例如,, logstash-2026.02.16Loki 专注于索引元数据(例如 Pod 名称、命名空间和标签),并将实际的日志内容存储在压缩对象存储中,而 Kubernetes 则专注于全文搜索。这种方法使得 Loki 成为大规模部署的经济高效之选。正如 Kubernetes 文档中所述,, "在集群中,日志应该拥有独立于节点、Pod 或容器的存储和生命周期。这种概念称为集群级日志记录。"
查询日志时,诸如此类的工具 KQL(Kibana 查询语言) 或者,通常使用基于 SQL 的语法。例如,在特定命名空间中搜索错误可能如下所示: 日志级别:"错误" 且 kubernetes 命名空间:"生产"". 在命令行中,, kubectl 日志 提供标签等筛选选项(-l app=nginx),时间范围(--since=1h),甚至还可以使用以下方法从崩溃的容器中检索日志: - 以前的 标志。虽然命令行工具非常适合满足即时需求,但集中式系统能提供更广阔的视角,便于进行历史数据和趋势分析。.
用于日志查询的命令行工具
命令行工具对于快速获取信息至关重要,尤其是在日志集中聚合的情况下。 kubectl 日志 该命令应用广泛,但也存在局限性。例如,Kubernetes kubelet 会在日志达到一定时进行轮换。 10英里 并且只保留 5 个文件 每个容器。这意味着如果一个 Pod 生成了 40Mi 的日志,您只会看到最新的 10Mi。 kubectl 日志. 对于系统级问题,运行中的 Linux 节点 systemd 允许您使用以下方式查询 kubelet 和容器运行时日志: journalctl 命令。.
以下是一些有用的信息 kubectl 日志 旗帜:
- 自从:检索特定时间段内的日志,例如最近一小时的日志(--since=1h).- 尾巴:将输出限制为最后几行,例如,最近的 20 行(--tail=20).--时间戳:在每行日志中添加时间戳,使分析与时间相关的问题变得更加容易。.
聚合模式比较
理解本地日志轮换和集中式聚合之间的区别是选择正确方法的关键。本地轮换由 kubelet 管理,将日志存储在节点的磁盘上。 /var/log/pods. 然而,当 Pod 被驱逐或节点发生故障时,这些日志就会丢失。另一方面,集中式聚合会将日志存储在 Elasticsearch 或云存储等外部系统中,从而确保即使容器终止后日志仍然可以访问。.
| 特征 | 默认(本地)旋转 | 集中式聚合 |
|---|---|---|
| 存储位置 | 本地节点磁盘(/var/log/pods) | 外部后端(例如 Elasticsearch、云存储) |
| 持久性 | 轮换或舱体驱逐后日志被删除 | 超越 pod 和节点生命周期保留 |
| 无障碍 | 通过以下方式访问 kubectl 日志 (仅限最新文件) | 通过 Web 用户界面或 API 访问(完整历史记录) |
| 搜索功能 | 基本文本流/尾部 | 高级查询、索引和相关性 |
| 资源影响 | 最小(由 kubelet 处理) | 更高(需要代理和网络带宽) |
集中式日志平台可以显著减少根本原因分析所需的时间——最多可减少至 80%, 根据行业数据,这种效率源于高级查询功能、多服务日志关联和历史数据保留等特性。对于日志量巨大的环境,在收集阶段实施日志采样有助于控制存储成本,同时保持对系统性能的关键洞察。持久性和查询能力之间的这种平衡对于有效的日志管理至关重要。.
如何 服务器 支持日志聚合

设置好日志收集和存储策略后,下一步是构建合适的架构来维护日志完整性——而这正是 Serverion 的优势所在。有效的日志聚合需要两者兼备。 持久存储 和 高性能基础设施, Serverion 的 VPS 和专用服务器正是为了满足这一需求而构建的。由于容器本质上是临时的,除非有稳定的主机存储来保存日志,否则容器停止运行时,其日志就会消失。持久存储对于在容器生命周期内保持日志完整至关重要,尤其是在处理 Pod 故障或重启时。Serverion 通过提供挂载在主机上的专用存储来解决这个问题。 /var/日志/, 确保您的日志在容器重启、Pod 驱逐甚至节点故障后仍然存在。.
专用服务器 裸机服务器在处理日志聚合工作负载方面表现出色。与虚拟化环境不同,裸机服务器无需虚拟机管理程序层,因此非常适合资源密集型日志任务和处理大量遥测数据。这在分布式容器环境中尤为重要,因为日志量会迅速增长。此外,与基于边车(sidecar)的日志记录方法相比,使用节点级日志代理(一个代理从主机上的所有容器收集日志)可以降低 CPU 和内存压力。.
Serverion 的 全球数据中心 为日志聚合增添了另一层效率。它们允许在更靠近源头的地方处理或存储日志,从而降低网络延迟并改进实时监控。这种分布式方法还有助于满足 GDPR 或 HIPAA 等区域法规的要求,因为它可以将审计日志保留在特定司法管辖区内。对于高流量应用程序,Serverion 支持非阻塞日志传输,即在处理之前将日志缓冲在内存中(默认情况下通常最多 1 MB)。这可以防止日志操作降低应用程序速度,同时优化性能和合规性。.
Serverion 基础架构的另一项关键优势在于其避免资源瓶颈的能力。Filebeat 或 Fluentd 等日志代理依赖于稳定的 I/O 和网络带宽,尤其是在日志高峰期。借助专用资源,日志管道可以处理实时索引和搜索,而无需与生产工作负载争夺系统资源。.
对于希望集中管理日志聚合的组织而言,Serverion 的基础架构涵盖了所有方面:从在每个 Kubernetes 节点上部署 DaemonSet 以收集日志,到托管存储后端以保留超出标准 10 MiB 轮换限制的历史数据。这种持久存储、处理能力和全球可用性的组合确保了可扩展的日志聚合。借助 Serverion,无论单个容器、Pod 或节点发生什么情况,您的日志始终可访问且可靠。.
结论
在容器化环境中,, 日志聚合至关重要 为了保持可见性并确保平稳运行,容器的设计初衷是临时性的。当它们停止或崩溃时,它们的日志也会随之消失。如果没有集中式聚合系统,数据就会分散在各个节点上,形成数据孤岛,这使得诊断分布式应用程序中的问题几乎不可能。正如 Chronosphere 的产品营销经理 Karl Kalash 所解释的那样: "日志聚合是可观测性和安全性的一个基本方面。通过整合日志,您可以全面了解系统、应用程序和基础设施的行为和性能。"
集中式日志管道不仅仅是为了方便——它们能彻底改变游戏规则。实际的 SaaS 部署表明,它们可以将平均事件解决时间从 4 小时缩短到 40 分钟以内。这种改进可能意味着小故障和全面宕机之间的区别。.
为了有效地实现这一点,请将日志视为事件流,并将它们全部路由到 标准输出 和 标准错误输出. 部署节点级代理以高效处理大量日志,并采用适当的日志轮换机制来防止磁盘空间耗尽。最重要的是,确保日志的生命周期独立于生成它们的容器。这种设置无需跨节点手动搜索,同时还能实现自动告警和跨层关联,从而加快故障排除速度。.
对于运行容器化工作负载的组织而言,支持日志记录策略的基础设施同样至关重要。可靠的解决方案,例如 Serverion 的 VPS 和专用服务器, 提供所需的存储容量、处理能力和全球数据中心网络,以满足日志摄取和保留的需求。无论您管理的是小型部署还是数百个节点,可靠的基础设施都能确保您的日志始终可访问,监控系统始终保持响应——即使在高压生产事件期间也是如此。.
常见问题解答
我的容器应该输出什么格式的日志?
容器应以一致的格式(例如纯文本)生成日志,并将其定向到 标准输出 和 标准错误输出. 该方法遵循处理日志流的既定最佳实践,确保日志易于收集、集中和分析。遵循此方法可以更轻松地与日志聚合工具集成,并增强容器化环境中的日志管理。.
什么时候应该使用 sidecar 而不是 node agent?
当你需要的时候 按服务隔离 和 精确控制 对于诸如日志记录、监控或单个 pod 内的安全等任务, 边车 这是最佳方案。Sidecar 容器与主容器在同一个 pod 中并行运行,无需修改容器代码即可增强其功能。这使得它们非常适合添加针对特定服务的定制功能。.
另一方面, 节点代理 它们在节点级别运行,处理跨多个 Pod 的日志或指标。虽然它们在处理更广泛的任务时很有效,但它们无法提供像 sidecar 那样对单个应用程序或微服务进行控制或隔离的程度。.
如何防止后端服务中断期间日志丢失?
为避免后端服务中断期间丢失日志,拥有以下配置至关重要: 可靠的日志收集策略 就地处理。例如,使用本地缓冲和队列机制可以帮助临时存储日志,直到可以发送为止。专门用于缓冲日志和重试发送的工具对于确保日志在意外停机期间不会丢失尤其有用。.
将日志集中存储在可扩展且冗余的系统中也是一个好主意。这样即使系统部分组件发生故障,也能确保日志仍然可访问且安全。此外,设置合适的日志轮换和存储策略至关重要——这有助于有效管理磁盘空间并防止溢出,这在资源通常有限的容器化环境中尤为重要。.