k8s日志采集方式对比
一. DaemonSet
每一个节点部署一个DaemonSet,比如使用Fluentd、promtail,采集该节点所有的容器日志,要求服务支持输出日志到容器的stdout、stderr。
优点是资源占用率低,部署简单。
缺点是多个业务系统共享同一个节点级 agent 的采集配置(通常集中在一个 ConfigMap 中统一维护),按应用定制解析/路由规则的灵活性较低、配置变更影响面较大,可通过 logging operator 的租户级路由规则或多 agent 部署缓解;然后是无法采集容器内文件的日志。
适合中小型集群、和统一多个项目的标准输出日志的场景。
[!运维前提]
容器 stdout/stderr 由容器运行时写入节点/var/log/pods/<namespace>_<pod>_<uid>/<container>/目录,/var/log/containers/下为指向这些日志文件的符号链接,采集 agent 通常挂载/var/log/containers或/var/log/pods进行读取。日志轮转由 kubelet 负责,通过 KubeletConfiguration 配置:containerLogMaxSize(默认 10Mi,单文件上限)和containerLogMaxFiles(默认 5,保留份数),即每个容器默认最多保留约 50Mi 日志。注意:轮转会删除旧文件,采集 agent 必须在轮转前完成读取并正确处理文件切换;kubectl logs仅返回最新一份轮转文件的内容。

二. Sidecar
每个业务 Pod 中注入独立的采集容器,共享存储卷读取日志,可以解决服务的日志没办法直接输出到容器的stdout、stderr的问题,例如部署一个采集agent(fluentd)将日志文件输出到Sidecar容器的stdout、stderr,或者直接将日志直接发送到存储日志的后端服务。
优点是每个业务系统的配置是隔离的,更加灵活。
缺点是资源消耗更高——Kubernetes 官方文档明确指出在 sidecar 容器中运行日志 agent 可能导致显著的资源消耗;且当 sidecar 把日志直接发送到后端服务时,这些日志不受 kubelet 管理,无法通过 kubectl logs 查看。
适合大型集群、需要精细化采集的场景。
[!版本更新]
自 Kubernetes v1.33 起,原生 sidecar 容器(native sidecar containers)已进入 Stable(v1.28 Alpha、v1.29 Beta 默认启用):在spec.initContainers中定义容器并设置restartPolicy: Always。相比把采集 agent 放在普通containers中,它能保证日志 agent 先于应用容器启动、支持 liveness/readiness/startup 探针、Pod 终止时晚于应用容器停止(避免丢日志),且不会阻塞 Job 完成。集群版本满足时建议优先使用原生 sidecar 方式运行采集 agent。参考:Sidecar Containers — Kubernetes

三. 补充:官方文档中的其他日志架构
Kubernetes 官方 Logging Architecture 文档在 DaemonSet(节点级 agent)和 Sidecar 之外,还单独列出了两类方案:
- Streaming Sidecar(流式 Sidecar):sidecar 容器从共享存储卷中读取应用的日志文件,再转发到自己的 stdout/stderr,从而复用节点级 agent 和 kubelet 的日志机制(可以用
kubectl logs查看)。适合一个应用需要输出多种格式日志的场景(可用多个 sidecar 分别 tail 不同日志文件);代价是节点上的日志存储会翻倍,只有单一日志文件的应用更建议直接写/dev/stdout。 - 应用直接暴露/推送日志(Exposing logs directly from the application):应用自身把日志直接暴露或推送到日志后端,不依赖节点级 agent 或 kubelet。官方注明该方式在 Kubernetes 范畴之外,需自行实现日志的聚合与轮转,例如在logback的配置文件中增加 Kafka的appender 。
浙公网安备 33010602011771号