将多个日志文件聚合到一个目录中

将多个日志文件聚合到一个目录中

我在一台机器上运行着 k3s 单节点集群。我还没有设置任何日志记录基础设施,现在我将其作为未来的学习经验。

在那个 k3s 上,我运行了一些 cron 作业,这些作业会将每个作业的日志创建到单独的文件中。我可以在/var/log/containers/cron-job-*主机上观察它们。这些日志会在一定时间后消失(successfulJobsHistoryLimit:3)。新的作业实例会创建新的日志文件。

我找不到一个简单的工具来监视该日志目录,最好使用文件名模式,并将这些小作业日志流式传输/合并到单个日志文件中,包括正在创建的新文件。我不介意文件名丢失,我只是希望日志行最终放在一个文件中,作为所有作业运行的存档。

我考虑过什么?

我可以添加一个脚本来 cat 这些文件并以一定间隔将其附加到目标文件中,但我必须跟踪哪些文件已经插入,以防作业不同步或 cron 间隔发生变化。此外,我可能希望将此功能扩展到“长期运行”的 pod,在这种情况下,我必须开始跟踪日志中更新的行。

我发现的所有示例都涉及屏幕上的实时尾部处理,这不是我所需要的。我需要将多个尾部处理到目标日志文件中。

有什么想法吗?(我也会接受一些简单的 Kubernetes 日志钩子示例)

答案1

我提供了一个我自己选择的解决方案。这不是我想要的答案,但似乎顺其自然。我仍然很好奇这是否可以通过一些常见的 Unix 命令来处理。

无论如何,这就是我所做的:

常见的方法似乎是使用一种叫做Fluentd,它允许您从各种来源收集日志并将它们传输到您认为合适的任何地方 - 一种日志的 ETL。

我选择将日志发送到 syslog 服务器,因为我已经有一个正在运行的服务器,但是您可以从这里选择任何输出插件:输出插件。还有一大套附加插件:所有插件

步骤1

获取已安装 remote_syslog 插件的 Fluentd 设置。它不包含在官方 docker 镜像中,但您可以自行设置。

FROM fluent/fluentd:v1.14.0-1.0
USER root

# https://github.com/fluent-plugins-nursery/fluent-plugin-remote_syslog
RUN fluent-gem install fluent-plugin-remote_syslog

USER fluent

构建图像并推送到您的注册表。

第2步

接下来设置一个 Fluentd 部署清单,其中包含只读卷声明以访问 pod 日志。实际文件位于 /var/log/pods/* 中,而 /var/log/containers 实际上包含符号链接。我们需要实际文件。这些日志由主机上的 root 拥有,普通 Fluent 用户无权读取它们。我们需要设置一些安全上下文。为了让一切正常,我已将 root 组用于 fsGroup。请随意深入挖掘并找到/评论此安全方面的最佳解决方案。

apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
    spec:
      securityContext:
        fsGroup: 0
      volumes:
        - name: varlogpods-pv
          persistentVolumeClaim:
            claimName: pvc-var-log-pods
            ...
      containers:
        - name: fluentd
          image: your/fluentd-image

请参阅此要点中的完整清单:fluentd-部署

步骤3

在部署之前,您还需要设置fluent.conf并描述一些规则。

我的设置为匹配这样的日志行:

2022-04-26T20:05:00.847016854+03:00 stderr F time="2022-04-26 17:05:00" level=info msg="processing 3 records ..."

有关 tail 插件的更多信息:尾巴

    <source>
      @type tail
      @id in_tail_container_logs
      path "/var/log/pods/default_cron-*/*/*.log"
      pos_file "/tmp/cron_.log.pos"
      read_from_head true
      tag cron
      <parse>
        @type regexp
        expression /^(?<logtime>[^ ]*) .* level=(?<level>[^ ]*) msg="(?<message>[^"]*)"$/ 
        time_key logtime
        time_format %FT%T.%N%:z
      </parse>
    </source>
    
    <match cron>
     @type remote_syslog
     host 172.16.3.10
     port 514
     protocol udp
     severity info
     program "fluentd"
     hostname "k3sserver"
     
     <buffer>
     </buffer>
     
     <format>
      @type single_value
      message_key message
     </format>
    </match>

这里一个重要的配置属性是read_from_head true从顶部读取日志文件。对于这种情况,这是必要的,因为 pod 日志正在轮换,我们希望 Fluentd 读取完整的 pod 日志,而不仅仅是最后的几行更新。对于简短的 cron 作业,日志文件只会出现,而 tail 不会报告其中的任何初始行。

步骤4

修改配置并重试。更新 configMap 中的配置后,不要忘记重新启动部署。

搜索线索如下:

相关内容