本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes v1.22 中的 Alpha 特性:API Server Tracing
在分布式系统中,找出问题所在可能很困难。您在一个组件的日志中搜索,结果发现问题源自另一个组件。您在那里搜索,结果发现需要启用调试日志才能弄清楚到底出了什么问题……如此循环。您的请求路径越复杂,就越难回答它去了哪里。我个人花了很多时间在各种 Kubernetes 组件上进行这种“舞蹈”。分布式跟踪是一种旨在帮助解决这些情况的工具,而 Kubernetes API 服务器也许是最重要的需要调试的 Kubernetes 组件。在 Kubernetes 的 Sig Instrumentation,我们的使命是让您更容易理解集群中发生的事情,我们很高兴地宣布 Kubernetes API 服务器中的分布式跟踪在 1.22 版本中达到了 Alpha 阶段。
什么是跟踪?
分布式跟踪将来自多个不同来源的一系列超详细信息链接在一起,并将这些遥测数据构建成该请求的单个树。与通过使用日志级别限制摄入数据量的日志记录不同,跟踪收集所有详细信息并使用采样来仅收集一小部分请求。这意味着一旦您拥有一个可以证明问题的跟踪,您就应该拥有解决问题所需的所有信息——无需搜索对象 UID!不过,我最喜欢的是跟踪可视化图的实用性。即使您不了解 API 服务器的内部工作原理,或者不清楚 etcd “事务”是什么,我敢打赌您(是的,就是您!)也能大致告诉我事件的顺序,以及哪些组件参与了请求。如果某个步骤花费了很长时间,很容易就能看出问题出在哪里。
为什么要选择 OpenTelemetry?
Kubernetes 能够良好地适用于每个人非常重要,无论谁管理您的基础设施,或您选择与哪些供应商集成。对于 Kubernetes 与遥测解决方案的集成尤其如此。OpenTelemetry 作为 CNCF 项目,秉承这些核心价值,并且正在创建我们 Kubernetes 所需的:一套用于跟踪客户端库 API 的开放标准和一种标准的跟踪格式。通过使用 OpenTelemetry,我们可以确保用户可以自由选择其后端,并确保供应商拥有公平的竞争环境。时机再好不过了:OpenTelemetry golang API 和 SDK 即将发布 1.0 版本,并将很快为这些开放标准提供向后兼容性。
为什么要对 API 服务器进行检测?
Kubernetes API 服务器是一个很好的跟踪候选对象,原因有以下几点:
- 它遵循标准的“RPC”模型(通过向下游组件发出请求来服务请求),这使其易于检测。
- 用户对延迟敏感:如果请求需要超过 10 秒才能完成,许多客户端将超时。
- 它具有复杂的服务拓扑:单个请求可能需要咨询十几个 webhook,或涉及对 etcd 的多个请求。
使用 webhook 试用 APIServer 跟踪
启用 API 服务器跟踪
启用 APIServerTracing 功能门。
通过将 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 中,每百万个 span 收集的样本数量可以使用新引入的 --experimental-distributed-tracing-sampling-rate=1000000
标志进行配置。
示例跟踪:列出节点
我可以使用任何跟踪后端,但决定使用 Jaeger,因为它是一个最受欢迎的开源跟踪项目。我在集群中部署了 Jaeger All-in-one 容器,在控制平面节点上部署了 OpenTelemetry 收集器 (示例),并捕获了这样的跟踪:
青色线条来自 API 服务器,包括它服务对 /api/v1/nodes
的请求,并向 ETCD 发出 grpc Range
RPC。黄色线条来自 ETCD 处理 Range
RPC。
示例跟踪:使用 mutating webhook 创建 Pod
我使用 OpenTelemetry 检测了示例 webhook(我不得不修补 controller-runtime,但它是一个很棒的演示),并将跟踪路由到 Jaeger。我收集了这样的跟踪:
与之前的跟踪相比,有两个新的 span:来自 API 服务器向准入 webhook 发出请求的青色 span,以及来自准入 webhook 服务请求的棕色 span。即使您没有检测您的 webhook,您仍然会从 API 服务器向 webhook 发出请求中获取 span。
参与其中!
由于这是我们首次尝试向 Kubernetes 组件添加分布式跟踪,因此可能还有很多可以改进的地方!如果我的挣扎与您产生共鸣,或者您只是想尝试 Kubernetes 的最新功能,请试用该功能并提交您遇到的任何问题以及您认为可以改进该功能的方法。
这仅仅是我们可以在 Kubernetes 中利用分布式跟踪所能做的开始。如果您认为其他组件会受益于分布式跟踪,或者想帮助将 API 服务器跟踪推向 GA,请加入我们 定期会议 的 sig-instrumentation 组,并参与其中!