本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不正确。

Kubernetes v1.22 中的 Alpha 版本:API 服务器跟踪

在分布式系统中,很难找出问题的根源。您需要在某个组件的日志中进行 grep,却发现问题的根源在另一个组件中。您在那里搜索,却发现需要启用调试日志才能弄清楚真正的问题所在……诸如此类。您的请求路径越复杂,就越难回答请求去向的问题。我个人就曾花很多时间与各种 Kubernetes 组件进行这种“舞蹈”。分布式跟踪是一种旨在帮助解决这些情况的工具,而 Kubernetes API Server 也许是 Kubernetes 中最重要的组件,需要能够对其进行调试。在 Kubernetes 的 Sig Instrumentation 中,我们的使命是让您更容易了解集群中正在发生的事情,我们很高兴地宣布 Kubernetes API Server 中的分布式跟踪在 1.22 版本中达到了 alpha 阶段。

什么是跟踪?

分布式跟踪将来自多个不同来源的大量超详细信息链接在一起,并将该遥测数据构建为该请求的单个树。与日志记录不同,日志记录通过使用日志级别来限制摄取的数据量,而跟踪会收集所有详细信息,并使用采样来仅收集少量请求。这意味着,一旦您获得了一个显示问题的跟踪,您应该拥有解决该问题所需的所有信息,而无需使用 grep 搜索对象 UID!不过,我最喜欢的是跟踪的可视化效果非常有用。即使您不了解 API Server 的内部工作原理,或者不清楚 etcd “事务” 是什么,我也敢打赌您(是的,就是您!)可以大致告诉我事件的顺序,以及请求中涉及的组件。如果某个步骤花费很长时间,则很容易知道问题所在。

为什么选择 OpenTelemetry?

重要的是,无论谁管理您的基础设施,或者您选择与哪个供应商集成,Kubernetes 都能为每个人提供良好的服务。对于 Kubernetes 与遥测解决方案的集成尤其如此。OpenTelemetry 作为一个 CNCF 项目,秉承着这些核心价值观,并且正在 Kubernetes 中创建我们真正需要的东西:一套用于跟踪客户端库 API 和标准跟踪格式的开放标准。通过使用 OpenTelemetry,我们可以确保用户有自由选择其后端,并确保供应商有一个公平的竞争环境。时机再好不过了:OpenTelemetry golang API 和 SDK 非常接近 1.0 版本,很快将为这些开放标准提供向后兼容性。

为什么要检测 API Server?

Kubernetes API Server 是跟踪的理想选择,原因如下:

  • 它遵循标准的“RPC”模型(通过向下游组件发送请求来服务请求),这使得它易于检测。
  • 用户对延迟敏感:如果请求完成时间超过 10 秒,许多客户端将超时。
  • 它具有复杂的服务拓扑:单个请求可能需要咨询十几个 Webhook,或者涉及对 etcd 的多个请求。

尝试使用 Webhook 进行 APIServer 跟踪

启用 API Server 跟踪

  1. 启用 APIServerTracing 功能门控

  2. 通过将 kube-apiserver 上的 --tracing-config-file 标志指向我们的配置文件来设置跟踪配置,其中包含:

apiVersion: apiserver.config.k8s.io/v1alpha1
kind: TracingConfiguration
# 1% sampling rate
samplingRatePerMillion: 10000

启用 Etcd 跟踪

更新:以下内容是在博客发布后添加的 添加 --experimental-enable-distributed-tracing--experimental-distributed-tracing-address=0.0.0.0:4317--experimental-distributed-tracing-service-name=etcd 标志到 etcd 以启用跟踪。请注意,这会跟踪每个请求,因此如果您启用它,则可能会生成大量跟踪。所需的 etcd 版本为 3.5 至 3.5.4

从 3.5.5 版本到 3.5.10 版本,跟踪的默认采样率设置为 0%,这意味着默认情况下不会收集任何跟踪。不幸的是,没有提供配置更高采样率的选项。( 查看详细信息)

在版本 3.5.11 中,可以使用新引入的 --experimental-distributed-tracing-sampling-rate=1000000 标志配置每百万个跨度要收集的样本数。

示例跟踪:列出节点

我可以使用任何跟踪后端,但决定使用 Jaeger,因为它是最流行的开源跟踪项目之一。我在我的集群中部署了 Jaeger All-in-one 容器,在我的控制平面节点上部署了 OpenTelemetry 收集器 ( 示例),并捕获了如下跟踪:

Jaeger screenshot showing API server and etcd trace

青色线条来自 API Server,包括它处理对 /api/v1/nodes 的请求,并向 ETCD 发出 grpc Range RPC。黄色线条来自 ETCD 处理 Range RPC。

示例跟踪:使用 Mutating Webhook 创建 Pod

我使用 OpenTelemetry 检测了 示例 webhook (我必须 修补 controller-runtime,但这使得它成为一个很棒的演示),并将跟踪路由到 Jaeger。我收集了如下跟踪:

Jaeger screenshot showing API server, admission webhook, and etcd trace

与之前的跟踪相比,有两个新的跨度:一个来自 API Server 的青色跨度,表示它向准入 webhook 发出请求,以及一个来自准入 webhook 的棕色跨度,表示它正在处理请求。即使您没有检测您的 webhook,您仍然会从 API Server 获得向 webhook 发出请求的跨度。

参与进来!

这是我们第一次尝试将分布式跟踪添加到 Kubernetes 组件中,可能还有很多地方可以改进!如果我的经历引起了您的共鸣,或者您只是想尝试 Kubernetes 的最新功能,请尝试该功能,并针对您遇到的任何问题以及您认为可以改进该功能的方式提出问题。

这仅仅是我们在 Kubernetes 中使用分布式跟踪的开始。如果您认为其他组件可以从分布式跟踪中受益,或者想帮助将 API Server 跟踪推向 GA,请参加我们 定期会议 中的 sig-instrumentation 并参与进来!