本文档采用自动化机器翻译技术翻译。 尽管我们力求提供准确的译文,但不对翻译内容的完整性、准确性或可靠性作出任何保证。 若出现任何内容不一致情况,请以原始 英文 版本为准,且原始英文版本为权威文本。

日志最佳实践

在本指南中,我们推荐集群级日志和应用程序日志记录的最佳实践。

在Rancher v2.5之前,Rancher中的日志记录历史上是一个相对静态的集成。可供选择的聚合器有固定列表(ElasticSearch、Splunk、Kafka、Fluentd和Syslog),并且只有两个配置点可供选择(集群级和项目级)。

Rancher提供了灵活的日志聚合体验。通过日志记录功能,管理员和用户都可以部署满足细粒度收集标准的日志记录,同时提供更广泛的目标和配置选项。

在后台,Rancher日志使用 日志 Operator.我们提供该 Operator(及其资源)的可管理性,并将该体验与管理您的 Rancher 集群结合起来。

集群级日志

集群范围内抓取

对于某些用户,抓取集群中每个容器的日志是可取的。这通常与您的安全团队要求(或需求)从所有执行点收集所有日志的请求相吻合。

在这种情况下,建议创建至少两个_ClusterOutput_对象 - 一个供您的安全团队使用(如果您有该需求),另一个供您自己,集群管理员使用。创建这些对象时,请注意选择一个能够处理来自整个集群的显著日志流量的输出端点。还要确保选择一个合适的索引来接收所有这些日志。

一旦您创建了这些_ClusterOutput_对象,创建一个_ClusterFlow_来收集所有日志。不要在此流上定义任何_包含_或_排除_规则。这将确保从整个集群收集所有日志。如果您有两个 ClusterOutputs,请确保将日志发送到它们两个。

Kubernetes 组件

ClusterFlows 能够从 Kubernetes 集群中的所有主机上的所有容器收集日志。在这些容器是 Kubernetes pod 的一部分的情况下,这种方法效果很好。

未来的 Rancher 版本将包括源容器名称,这将使得过滤这些组件日志成为可能。一旦进行该更改,您将能够自定义一个 ClusterFlow 来检索 Kubernetes 组件日志,并将其定向到适当的输出。

应用程序日志记录

在 Kubernetes 以及所有基于容器的应用程序中,最佳实践是将应用程序日志定向到 stdout/stderr。容器运行时将捕获这些日志并对其进行 某种操作 - 通常是将其写入文件。根据容器运行时(及其配置),这些日志可以最终存储在多个位置。

在将日志写入文件的情况下,Kubernetes 通过在每个主机上创建一个 /var/log/containers 目录来提供帮助。该目录将日志文件的符号链接指向其实际目的地(这可能根据配置或容器运行时而有所不同)。

Rancher 日志记录将读取 /var/log/containers 中的所有日志条目,确保所有容器的所有日志条目(假设使用默认配置)都有机会被收集和处理。

特定日志文件

日志收集仅从 Kubernetes 中的 pod 检索 stdout/stderr 日志。但是如果我们想收集由应用程序生成的其他文件的日志呢?在这里,日志流侧车(或两个)可能会派上用场。

设置流侧车的目标是将写入磁盘的日志文件的内容流式传输到 stdout。这样,日志 Operator 可以获取这些日志并将其发送到您所需的输出。

要设置此功能,请编辑您的工作负载资源(例如,Deployment)并添加以下侧车定义:

...
containers:
- args:
  - -F
  - /path/to/your/log/file.log
  command:
  - tail
  image: busybox
  name: stream-log-file-[name]
  volumeMounts:
  - mountPath: /path/to/your/log
    name: mounted-log
...

这将向您的工作负载定义添加一个容器,该容器现在将流式传输(在本示例中)/path/to/your/log/file.log 的内容到 stdout

然后根据您设置的任何 FlowsClusterFlows 自动收集此日志流。您可能还希望考虑通过定位容器的名称来专门为此日志文件创建一个 Flow。请参见示例:

...
spec:
  match:
  - select:
      container_names:
      - stream-log-file-name
...

一般最佳实践

  • 在可能的情况下,输出结构化日志条目(例如 syslog,JSON)。这使得处理日志条目变得更容易,因为这些格式已经有解析器编写。

  • 尽量在日志条目中提供创建该日志条目的应用程序的名称。这可以使故障排除变得更容易,因为 Kubernetes 对象并不总是将应用程序的名称作为对象名称。例如,pod ID 可能类似 myapp-098kjhsdf098sdf98,这并没有提供关于容器内运行的应用程序的太多信息。

  • 除非收集所有集群范围内的日志,否则尽量将您的 FlowClusterFlow 对象的范围限制得更紧。这使得在出现问题时更容易进行故障排除,并且还有助于确保无关的日志条目不会出现在您的聚合器中。紧密范围的一个例子是将一个 Flow 限制在一个名称空间中的单个 Deployment,或者甚至是一个 Pod 中的单个容器。

  • 除非在故障排除时,否则保持日志的详细程度较低。高日志详细程度会带来许多问题,其中最主要的是 噪声:重要事件可能会在大量 DEBUG 消息中被淹没。这在一定程度上通过自动警报和脚本得到了缓解,但高度冗长的日志记录仍然对日志基础设施施加了过大的压力。

  • 在可能的情况下,尽量在日志条目中提供事务或请求 ID。这可以使跨多个日志源跟踪应用程序活动变得更容易,特别是在处理分布式应用程序时。