本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

使用 Node Dashboard 可视化 Kubelet 性能

自本文发表以来,节点性能仪表板已停用,不再可用。

此次停用发生在2019年初,作为 kubernetes/contrib 仓库弃用的一部分

在 Kubernetes 1.4 中,我们引入了一个新的节点性能分析工具,称为节点性能仪表板,用于以更丰富的细节可视化和探索 Kubelet 的行为。这项新功能将使 Kubelet 开发人员更容易理解和改进代码性能,并允许集群维护人员根据提供的服务水平目标 (SLO) 设置配置。

背景

Kubernetes 集群由主节点和工作节点组成。主节点管理集群的状态,而工作节点则实际运行和管理 Pod。为此,在每个工作节点上,一个名为 Kubelet 的二进制文件会监视 Pod 配置中的任何更改,并采取相应的操作以确保容器成功运行。Kubelet 的高性能,例如与新 Pod 配置收敛的低延迟和低资源使用率的高效内务管理,对于整个 Kubernetes 集群至关重要。为了衡量这种性能,Kubernetes 使用端到端 (e2e) 测试来持续监控最新版本与新功能的基准变化。

Kubernetes SLO 由以下基准定义 :

* API 响应能力:99% 的所有 API 调用在不到 1 秒的时间内返回。
* Pod 启动时间:99% 的 Pod 及其容器(使用预拉取的镜像)在 5 秒内启动。

在 1.4 版本发布之前,我们仅在集群级别衡量和定义了这些,这带来了其他因素可能影响结果的风险。除此之外,我们还希望有更多与性能相关的 SLO,例如特定机器类型的最大 Pod 数量,以允许最大程度地利用您的集群。为了正确地进行测量,我们希望引入一组仅限于节点性能的测试。此外,我们旨在从新测试中收集 Kubelet 更细粒度的资源使用情况和操作跟踪数据。

数据收集

从 1.4 版本开始,节点特定的密度和资源使用测试现已添加到 e2e-node 测试集中。资源使用情况由独立的 cAdvisor Pod 测量,以实现灵活的监控间隔(与 Kubelet 集成的 cAdvisor 相比)。性能数据,例如延迟和资源使用百分位,记录在持久性测试结果日志中。测试还记录时间序列数据,例如 Pod 的创建时间、运行时间以及实时资源使用情况。Kubelet 操作的跟踪数据记录在其日志中,并与测试结果一起存储。

节点性能仪表板

自 Kubernetes 1.4 起,我们持续构建最新的 Kubelet 代码并运行节点性能测试。数据由我们的新性能仪表板收集,可在 node-perf-dash.k8s.io 获取。图 1 预览了仪表板。您可以通过选择测试开始探索,可以使用短测试名称的下拉列表(区域 (a))或逐一选择测试选项(区域 (b))。测试详细信息显示在区域 (c) 中,其中包含来自 Ginkgo(Kubernetes 使用的 Go 测试框架)的完整测试名称。然后选择区域 (d) 中的节点类型(镜像和机器)。

| | | 图 1. 选择要显示在节点性能仪表板中的测试。 |

"BUILDS" 页面显示了不同构建的性能数据(图 2)。这些图表包括 Pod 启动延迟、Pod 创建吞吐量以及 Kubelet 和运行时(目前为 Docker)的 CPU/内存使用情况。通过这种方式,可以轻松监控随着新功能的签入而随时间变化的性能。

| | | 图 2. 不同构建的性能数据。 |

比较不同的节点配置

比较不同配置之间的性能总是很有趣,例如比较不同机器类型、不同 Pod 数量的启动延迟,或者比较托管不同数量 Pod 的资源使用情况。仪表板提供了一种便捷的方式来完成此操作。只需单击测试选择菜单右上角的“Compare it”按钮(图 1 中的区域 (e))。选定的测试将添加到“COMPARISON”页面中的比较列表,如图 3 所示。一系列构建的数据被聚合到一个值中,以方便比较并以条形图显示。

| | | 图 3. 比较不同的测试配置。 |

时间序列和追踪:深入探究性能数据

Pod 启动延迟是 Kubelet 的一个重要指标,尤其是在每个节点创建大量 Pod 时。使用仪表板,您可以查看延迟的变化,例如,当创建 105 个 Pod 时,如图 4 所示。当您看到高度可变的线条时,您可能会认为这种差异是由于不同的构建造成的。然而,由于这些测试是针对相同的 Kubernetes 代码运行的,我们可以得出结论,这种差异是由于性能波动造成的。当我们比较构建 #162 和 #173 的 99% 延迟时,方差接近 40 秒,这是一个非常大的值。为了深入探究波动源,让我们查看“TIME SERIES”页面。

| | | 图 4. 创建 105 个 Pod 时的 Pod 启动延迟。 |

具体来看构建 #162,我们能够看到在 Pod 创建延迟图(图 5)中绘制的跟踪数据。每条曲线都是已经到达某个跟踪探针的 Pod 操作数量的累积直方图。跟踪 Pod 的时间戳要么从性能测试中收集,要么通过解析 Kubelet 日志获得。目前我们收集以下跟踪数据

  • "create"(在测试中):测试通过 API 客户端创建 Pod;
  • "running"(在测试中):测试监视 Pod 从 API 服务器运行;
  • "pod_config_change":Kubelet SyncLoop 检测到 Pod 配置更改;
  • "runtime_manager":运行时管理器开始创建容器;
  • "infra_container_start":Pod 的基础设施容器启动;
  • "container_start":Pod 的容器启动;
  • "pod_running":Pod 正在运行;
  • "pod_status_running":状态管理器更新运行中 Pod 的状态;

时间序列图表显示状态管理器更新 Pod 状态需要很长时间(“running”的数据未显示,因为它与“pod_status_running”重叠)。我们发现此延迟是由于 Kubelet 对 API 服务器的每秒查询数 (QPS) 限制(默认为 5)造成的。意识到这一点后,我们在其他测试中发现,通过增加 QPS 限制,“running”曲线逐渐与“pod_running”收敛,从而导致更低的延迟。因此,之前的 e2e 测试 Pod 启动结果反映了 Kubelet 和上传状态时间的总延迟,Kubelet 的性能因此被低估了。

| | | 图 5. 使用构建 #162 数据的时间序列页面。 |

此外,通过比较构建 #162(图 5)和构建 #173(图 6)的时间序列数据,我们发现性能 Pod 启动延迟波动实际上发生在更新 Pod 状态期间。构建 #162 有几个落后的“pod_status_running”事件,具有较长的延迟尾部。因此,它为未来的优化提供了有用的想法。

| | | 图 6. 构建 #173 的 Pod 启动延迟。 |

未来,我们计划使用 Kubernetes 中具有固定日志格式的事件来更方便地收集跟踪数据。这样,您无需提取现有日志条目,即可在 Kubelet 内部插入自己的跟踪探针,并获取每个分段的细分延迟。

您可以在“TRACING”页面中检查不同构建之间任意两个探针的延迟,如图 7 所示。例如,通过选择“pod_config_change”作为开始探针,并选择“pod_status_running”作为结束探针,它给出了 Kubelet 在没有状态更新开销的连续构建中的延迟方差。通过此功能,开发人员能够监控 Kubelet 内部特定部分代码的性能变化。

| | | 图 7. 绘制任意两个探针之间的延迟。 |

未来工作

节点性能仪表板是一个全新的功能。它仍处于活跃开发中的 Alpha 版本。我们将持续优化数据收集和可视化,为开发人员和集群维护人员提供更多测试、指标和工具。

请加入我们的社区,帮助我们构建 Kubernetes 的未来!如果您对节点或性能测试特别感兴趣,请加入我们的 Slack 频道与我们聊天,或加入我们每周二太平洋时间上午 10 点举行的 SIG-Node Hangout 会议。