Kubernetes 中 JSON 日志记录的最佳实践

时间:2021-05-14 21:15:37

标签: docker kubernetes logging devops

我正在开发一个应用,它的日志包含用于度量目的的自定义字段。 因此,我们生成 JSON 格式的日志,并将它们发送到 Elasticsearch 集群。 我们目前正致力于将应用程序从本地 Docker 节点迁移到我们组织的 Kubernetes 集群。 我们的集群使用 Fluentd 作为 DaemonSet,将所有 pod 的日志输出到我们的 Elasticsearch 集群。 设置类似于:https://medium.com/kubernetes-tutorials/cluster-level-logging-in-kubernetes-with-fluentd-e59aa2b6093a

我正在尝试找出从我们的应用发送日志的最佳做法是什么。我的两个要求是:

  1. 日志以 JSON 格式正确格式化。我不希望它们嵌套在持久化文档的 msg 字段中。
  2. 我可以运行 kubectl logs -f <pod> 并以可读的文本格式查看日志。

目前,如果我什么都不做而让 DaemonSet 发送日志,这两个要求都会失败

我想到的最佳解决方案是要求我们 Kubernetes 集群的管理员将 Fluentd 日志记录替换为 Fluentbit。 然后我可以像这样配置我的部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
  labels:
    app: example-app
  annotations:
    fluentbit.io/parser-example-app: json
    fluentbit.io/exclude-send-logs: "true"
spec:
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-app
        image: myapp:1.0.0
        volumeMounts:
          - name: app-logs
            mountPath: "/var/log/app"
      - name: tail-logs
        image: busybox
        args: [/bin/sh, -c, 'tail -f /var/log/example-app.log']
        volumeMounts:
          - name: app-logs
            mountPath: "/var/log/app"
      volumes:
        - name: app-logs
          emptyDir: {}

然后日志以正确的 JSON 格式发送到 Elasticsearch,我可以运行 kubectl logs -f example-app -c tail-logs 以可读格式查看它们。

这是最佳实践吗?我错过了一个更简单的解决方案吗? Fluentd 是否支持替代方案?

我很高兴在这里发表您的意见:)

1 个答案:

答案 0 :(得分:1)

这里没有一个不会占用大量 CPU 的好选择。除了您上面提到的解决方案之外,我可以建议的最接近的事情是在主输出流未格式化的情况下反转它,并且您运行 Fluent*(通常是 Bit)是辅助文件流上的 sidecar。不过也好不到哪里去。

实际上,我们中的大多数人只是将输出设为 JSON 格式,在极少数情况下,我们需要手动查看正常 UI(Kibana、Grafana 等)之外的日志,我们只是处理烦恼。

理论上,您还可以使您的“人类”格式足够机器解析以允许查询。通常的选择是“logfmt”,也就是 key=value 对。所以我在 logfmt-y 服务上的日志行看起来像 timestamp=2021-05-15T03:48:05.171973Z level=info event="some message" otherkey=1 foo="bar baz"。这很简单,可以手动阅读,但也可以有效解析。

相关问题