Kubernetes 1.29 中的上下文日志:更好的故障排除和增强的日志记录

我们代表结构化日志工作组SIG Instrumentation,很高兴地宣布,Kubernetes v1.24 中引入的上下文日志功能已成功迁移到两个组件(kube-scheduler 和 kube-controller-manager)以及一些目录。此功能旨在提供更有用的日志,以便更好地对 Kubernetes 进行故障排除,并使开发人员能够增强 Kubernetes。

什么是上下文日志?

上下文日志基于 go-logr API。其核心思想是,库由其调用者传递一个记录器实例,并使用该实例进行日志记录,而不是访问全局记录器。二进制文件决定日志记录的实现,而不是库。 go-logr API 围绕结构化日志设计,并支持将附加信息附加到记录器。

这支持了其他用例

  • 调用者可以将附加信息附加到记录器

    • WithName 添加一个 “logger” 键,其值为以点分隔的名称
    • WithValues 添加键/值对

    当将此扩展的记录器传递给函数时,如果函数使用它而不是全局记录器,则附加信息将包含在所有日志条目中,而无需修改生成日志条目的代码。这在高度并行的应用程序中非常有用,在这些应用程序中,由于来自不同操作的输出交错,因此很难识别特定操作的所有日志条目。

  • 在运行单元测试时,日志输出可以与当前测试关联。然后,当测试失败时,go test 只会显示失败测试的日志输出。默认情况下,该输出也可以更详细,因为它不会为成功的测试显示。测试可以并行运行,而不会交错其输出。

上下文日志的设计决策之一是允许将记录器作为值附加到 context.Context。由于记录器封装了调用的预期日志记录的所有方面,因此它是上下文的一部分,而不仅仅是使用它。一个实际的优点是许多 API 已经有一个 ctx 参数或可以添加一个。这提供了额外的优势,例如能够摆脱函数内部的 context.TODO() 调用。

如何使用它

上下文日志功能从 Kubernetes v1.24 开始为 alpha 版本,因此需要启用 ContextualLogging 功能门控。如果要在 alpha 阶段测试该功能,则需要在 kube-controller-managerkube-scheduler 上启用此功能门控。

对于 kube-scheduler,除了启用 ContextualLogging 功能门控外,还有一点需要注意,检测还取决于日志详细程度。为了避免因 1.29 添加的上下文日志的日志记录检测而减慢调度程序的速度,仔细选择何时添加其他信息非常重要

  • -v3 或更低级别,每个调度周期仅使用一次 WithValues("pod")。这样做的预期效果是,该周期的所有日志消息都包含 pod 信息。一旦上下文日志达到 GA,就可以从所有日志调用中删除 “pod” 键/值对。
  • -v4 或更高级别,会生成更丰富的日志条目,其中 WithValues 也用于节点(如果适用),并且 WithName 用于当前操作和插件。

这是一个演示效果的示例

I1113 08:43:37.029524 87144 default_binder.go:53] "尝试将 pod 绑定到节点" logger="Bind.DefaultBinder" pod="kube-system/coredns-69cbfb9798-ms4pq" node="127.0.0.1"

直接的好处是,操作和插件名称在 logger 中可见。podnode 已经作为 kube-scheduler 代码中单个日志调用中的参数记录。一旦 kube-scheduler 之外的更多软件包支持上下文日志,它们也将在此处可见(例如,client-go)。一旦它达到 GA,可以简化日志调用以避免重复这些值。

kube-controller-manager 中,WithName 用于将用户可见的控制器名称添加到日志输出,例如

I1113 08:43:29.284360 87141 graph_builder.go:285] "垃圾回收控制器监视器未同步:无监视器" logger="garbage-collector-controller"

logger=”garbage-collector-controller” 是在实例化该控制器时由 kube-controller-manager 核心添加的,并出现在其所有日志条目中 - 至少在它调用的代码支持上下文日志的情况下。还需要进一步工作来转换像 client-go 这样的共享软件包。

性能影响

在软件包中支持上下文日志记录(即,接受来自调用者的记录器)的成本很低。对于 kube-scheduler 没有观察到性能影响。如上所述,需要更仔细地完成添加 WithNameWithValues

在 Kubernetes 1.29 中,在生产详细程度(-v3 或更低)下启用上下文日志记录不会导致 kube-scheduler 出现可测量的减速,并且 kube-controller-manager 也预计不会出现这种情况。在调试级别,某些测试用例的 28% 减速仍然是合理的,因为生成的日志使调试更容易。有关详细信息,请参阅围绕将该功能提升为 beta 版的讨论

对下游用户的影响

日志输出不是 Kubernetes API 的一部分,并且在每个版本中都会定期更改,无论是由于开发人员在代码上工作,还是由于正在进行的向结构化和上下文日志的转换。

如果下游用户依赖于特定的日志,则他们需要了解此更改如何影响他们。

延伸阅读

参与进来

如果您有兴趣参与其中,我们始终欢迎新的贡献者加入我们。上下文日志为您提供了一个为 Kubernetes 开发做出贡献并产生有意义影响的绝佳机会。通过加入结构化日志 WG,您可以积极参与 Kubernetes 的开发并做出您的第一个贡献。这是在获得宝贵经验的同时学习和与社区互动的绝佳方式。

我们鼓励您浏览存储库,并熟悉正在进行的讨论和项目。这是一个协作环境,您可以在其中交流想法、提出问题并与其他贡献者一起工作。

如果您有任何疑问或需要指导,请随时与我们联系,您可以通过我们的公共 Slack 频道进行联系。如果您还不是该 Slack 工作区的一部分,可以访问 https://slack.k8s.io/ 获取邀请。

我们要感谢所有提供出色评论、分享宝贵见解并协助实施此功能(按字母顺序排列)的贡献者